Merge "Find the most applicable subtype when there is no selected subtype but IME has subtypes"
diff --git a/include/ui/KeycodeLabels.h b/include/ui/KeycodeLabels.h
index ef2b6b3..73f5863 100755
--- a/include/ui/KeycodeLabels.h
+++ b/include/ui/KeycodeLabels.h
@@ -188,6 +188,7 @@
     { "NUMPAD_EQUALS", 161 },
     { "NUMPAD_LEFT_PAREN", 162 },
     { "NUMPAD_RIGHT_PAREN", 163 },
+    { "VOLUME_MUTE", 164 },
 
     // NOTE: If you add a new keycode here you must also add it to several other files.
     //       Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
diff --git a/libs/ui/Input.cpp b/libs/ui/Input.cpp
index 811edaf..944a79b 100644
--- a/libs/ui/Input.cpp
+++ b/libs/ui/Input.cpp
@@ -33,6 +33,7 @@
         case AKEYCODE_ENDCALL:
         case AKEYCODE_VOLUME_UP:
         case AKEYCODE_VOLUME_DOWN:
+        case AKEYCODE_VOLUME_MUTE:
         case AKEYCODE_POWER:
         case AKEYCODE_CAMERA:
         case AKEYCODE_HEADSETHOOK:
@@ -40,11 +41,14 @@
         case AKEYCODE_NOTIFICATION:
         case AKEYCODE_FOCUS:
         case AKEYCODE_SEARCH:
+        case AKEYCODE_MEDIA_PLAY:
+        case AKEYCODE_MEDIA_PAUSE:
         case AKEYCODE_MEDIA_PLAY_PAUSE:
         case AKEYCODE_MEDIA_STOP:
         case AKEYCODE_MEDIA_NEXT:
         case AKEYCODE_MEDIA_PREVIOUS:
         case AKEYCODE_MEDIA_REWIND:
+        case AKEYCODE_MEDIA_RECORD:
         case AKEYCODE_MEDIA_FAST_FORWARD:
         case AKEYCODE_MUTE:
             return true;
@@ -67,14 +71,18 @@
         case AKEYCODE_ENDCALL:
         case AKEYCODE_VOLUME_UP:
         case AKEYCODE_VOLUME_DOWN:
+        case AKEYCODE_VOLUME_MUTE:
         case AKEYCODE_MUTE:
         case AKEYCODE_POWER:
         case AKEYCODE_HEADSETHOOK:
+        case AKEYCODE_MEDIA_PLAY:
+        case AKEYCODE_MEDIA_PAUSE:
         case AKEYCODE_MEDIA_PLAY_PAUSE:
         case AKEYCODE_MEDIA_STOP:
         case AKEYCODE_MEDIA_NEXT:
         case AKEYCODE_MEDIA_PREVIOUS:
         case AKEYCODE_MEDIA_REWIND:
+        case AKEYCODE_MEDIA_RECORD:
         case AKEYCODE_MEDIA_FAST_FORWARD:
         case AKEYCODE_CAMERA:
         case AKEYCODE_FOCUS:
diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp
index a02c154..f9c0b91 100644
--- a/libs/ui/InputDispatcher.cpp
+++ b/libs/ui/InputDispatcher.cpp
@@ -619,6 +619,38 @@
 bool InputDispatcher::dispatchKeyLocked(
         nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
         DropReason* dropReason, nsecs_t* nextWakeupTime) {
+    // Preprocessing.
+    if (! entry->dispatchInProgress) {
+        if (entry->repeatCount == 0
+                && entry->action == AKEY_EVENT_ACTION_DOWN
+                && (entry->policyFlags & POLICY_FLAG_TRUSTED)
+                && !entry->isInjected()) {
+            if (mKeyRepeatState.lastKeyEntry
+                    && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
+                // We have seen two identical key downs in a row which indicates that the device
+                // driver is automatically generating key repeats itself.  We take note of the
+                // repeat here, but we disable our own next key repeat timer since it is clear that
+                // we will not need to synthesize key repeats ourselves.
+                entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
+                resetKeyRepeatLocked();
+                mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
+            } else {
+                // Not a repeat.  Save key down state in case we do see a repeat later.
+                resetKeyRepeatLocked();
+                mKeyRepeatState.nextRepeatTime = entry->eventTime + keyRepeatTimeout;
+            }
+            mKeyRepeatState.lastKeyEntry = entry;
+            entry->refCount += 1;
+        } else if (! entry->syntheticRepeat) {
+            resetKeyRepeatLocked();
+        }
+
+        entry->dispatchInProgress = true;
+        resetTargetsLocked();
+
+        logOutboundKeyDetailsLocked("dispatchKey - ", entry);
+    }
+
     // Give the policy a chance to intercept the key.
     if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
         if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
@@ -647,38 +679,6 @@
         return true;
     }
 
-    // Preprocessing.
-    if (! entry->dispatchInProgress) {
-        logOutboundKeyDetailsLocked("dispatchKey - ", entry);
-
-        if (entry->repeatCount == 0
-                && entry->action == AKEY_EVENT_ACTION_DOWN
-                && (entry->policyFlags & POLICY_FLAG_TRUSTED)
-                && !entry->isInjected()) {
-            if (mKeyRepeatState.lastKeyEntry
-                    && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
-                // We have seen two identical key downs in a row which indicates that the device
-                // driver is automatically generating key repeats itself.  We take note of the
-                // repeat here, but we disable our own next key repeat timer since it is clear that
-                // we will not need to synthesize key repeats ourselves.
-                entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
-                resetKeyRepeatLocked();
-                mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
-            } else {
-                // Not a repeat.  Save key down state in case we do see a repeat later.
-                resetKeyRepeatLocked();
-                mKeyRepeatState.nextRepeatTime = entry->eventTime + keyRepeatTimeout;
-            }
-            mKeyRepeatState.lastKeyEntry = entry;
-            entry->refCount += 1;
-        } else if (! entry->syntheticRepeat) {
-            resetKeyRepeatLocked();
-        }
-
-        entry->dispatchInProgress = true;
-        resetTargetsLocked();
-    }
-
     // Identify targets.
     if (! mCurrentInputTargetsValid) {
         int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
@@ -705,16 +705,24 @@
 #if DEBUG_OUTBOUND_EVENT_DETAILS
     LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
             "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
-            "downTime=%lld",
+            "repeatCount=%d, downTime=%lld",
             prefix,
             entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
             entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
-            entry->downTime);
+            entry->repeatCount, entry->downTime);
 #endif
 }
 
 bool InputDispatcher::dispatchMotionLocked(
         nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
+    // Preprocessing.
+    if (! entry->dispatchInProgress) {
+        entry->dispatchInProgress = true;
+        resetTargetsLocked();
+
+        logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
+    }
+
     // Clean up if dropping the event.
     if (*dropReason != DROP_REASON_NOT_DROPPED) {
         resetTargetsLocked();
@@ -723,14 +731,6 @@
         return true;
     }
 
-    // Preprocessing.
-    if (! entry->dispatchInProgress) {
-        logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
-
-        entry->dispatchInProgress = true;
-        resetTargetsLocked();
-    }
-
     bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
 
     // Identify targets.
diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp
index 12db908..1994f6a 100644
--- a/libs/ui/Region.cpp
+++ b/libs/ui/Region.cpp
@@ -289,7 +289,7 @@
     void flushSpan() {
         bool merge = false;
         if (tail-head == ssize_t(span.size())) {
-            Rect const* p = cur;
+            Rect const* p = span.editArray();
             Rect const* q = head;
             if (p->top == q->bottom) {
                 merge = true;
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index 03d2e21..f287298 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -1949,7 +1949,7 @@
         desiredConfig = overrideConfig;
     }
 
-    ssize_t rc = BAD_INDEX;
+    ssize_t rc = BAD_VALUE;
     size_t ip = grp->packages.size();
     while (ip > 0) {
         ip--;