merge from open-source master

Change-Id: I24ecfac151c0ddc27237d711c95b8fe488d7931b
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 9a843a7..be5cc7b 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -6526,18 +6526,30 @@
                             case RawInputEvent.CLASS_KEYBOARD:
                                 KeyEvent ke = (KeyEvent)ev.event;
                                 if (ke.isDown()) {
-                                    lastKey = ke;
-                                    downTime = curTime;
-                                    keyRepeatCount = 0;
                                     lastKeyTime = curTime;
-                                    nextKeyTime = lastKeyTime
-                                            + ViewConfiguration.getLongPressTimeout();
-                                    if (DEBUG_INPUT) Slog.v(
-                                        TAG, "Received key down: first repeat @ "
-                                        + nextKeyTime);
+                                    if (lastKey != null &&
+                                            ke.getKeyCode() == lastKey.getKeyCode()) {
+                                        keyRepeatCount++;
+                                        // Arbitrary long timeout to block
+                                        // repeating here since we know that
+                                        // the device driver takes care of it.
+                                        nextKeyTime = lastKeyTime + LONG_WAIT;
+                                        if (DEBUG_INPUT) Slog.v(
+                                                TAG, "Received repeated key down");
+                                    } else {
+                                        downTime = curTime;
+                                        keyRepeatCount = 0;
+                                        nextKeyTime = lastKeyTime
+                                                + ViewConfiguration.getLongPressTimeout();
+                                        if (DEBUG_INPUT) Slog.v(
+                                            TAG, "Received key down: first repeat @ "
+                                            + nextKeyTime);
+                                    }
+                                    lastKey = ke;
                                 } else {
                                     lastKey = null;
                                     downTime = 0;
+                                    keyRepeatCount = 0;
                                     // Arbitrary long timeout.
                                     lastKeyTime = curTime;
                                     nextKeyTime = curTime + LONG_WAIT;
@@ -6545,7 +6557,12 @@
                                         TAG, "Received key up: ignore repeat @ "
                                         + nextKeyTime);
                                 }
-                                dispatchKey((KeyEvent)ev.event, 0, 0);
+                                if (keyRepeatCount > 0) {
+                                    dispatchKey(KeyEvent.changeTimeRepeat(ke,
+                                            ke.getEventTime(), keyRepeatCount), 0, 0);
+                                } else {
+                                    dispatchKey(ke, 0, 0);
+                                }
                                 mQueue.recycleEvent(ev);
                                 break;
                             case RawInputEvent.CLASS_TOUCHSCREEN: