Merge "Caps Lock toggle with Meta + Alt (1/2)" into nyc-dev
diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp
index 8556c23..374a5de 100644
--- a/services/inputflinger/InputReader.cpp
+++ b/services/inputflinger/InputReader.cpp
@@ -697,6 +697,21 @@
     return result;
 }
 
+void InputReader::toggleCapsLockState(int32_t deviceId) {
+    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+    if (deviceIndex < 0) {
+        ALOGW("Ignoring toggleCapsLock for unknown deviceId %" PRId32 ".", deviceId);
+        return;
+    }
+
+    InputDevice* device = mDevices.valueAt(deviceIndex);
+    if (device->isIgnored()) {
+        return;
+    }
+
+    device->updateMetaState(AKEYCODE_CAPS_LOCK);
+}
+
 bool InputReader::hasKeys(int32_t deviceId, uint32_t sourceMask,
         size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) {
     AutoMutex _l(mLock);
@@ -1172,6 +1187,13 @@
     return result;
 }
 
+void InputDevice::updateMetaState(int32_t keyCode) {
+    size_t numMappers = mMappers.size();
+    for (size_t i = 0; i < numMappers; i++) {
+        mMappers[i]->updateMetaState(keyCode);
+    }
+}
+
 void InputDevice::fadePointer() {
     size_t numMappers = mMappers.size();
     for (size_t i = 0; i < numMappers; i++) {
@@ -1880,6 +1902,9 @@
     return 0;
 }
 
+void InputMapper::updateMetaState(int32_t keyCode) {
+}
+
 void InputMapper::updateExternalStylusState(const StylusState& state) {
 
 }
@@ -2265,18 +2290,12 @@
         }
     }
 
-    int32_t oldMetaState = mMetaState;
-    int32_t newMetaState = updateMetaState(keyCode, down, oldMetaState);
-    bool metaStateChanged = oldMetaState != newMetaState;
-    if (metaStateChanged) {
-        mMetaState = newMetaState;
-        updateLedState(false);
-
+    if (updateMetaStateIfNeeded(keyCode, down)) {
         // If global meta state changed send it along with the key.
         // If it has not changed then we'll use what keymap gave us,
         // since key replacement logic might temporarily reset a few
         // meta bits for given key.
-        keyMetaState = newMetaState;
+        keyMetaState = mMetaState;
     }
 
     nsecs_t downTime = mDownTime;
@@ -2294,10 +2313,6 @@
         policyFlags |= POLICY_FLAG_DISABLE_KEY_REPEAT;
     }
 
-    if (metaStateChanged) {
-        getContext()->updateGlobalMetaState();
-    }
-
     if (down && !isMetaKey(keyCode)) {
         getContext()->fadePointer();
     }
@@ -2335,6 +2350,24 @@
     return mMetaState;
 }
 
+void KeyboardInputMapper::updateMetaState(int32_t keyCode) {
+    updateMetaStateIfNeeded(keyCode, false);
+}
+
+bool KeyboardInputMapper::updateMetaStateIfNeeded(int32_t keyCode, bool down) {
+    int32_t oldMetaState = mMetaState;
+    int32_t newMetaState = android::updateMetaState(keyCode, down, oldMetaState);
+    bool metaStateChanged = oldMetaState != newMetaState;
+    if (metaStateChanged) {
+        mMetaState = newMetaState;
+        updateLedState(false);
+
+        getContext()->updateGlobalMetaState();
+    }
+
+    return metaStateChanged;
+}
+
 void KeyboardInputMapper::resetLedState() {
     initializeLedState(mCapsLockLedState, ALED_CAPS_LOCK);
     initializeLedState(mNumLockLedState, ALED_NUM_LOCK);
diff --git a/services/inputflinger/InputReader.h b/services/inputflinger/InputReader.h
index e554e57..076f3d6 100644
--- a/services/inputflinger/InputReader.h
+++ b/services/inputflinger/InputReader.h
@@ -359,6 +359,9 @@
     virtual int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask,
             int32_t sw) = 0;
 
+    /* Toggle Caps Lock */
+    virtual void toggleCapsLockState(int32_t deviceId) = 0;
+
     /* Determine whether physical keys exist for the given framework-domain key codes. */
     virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask,
             size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) = 0;
@@ -461,6 +464,8 @@
     virtual int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask,
             int32_t sw);
 
+    virtual void toggleCapsLockState(int32_t deviceId);
+
     virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask,
             size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags);
 
@@ -616,6 +621,7 @@
     void cancelTouch(nsecs_t when);
 
     int32_t getMetaState();
+    void updateMetaState(int32_t keyCode);
 
     void fadePointer();
 
@@ -1031,6 +1037,7 @@
     virtual void cancelTouch(nsecs_t when);
 
     virtual int32_t getMetaState();
+    virtual void updateMetaState(int32_t keyCode);
 
     virtual void updateExternalStylusState(const StylusState& state);
 
@@ -1116,6 +1123,7 @@
             const int32_t* keyCodes, uint8_t* outFlags);
 
     virtual int32_t getMetaState();
+    virtual void updateMetaState(int32_t keyCode);
 
 private:
     struct KeyDown {
@@ -1156,6 +1164,8 @@
 
     void processKey(nsecs_t when, bool down, int32_t scanCode, int32_t usageCode);
 
+    bool updateMetaStateIfNeeded(int32_t keyCode, bool down);
+
     ssize_t findKeyDown(int32_t scanCode);
 
     void resetLedState();