Loading services/core/java/com/android/server/input/KeyRemapper.java +19 −47 Original line number Diff line number Diff line Loading @@ -17,27 +17,24 @@ package com.android.server.input; import android.content.Context; import android.hardware.input.InputManager; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.util.ArrayMap; import android.util.FeatureFlagUtils; import android.view.InputDevice; import com.android.internal.annotations.GuardedBy; import java.util.Map; import java.util.Objects; /** * A component of {@link InputManagerService} responsible for managing key remappings. * * @hide */ final class KeyRemapper implements InputManager.InputDeviceListener { final class KeyRemapper { private static final int MSG_UPDATE_EXISTING_DEVICES = 1; private static final int MSG_UPDATE_EXISTING_KEY_REMAPPING = 1; private static final int MSG_REMAP_KEY = 2; private static final int MSG_CLEAR_ALL_REMAPPING = 3; Loading @@ -57,13 +54,7 @@ final class KeyRemapper implements InputManager.InputDeviceListener { } public void systemRunning() { InputManager inputManager = Objects.requireNonNull( mContext.getSystemService(InputManager.class)); inputManager.registerInputDeviceListener(this, mHandler); Message msg = Message.obtain(mHandler, MSG_UPDATE_EXISTING_DEVICES, inputManager.getInputDeviceIds()); mHandler.sendMessage(msg); Message.obtain(mHandler, MSG_UPDATE_EXISTING_KEY_REMAPPING).sendToTarget(); } public void remapKey(int fromKey, int toKey) { Loading Loading @@ -91,19 +82,19 @@ final class KeyRemapper implements InputManager.InputDeviceListener { } } private void addKeyRemapping(int fromKey, int toKey) { InputManager inputManager = Objects.requireNonNull( mContext.getSystemService(InputManager.class)); for (int deviceId : inputManager.getInputDeviceIds()) { InputDevice inputDevice = inputManager.getInputDevice(deviceId); if (inputDevice != null && !inputDevice.isVirtual() && inputDevice.isFullKeyboard()) { mNative.addKeyRemapping(deviceId, fromKey, toKey); } private void setKeyRemapping(Map<Integer, Integer> keyRemapping) { int index = 0; int[] fromKeycodesArr = new int[keyRemapping.size()]; int[] toKeycodesArr = new int[keyRemapping.size()]; for (Map.Entry<Integer, Integer> entry : keyRemapping.entrySet()) { fromKeycodesArr[index] = entry.getKey(); toKeycodesArr[index] = entry.getValue(); index++; } mNative.setKeyRemapping(fromKeycodesArr, toKeycodesArr); } private void remapKeyInternal(int fromKey, int toKey) { addKeyRemapping(fromKey, toKey); synchronized (mDataStore) { try { if (fromKey == toKey) { Loading @@ -114,6 +105,7 @@ final class KeyRemapper implements InputManager.InputDeviceListener { } finally { mDataStore.saveIfNeeded(); } setKeyRemapping(mDataStore.getKeyRemapping()); } } Loading @@ -123,45 +115,25 @@ final class KeyRemapper implements InputManager.InputDeviceListener { Map<Integer, Integer> keyRemapping = mDataStore.getKeyRemapping(); for (int fromKey : keyRemapping.keySet()) { mDataStore.clearMappedKey(fromKey); // Remapping to itself will clear the remapping on native side addKeyRemapping(fromKey, fromKey); } } finally { mDataStore.saveIfNeeded(); } setKeyRemapping(mDataStore.getKeyRemapping()); } } @Override public void onInputDeviceAdded(int deviceId) { public void updateExistingKeyMapping() { if (!supportRemapping()) { return; } InputManager inputManager = Objects.requireNonNull( mContext.getSystemService(InputManager.class)); InputDevice inputDevice = inputManager.getInputDevice(deviceId); if (inputDevice != null && !inputDevice.isVirtual() && inputDevice.isFullKeyboard()) { Map<Integer, Integer> remapping = getKeyRemapping(); remapping.forEach( (fromKey, toKey) -> mNative.addKeyRemapping(deviceId, fromKey, toKey)); } } @Override public void onInputDeviceRemoved(int deviceId) { } @Override public void onInputDeviceChanged(int deviceId) { setKeyRemapping(getKeyRemapping()); } private boolean handleMessage(Message msg) { switch (msg.what) { case MSG_UPDATE_EXISTING_DEVICES: for (int deviceId : (int[]) msg.obj) { onInputDeviceAdded(deviceId); } case MSG_UPDATE_EXISTING_KEY_REMAPPING: updateExistingKeyMapping(); return true; case MSG_REMAP_KEY: remapKeyInternal(msg.arg1, msg.arg2); Loading services/core/java/com/android/server/input/NativeInputManagerService.java +2 −2 Original line number Diff line number Diff line Loading @@ -48,7 +48,7 @@ interface NativeInputManagerService { int getSwitchState(int deviceId, int sourceMask, int sw); void addKeyRemapping(int deviceId, int fromKeyCode, int toKeyCode); void setKeyRemapping(int[] fromKeyCodes, int[] toKeyCodes); boolean hasKeys(int deviceId, int sourceMask, int[] keyCodes, boolean[] keyExists); Loading Loading @@ -311,7 +311,7 @@ interface NativeInputManagerService { public native int getSwitchState(int deviceId, int sourceMask, int sw); @Override public native void addKeyRemapping(int deviceId, int fromKeyCode, int toKeyCode); public native void setKeyRemapping(int[] fromKeyCodes, int[] toKeyCodes); @Override public native boolean hasKeys(int deviceId, int sourceMask, int[] keyCodes, Loading services/core/jni/com_android_server_input_InputManagerService.cpp +30 −5 Original line number Diff line number Diff line Loading @@ -357,6 +357,7 @@ public: FloatPoint getMouseCursorPosition(ui::LogicalDisplayId displayId); void setStylusPointerIconEnabled(bool enabled); void setInputMethodConnectionIsActive(bool isActive); void setKeyRemapping(const std::map<int32_t, int32_t>& keyRemapping); /* --- InputReaderPolicyInterface implementation --- */ Loading Loading @@ -504,6 +505,9 @@ private: // True if there is an active input method connection. bool isInputMethodConnectionActive{false}; // Keycodes to be remapped. std::map<int32_t /* fromKeyCode */, int32_t /* toKeyCode */> keyRemapping{}; } mLocked GUARDED_BY(mLock); std::atomic<bool> mInteractive; Loading Loading @@ -761,6 +765,8 @@ void NativeInputManager::getReaderConfiguration(InputReaderConfiguration* outCon outConfig->stylusButtonMotionEventsEnabled = mLocked.stylusButtonMotionEventsEnabled; outConfig->stylusPointerIconEnabled = mLocked.stylusPointerIconEnabled; outConfig->keyRemapping = mLocked.keyRemapping; } // release lock } Loading Loading @@ -1910,6 +1916,16 @@ void NativeInputManager::setInputMethodConnectionIsActive(bool isActive) { mInputManager->getDispatcher().setInputMethodConnectionIsActive(isActive); } void NativeInputManager::setKeyRemapping(const std::map<int32_t, int32_t>& keyRemapping) { { // acquire lock std::scoped_lock _l(mLock); mLocked.keyRemapping = keyRemapping; } // release lock mInputManager->getReader().requestRefreshConfiguration( InputReaderConfiguration::Change::KEY_REMAPPING); } // ---------------------------------------------------------------------------- static NativeInputManager* getNativeInputManager(JNIEnv* env, jobject clazz) { Loading Loading @@ -1983,10 +1999,19 @@ static std::vector<int32_t> getIntArray(JNIEnv* env, jintArray arr) { return vec; } static void nativeAddKeyRemapping(JNIEnv* env, jobject nativeImplObj, jint deviceId, jint fromKeyCode, jint toKeyCode) { static void nativeSetKeyRemapping(JNIEnv* env, jobject nativeImplObj, jintArray fromKeyCodesArr, jintArray toKeyCodesArr) { const std::vector<int32_t> fromKeycodes = getIntArray(env, fromKeyCodesArr); const std::vector<int32_t> toKeycodes = getIntArray(env, toKeyCodesArr); if (fromKeycodes.size() != toKeycodes.size()) { jniThrowRuntimeException(env, "FromKeycodes and toKeycodes cannot match."); } NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->getInputManager()->getReader().addKeyRemapping(deviceId, fromKeyCode, toKeyCode); std::map<int32_t, int32_t> keyRemapping; for (int i = 0; i < fromKeycodes.size(); i++) { keyRemapping.insert_or_assign(fromKeycodes[i], toKeycodes[i]); } im->setKeyRemapping(keyRemapping); } static jboolean nativeHasKeys(JNIEnv* env, jobject nativeImplObj, jint deviceId, jint sourceMask, Loading Loading @@ -2491,7 +2516,7 @@ static jobject nativeGetLights(JNIEnv* env, jobject nativeImplObj, jint deviceId jTypeId = env->GetStaticIntField(gLightClassInfo.clazz, gLightClassInfo.lightTypeKeyboardMicMute); } else { ALOGW("Unknown light type %d", lightInfo.type); ALOGW("Unknown light type %s", ftl::enum_string(lightInfo.type).c_str()); continue; } Loading Loading @@ -2955,7 +2980,7 @@ static const JNINativeMethod gInputManagerMethods[] = { {"getScanCodeState", "(III)I", (void*)nativeGetScanCodeState}, {"getKeyCodeState", "(III)I", (void*)nativeGetKeyCodeState}, {"getSwitchState", "(III)I", (void*)nativeGetSwitchState}, {"addKeyRemapping", "(III)V", (void*)nativeAddKeyRemapping}, {"setKeyRemapping", "([I[I)V", (void*)nativeSetKeyRemapping}, {"hasKeys", "(II[I[Z)Z", (void*)nativeHasKeys}, {"getKeyCodeForKeyLocation", "(II)I", (void*)nativeGetKeyCodeForKeyLocation}, {"createInputChannel", "(Ljava/lang/String;)Landroid/view/InputChannel;", Loading Loading
services/core/java/com/android/server/input/KeyRemapper.java +19 −47 Original line number Diff line number Diff line Loading @@ -17,27 +17,24 @@ package com.android.server.input; import android.content.Context; import android.hardware.input.InputManager; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.util.ArrayMap; import android.util.FeatureFlagUtils; import android.view.InputDevice; import com.android.internal.annotations.GuardedBy; import java.util.Map; import java.util.Objects; /** * A component of {@link InputManagerService} responsible for managing key remappings. * * @hide */ final class KeyRemapper implements InputManager.InputDeviceListener { final class KeyRemapper { private static final int MSG_UPDATE_EXISTING_DEVICES = 1; private static final int MSG_UPDATE_EXISTING_KEY_REMAPPING = 1; private static final int MSG_REMAP_KEY = 2; private static final int MSG_CLEAR_ALL_REMAPPING = 3; Loading @@ -57,13 +54,7 @@ final class KeyRemapper implements InputManager.InputDeviceListener { } public void systemRunning() { InputManager inputManager = Objects.requireNonNull( mContext.getSystemService(InputManager.class)); inputManager.registerInputDeviceListener(this, mHandler); Message msg = Message.obtain(mHandler, MSG_UPDATE_EXISTING_DEVICES, inputManager.getInputDeviceIds()); mHandler.sendMessage(msg); Message.obtain(mHandler, MSG_UPDATE_EXISTING_KEY_REMAPPING).sendToTarget(); } public void remapKey(int fromKey, int toKey) { Loading Loading @@ -91,19 +82,19 @@ final class KeyRemapper implements InputManager.InputDeviceListener { } } private void addKeyRemapping(int fromKey, int toKey) { InputManager inputManager = Objects.requireNonNull( mContext.getSystemService(InputManager.class)); for (int deviceId : inputManager.getInputDeviceIds()) { InputDevice inputDevice = inputManager.getInputDevice(deviceId); if (inputDevice != null && !inputDevice.isVirtual() && inputDevice.isFullKeyboard()) { mNative.addKeyRemapping(deviceId, fromKey, toKey); } private void setKeyRemapping(Map<Integer, Integer> keyRemapping) { int index = 0; int[] fromKeycodesArr = new int[keyRemapping.size()]; int[] toKeycodesArr = new int[keyRemapping.size()]; for (Map.Entry<Integer, Integer> entry : keyRemapping.entrySet()) { fromKeycodesArr[index] = entry.getKey(); toKeycodesArr[index] = entry.getValue(); index++; } mNative.setKeyRemapping(fromKeycodesArr, toKeycodesArr); } private void remapKeyInternal(int fromKey, int toKey) { addKeyRemapping(fromKey, toKey); synchronized (mDataStore) { try { if (fromKey == toKey) { Loading @@ -114,6 +105,7 @@ final class KeyRemapper implements InputManager.InputDeviceListener { } finally { mDataStore.saveIfNeeded(); } setKeyRemapping(mDataStore.getKeyRemapping()); } } Loading @@ -123,45 +115,25 @@ final class KeyRemapper implements InputManager.InputDeviceListener { Map<Integer, Integer> keyRemapping = mDataStore.getKeyRemapping(); for (int fromKey : keyRemapping.keySet()) { mDataStore.clearMappedKey(fromKey); // Remapping to itself will clear the remapping on native side addKeyRemapping(fromKey, fromKey); } } finally { mDataStore.saveIfNeeded(); } setKeyRemapping(mDataStore.getKeyRemapping()); } } @Override public void onInputDeviceAdded(int deviceId) { public void updateExistingKeyMapping() { if (!supportRemapping()) { return; } InputManager inputManager = Objects.requireNonNull( mContext.getSystemService(InputManager.class)); InputDevice inputDevice = inputManager.getInputDevice(deviceId); if (inputDevice != null && !inputDevice.isVirtual() && inputDevice.isFullKeyboard()) { Map<Integer, Integer> remapping = getKeyRemapping(); remapping.forEach( (fromKey, toKey) -> mNative.addKeyRemapping(deviceId, fromKey, toKey)); } } @Override public void onInputDeviceRemoved(int deviceId) { } @Override public void onInputDeviceChanged(int deviceId) { setKeyRemapping(getKeyRemapping()); } private boolean handleMessage(Message msg) { switch (msg.what) { case MSG_UPDATE_EXISTING_DEVICES: for (int deviceId : (int[]) msg.obj) { onInputDeviceAdded(deviceId); } case MSG_UPDATE_EXISTING_KEY_REMAPPING: updateExistingKeyMapping(); return true; case MSG_REMAP_KEY: remapKeyInternal(msg.arg1, msg.arg2); Loading
services/core/java/com/android/server/input/NativeInputManagerService.java +2 −2 Original line number Diff line number Diff line Loading @@ -48,7 +48,7 @@ interface NativeInputManagerService { int getSwitchState(int deviceId, int sourceMask, int sw); void addKeyRemapping(int deviceId, int fromKeyCode, int toKeyCode); void setKeyRemapping(int[] fromKeyCodes, int[] toKeyCodes); boolean hasKeys(int deviceId, int sourceMask, int[] keyCodes, boolean[] keyExists); Loading Loading @@ -311,7 +311,7 @@ interface NativeInputManagerService { public native int getSwitchState(int deviceId, int sourceMask, int sw); @Override public native void addKeyRemapping(int deviceId, int fromKeyCode, int toKeyCode); public native void setKeyRemapping(int[] fromKeyCodes, int[] toKeyCodes); @Override public native boolean hasKeys(int deviceId, int sourceMask, int[] keyCodes, Loading
services/core/jni/com_android_server_input_InputManagerService.cpp +30 −5 Original line number Diff line number Diff line Loading @@ -357,6 +357,7 @@ public: FloatPoint getMouseCursorPosition(ui::LogicalDisplayId displayId); void setStylusPointerIconEnabled(bool enabled); void setInputMethodConnectionIsActive(bool isActive); void setKeyRemapping(const std::map<int32_t, int32_t>& keyRemapping); /* --- InputReaderPolicyInterface implementation --- */ Loading Loading @@ -504,6 +505,9 @@ private: // True if there is an active input method connection. bool isInputMethodConnectionActive{false}; // Keycodes to be remapped. std::map<int32_t /* fromKeyCode */, int32_t /* toKeyCode */> keyRemapping{}; } mLocked GUARDED_BY(mLock); std::atomic<bool> mInteractive; Loading Loading @@ -761,6 +765,8 @@ void NativeInputManager::getReaderConfiguration(InputReaderConfiguration* outCon outConfig->stylusButtonMotionEventsEnabled = mLocked.stylusButtonMotionEventsEnabled; outConfig->stylusPointerIconEnabled = mLocked.stylusPointerIconEnabled; outConfig->keyRemapping = mLocked.keyRemapping; } // release lock } Loading Loading @@ -1910,6 +1916,16 @@ void NativeInputManager::setInputMethodConnectionIsActive(bool isActive) { mInputManager->getDispatcher().setInputMethodConnectionIsActive(isActive); } void NativeInputManager::setKeyRemapping(const std::map<int32_t, int32_t>& keyRemapping) { { // acquire lock std::scoped_lock _l(mLock); mLocked.keyRemapping = keyRemapping; } // release lock mInputManager->getReader().requestRefreshConfiguration( InputReaderConfiguration::Change::KEY_REMAPPING); } // ---------------------------------------------------------------------------- static NativeInputManager* getNativeInputManager(JNIEnv* env, jobject clazz) { Loading Loading @@ -1983,10 +1999,19 @@ static std::vector<int32_t> getIntArray(JNIEnv* env, jintArray arr) { return vec; } static void nativeAddKeyRemapping(JNIEnv* env, jobject nativeImplObj, jint deviceId, jint fromKeyCode, jint toKeyCode) { static void nativeSetKeyRemapping(JNIEnv* env, jobject nativeImplObj, jintArray fromKeyCodesArr, jintArray toKeyCodesArr) { const std::vector<int32_t> fromKeycodes = getIntArray(env, fromKeyCodesArr); const std::vector<int32_t> toKeycodes = getIntArray(env, toKeyCodesArr); if (fromKeycodes.size() != toKeycodes.size()) { jniThrowRuntimeException(env, "FromKeycodes and toKeycodes cannot match."); } NativeInputManager* im = getNativeInputManager(env, nativeImplObj); im->getInputManager()->getReader().addKeyRemapping(deviceId, fromKeyCode, toKeyCode); std::map<int32_t, int32_t> keyRemapping; for (int i = 0; i < fromKeycodes.size(); i++) { keyRemapping.insert_or_assign(fromKeycodes[i], toKeycodes[i]); } im->setKeyRemapping(keyRemapping); } static jboolean nativeHasKeys(JNIEnv* env, jobject nativeImplObj, jint deviceId, jint sourceMask, Loading Loading @@ -2491,7 +2516,7 @@ static jobject nativeGetLights(JNIEnv* env, jobject nativeImplObj, jint deviceId jTypeId = env->GetStaticIntField(gLightClassInfo.clazz, gLightClassInfo.lightTypeKeyboardMicMute); } else { ALOGW("Unknown light type %d", lightInfo.type); ALOGW("Unknown light type %s", ftl::enum_string(lightInfo.type).c_str()); continue; } Loading Loading @@ -2955,7 +2980,7 @@ static const JNINativeMethod gInputManagerMethods[] = { {"getScanCodeState", "(III)I", (void*)nativeGetScanCodeState}, {"getKeyCodeState", "(III)I", (void*)nativeGetKeyCodeState}, {"getSwitchState", "(III)I", (void*)nativeGetSwitchState}, {"addKeyRemapping", "(III)V", (void*)nativeAddKeyRemapping}, {"setKeyRemapping", "([I[I)V", (void*)nativeSetKeyRemapping}, {"hasKeys", "(II[I[Z)Z", (void*)nativeHasKeys}, {"getKeyCodeForKeyLocation", "(II)I", (void*)nativeGetKeyCodeForKeyLocation}, {"createInputChannel", "(Ljava/lang/String;)Landroid/view/InputChannel;", Loading