Loading core/java/android/hardware/input/IInputManager.aidl +5 −0 Original line number Diff line number Diff line Loading @@ -117,6 +117,11 @@ interface IInputManager { // static association for the cleared input port will be restored. void removePortAssociation(in String inputPort); // Add a runtime association between the input device and display. void addUniqueIdAssociation(in String inputDeviceName, in String displayUniqueId); // Remove the runtime association between the input device and display. void removeUniqueIdAssociation(in String inputDeviceName); InputSensorInfo[] getSensorList(int deviceId); boolean registerSensorListener(IInputSensorEventListener listener); Loading core/java/android/hardware/input/InputManager.java +37 −2 Original line number Diff line number Diff line Loading @@ -1293,7 +1293,7 @@ public final class InputManager { * @param inputPort The port of the input device. * @param displayPort The physical port of the associated display. * <p> * Requires {@link android.Manifest.permissions.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY_BY_PORT}. * Requires {@link android.Manifest.permissions.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY}. * </p> * @hide */ Loading @@ -1310,7 +1310,7 @@ public final class InputManager { * static association for the cleared input port will be restored. * @param inputPort The port of the input device to be cleared. * <p> * Requires {@link android.Manifest.permissions.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY_BY_PORT}. * Requires {@link android.Manifest.permissions.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY}. * </p> * @hide */ Loading @@ -1322,6 +1322,41 @@ public final class InputManager { } } /** * Add a runtime association between the input device name and display, by unique id. Input * device names are expected to be unique. * @param inputDeviceName The name of the input device. * @param displayUniqueId The unique id of the associated display. * <p> * Requires {@link android.Manifest.permissions.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY}. * </p> * @hide */ public void addUniqueIdAssociation(@NonNull String inputDeviceName, @NonNull String displayUniqueId) { try { mIm.addUniqueIdAssociation(inputDeviceName, displayUniqueId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Removes a runtime association between the input device and display. * @param inputDeviceName The name of the input device. * <p> * Requires {@link android.Manifest.permissions.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY}. * </p> * @hide */ public void removeUniqueIdAssociation(@NonNull String inputDeviceName) { try { mIm.removeUniqueIdAssociation(inputDeviceName); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } private void populateInputDevicesLocked() { if (mInputDevicesChangedListener == null) { final InputDevicesChangedListener listener = new InputDevicesChangedListener(); Loading core/res/AndroidManifest.xml +1 −1 Original line number Diff line number Diff line Loading @@ -5638,7 +5638,7 @@ android:protectionLevel="signature|recents" /> <!-- Allows the caller to change the associations between input devices and displays. Very dangerous! @hide --> <permission android:name="android.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY_BY_PORT" <permission android:name="android.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY" android:protectionLevel="signature" /> <!-- Allows query of any normal app on the device, regardless of manifest declarations. Loading services/core/java/com/android/server/input/InputManagerService.java +63 −8 Original line number Diff line number Diff line Loading @@ -270,6 +270,8 @@ public class InputManagerService extends IInputManager.Stub private final Object mAssociationsLock = new Object(); @GuardedBy("mAssociationLock") private final Map<String, Integer> mRuntimeAssociations = new ArrayMap<String, Integer>(); @GuardedBy("mAssociationLock") private final Map<String, String> mUniqueIdAssociations = new ArrayMap<>(); private static native long nativeInit(InputManagerService service, Context context, MessageQueue messageQueue); Loading Loading @@ -340,6 +342,7 @@ public class InputManagerService extends IInputManager.Stub boolean enabled); private static native boolean nativeCanDispatchToDisplay(long ptr, int deviceId, int displayId); private static native void nativeNotifyPortAssociationsChanged(long ptr); private static native void nativeChangeUniqueIdAssociation(long ptr); private static native void nativeSetMotionClassifierEnabled(long ptr, boolean enabled); private static native InputSensorInfo[] nativeGetSensorList(long ptr, int deviceId); private static native boolean nativeFlushSensor(long ptr, int deviceId, int sensorType); Loading Loading @@ -2222,10 +2225,10 @@ public class InputManagerService extends IInputManager.Stub @Override // Binder call public void addPortAssociation(@NonNull String inputPort, int displayPort) { if (!checkCallingPermission( android.Manifest.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY_BY_PORT, android.Manifest.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY, "addPortAssociation()")) { throw new SecurityException( "Requires ASSOCIATE_INPUT_DEVICE_TO_DISPLAY_BY_PORT permission"); "Requires ASSOCIATE_INPUT_DEVICE_TO_DISPLAY permission"); } Objects.requireNonNull(inputPort); Loading @@ -2243,10 +2246,10 @@ public class InputManagerService extends IInputManager.Stub @Override // Binder call public void removePortAssociation(@NonNull String inputPort) { if (!checkCallingPermission( android.Manifest.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY_BY_PORT, android.Manifest.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY, "clearPortAssociations()")) { throw new SecurityException( "Requires ASSOCIATE_INPUT_DEVICE_TO_DISPLAY_BY_PORT permission"); "Requires ASSOCIATE_INPUT_DEVICE_TO_DISPLAY permission"); } Objects.requireNonNull(inputPort); Loading @@ -2256,6 +2259,49 @@ public class InputManagerService extends IInputManager.Stub nativeNotifyPortAssociationsChanged(mPtr); } /** * Add a runtime association between the input device name and the display unique id. * @param inputDeviceName The name of the input device. * @param displayUniqueId The unique id of the associated display. */ @Override // Binder call public void addUniqueIdAssociation(@NonNull String inputDeviceName, @NonNull String displayUniqueId) { if (!checkCallingPermission( android.Manifest.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY, "addNameAssociation()")) { throw new SecurityException( "Requires ASSOCIATE_INPUT_DEVICE_TO_DISPLAY permission"); } Objects.requireNonNull(inputDeviceName); Objects.requireNonNull(displayUniqueId); synchronized (mAssociationsLock) { mUniqueIdAssociations.put(inputDeviceName, displayUniqueId); } nativeChangeUniqueIdAssociation(mPtr); } /** * Remove the runtime association between the input device and the display. * @param inputDeviceName The port of the input device to be cleared. */ @Override // Binder call public void removeUniqueIdAssociation(@NonNull String inputDeviceName) { if (!checkCallingPermission( android.Manifest.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY, "removeUniqueIdAssociation()")) { throw new SecurityException( "Requires ASSOCIATE_INPUT_DEVICE_TO_DISPLAY permission"); } Objects.requireNonNull(inputDeviceName); synchronized (mAssociationsLock) { mUniqueIdAssociations.remove(inputDeviceName); } nativeChangeUniqueIdAssociation(mPtr); } @Override // Binder call public InputSensorInfo[] getSensorList(int deviceId) { return nativeGetSensorList(mPtr, deviceId); Loading Loading @@ -2790,13 +2836,13 @@ public class InputManagerService extends IInputManager.Stub * key. * @return Flattened list */ private static List<String> flatten(@NonNull Map<String, Integer> map) { private static <T> String[] flatten(@NonNull Map<String, T> map) { final List<String> list = new ArrayList<>(map.size() * 2); map.forEach((k, v)-> { list.add(k); list.add(v.toString()); }); return list; return list.toArray(new String[0]); } /** Loading Loading @@ -2828,8 +2874,17 @@ public class InputManagerService extends IInputManager.Stub associations.putAll(mRuntimeAssociations); } final List<String> associationList = flatten(associations); return associationList.toArray(new String[0]); return flatten(associations); } // Native callback private String[] getInputUniqueIdAssociations() { final Map<String, String> associations; synchronized (mAssociationsLock) { associations = new HashMap<>(mUniqueIdAssociations); } return flatten(associations); } /** Loading services/core/jni/com_android_server_input_InputManagerService.cpp +26 −0 Original line number Diff line number Diff line Loading @@ -118,6 +118,7 @@ static struct { jmethodID getVirtualKeyQuietTimeMillis; jmethodID getExcludedDeviceNames; jmethodID getInputPortAssociations; jmethodID getInputUniqueIdAssociations; jmethodID getKeyRepeatTimeout; jmethodID getKeyRepeatDelay; jmethodID getHoverTapTimeout; Loading Loading @@ -579,6 +580,21 @@ void NativeInputManager::getReaderConfiguration(InputReaderConfiguration* outCon } env->DeleteLocalRef(portAssociations); } outConfig->uniqueIdAssociations.clear(); jobjectArray uniqueIdAssociations = jobjectArray( env->CallObjectMethod(mServiceObj, gServiceClassInfo.getInputUniqueIdAssociations)); if (!checkAndClearExceptionFromCallback(env, "getInputUniqueIdAssociations") && uniqueIdAssociations) { jsize length = env->GetArrayLength(uniqueIdAssociations); for (jsize i = 0; i < length / 2; i++) { std::string inputDeviceUniqueId = getStringElementFromJavaArray(env, uniqueIdAssociations, 2 * i); std::string displayUniqueId = getStringElementFromJavaArray(env, uniqueIdAssociations, 2 * i + 1); outConfig->uniqueIdAssociations.insert({inputDeviceUniqueId, displayUniqueId}); } env->DeleteLocalRef(uniqueIdAssociations); } jint hoverTapTimeout = env->CallIntMethod(mServiceObj, gServiceClassInfo.getHoverTapTimeout); Loading Loading @@ -2134,6 +2150,12 @@ static void nativeNotifyPortAssociationsChanged(JNIEnv* env, jclass /* clazz */, InputReaderConfiguration::CHANGE_DISPLAY_INFO); } static void nativeChangeUniqueIdAssociation(JNIEnv* env, jclass /* clazz */, jlong ptr) { NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); im->getInputManager()->getReader()->requestRefreshConfiguration( InputReaderConfiguration::CHANGE_DISPLAY_INFO); } static void nativeSetMotionClassifierEnabled(JNIEnv* /* env */, jclass /* clazz */, jlong ptr, jboolean enabled) { NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); Loading Loading @@ -2316,6 +2338,7 @@ static const JNINativeMethod gInputManagerMethods[] = { (void*)nativeSetCustomPointerIcon}, {"nativeCanDispatchToDisplay", "(JII)Z", (void*)nativeCanDispatchToDisplay}, {"nativeNotifyPortAssociationsChanged", "(J)V", (void*)nativeNotifyPortAssociationsChanged}, {"nativeChangeUniqueIdAssociation", "(J)V", (void*)nativeChangeUniqueIdAssociation}, {"nativeSetMotionClassifierEnabled", "(JZ)V", (void*)nativeSetMotionClassifierEnabled}, {"nativeGetSensorList", "(JI)[Landroid/hardware/input/InputSensorInfo;", (void*)nativeGetSensorList}, Loading Loading @@ -2425,6 +2448,9 @@ int register_android_server_InputManager(JNIEnv* env) { GET_METHOD_ID(gServiceClassInfo.getInputPortAssociations, clazz, "getInputPortAssociations", "()[Ljava/lang/String;"); GET_METHOD_ID(gServiceClassInfo.getInputUniqueIdAssociations, clazz, "getInputUniqueIdAssociations", "()[Ljava/lang/String;"); GET_METHOD_ID(gServiceClassInfo.getKeyRepeatTimeout, clazz, "getKeyRepeatTimeout", "()I"); Loading Loading
core/java/android/hardware/input/IInputManager.aidl +5 −0 Original line number Diff line number Diff line Loading @@ -117,6 +117,11 @@ interface IInputManager { // static association for the cleared input port will be restored. void removePortAssociation(in String inputPort); // Add a runtime association between the input device and display. void addUniqueIdAssociation(in String inputDeviceName, in String displayUniqueId); // Remove the runtime association between the input device and display. void removeUniqueIdAssociation(in String inputDeviceName); InputSensorInfo[] getSensorList(int deviceId); boolean registerSensorListener(IInputSensorEventListener listener); Loading
core/java/android/hardware/input/InputManager.java +37 −2 Original line number Diff line number Diff line Loading @@ -1293,7 +1293,7 @@ public final class InputManager { * @param inputPort The port of the input device. * @param displayPort The physical port of the associated display. * <p> * Requires {@link android.Manifest.permissions.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY_BY_PORT}. * Requires {@link android.Manifest.permissions.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY}. * </p> * @hide */ Loading @@ -1310,7 +1310,7 @@ public final class InputManager { * static association for the cleared input port will be restored. * @param inputPort The port of the input device to be cleared. * <p> * Requires {@link android.Manifest.permissions.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY_BY_PORT}. * Requires {@link android.Manifest.permissions.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY}. * </p> * @hide */ Loading @@ -1322,6 +1322,41 @@ public final class InputManager { } } /** * Add a runtime association between the input device name and display, by unique id. Input * device names are expected to be unique. * @param inputDeviceName The name of the input device. * @param displayUniqueId The unique id of the associated display. * <p> * Requires {@link android.Manifest.permissions.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY}. * </p> * @hide */ public void addUniqueIdAssociation(@NonNull String inputDeviceName, @NonNull String displayUniqueId) { try { mIm.addUniqueIdAssociation(inputDeviceName, displayUniqueId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Removes a runtime association between the input device and display. * @param inputDeviceName The name of the input device. * <p> * Requires {@link android.Manifest.permissions.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY}. * </p> * @hide */ public void removeUniqueIdAssociation(@NonNull String inputDeviceName) { try { mIm.removeUniqueIdAssociation(inputDeviceName); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } private void populateInputDevicesLocked() { if (mInputDevicesChangedListener == null) { final InputDevicesChangedListener listener = new InputDevicesChangedListener(); Loading
core/res/AndroidManifest.xml +1 −1 Original line number Diff line number Diff line Loading @@ -5638,7 +5638,7 @@ android:protectionLevel="signature|recents" /> <!-- Allows the caller to change the associations between input devices and displays. Very dangerous! @hide --> <permission android:name="android.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY_BY_PORT" <permission android:name="android.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY" android:protectionLevel="signature" /> <!-- Allows query of any normal app on the device, regardless of manifest declarations. Loading
services/core/java/com/android/server/input/InputManagerService.java +63 −8 Original line number Diff line number Diff line Loading @@ -270,6 +270,8 @@ public class InputManagerService extends IInputManager.Stub private final Object mAssociationsLock = new Object(); @GuardedBy("mAssociationLock") private final Map<String, Integer> mRuntimeAssociations = new ArrayMap<String, Integer>(); @GuardedBy("mAssociationLock") private final Map<String, String> mUniqueIdAssociations = new ArrayMap<>(); private static native long nativeInit(InputManagerService service, Context context, MessageQueue messageQueue); Loading Loading @@ -340,6 +342,7 @@ public class InputManagerService extends IInputManager.Stub boolean enabled); private static native boolean nativeCanDispatchToDisplay(long ptr, int deviceId, int displayId); private static native void nativeNotifyPortAssociationsChanged(long ptr); private static native void nativeChangeUniqueIdAssociation(long ptr); private static native void nativeSetMotionClassifierEnabled(long ptr, boolean enabled); private static native InputSensorInfo[] nativeGetSensorList(long ptr, int deviceId); private static native boolean nativeFlushSensor(long ptr, int deviceId, int sensorType); Loading Loading @@ -2222,10 +2225,10 @@ public class InputManagerService extends IInputManager.Stub @Override // Binder call public void addPortAssociation(@NonNull String inputPort, int displayPort) { if (!checkCallingPermission( android.Manifest.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY_BY_PORT, android.Manifest.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY, "addPortAssociation()")) { throw new SecurityException( "Requires ASSOCIATE_INPUT_DEVICE_TO_DISPLAY_BY_PORT permission"); "Requires ASSOCIATE_INPUT_DEVICE_TO_DISPLAY permission"); } Objects.requireNonNull(inputPort); Loading @@ -2243,10 +2246,10 @@ public class InputManagerService extends IInputManager.Stub @Override // Binder call public void removePortAssociation(@NonNull String inputPort) { if (!checkCallingPermission( android.Manifest.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY_BY_PORT, android.Manifest.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY, "clearPortAssociations()")) { throw new SecurityException( "Requires ASSOCIATE_INPUT_DEVICE_TO_DISPLAY_BY_PORT permission"); "Requires ASSOCIATE_INPUT_DEVICE_TO_DISPLAY permission"); } Objects.requireNonNull(inputPort); Loading @@ -2256,6 +2259,49 @@ public class InputManagerService extends IInputManager.Stub nativeNotifyPortAssociationsChanged(mPtr); } /** * Add a runtime association between the input device name and the display unique id. * @param inputDeviceName The name of the input device. * @param displayUniqueId The unique id of the associated display. */ @Override // Binder call public void addUniqueIdAssociation(@NonNull String inputDeviceName, @NonNull String displayUniqueId) { if (!checkCallingPermission( android.Manifest.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY, "addNameAssociation()")) { throw new SecurityException( "Requires ASSOCIATE_INPUT_DEVICE_TO_DISPLAY permission"); } Objects.requireNonNull(inputDeviceName); Objects.requireNonNull(displayUniqueId); synchronized (mAssociationsLock) { mUniqueIdAssociations.put(inputDeviceName, displayUniqueId); } nativeChangeUniqueIdAssociation(mPtr); } /** * Remove the runtime association between the input device and the display. * @param inputDeviceName The port of the input device to be cleared. */ @Override // Binder call public void removeUniqueIdAssociation(@NonNull String inputDeviceName) { if (!checkCallingPermission( android.Manifest.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY, "removeUniqueIdAssociation()")) { throw new SecurityException( "Requires ASSOCIATE_INPUT_DEVICE_TO_DISPLAY permission"); } Objects.requireNonNull(inputDeviceName); synchronized (mAssociationsLock) { mUniqueIdAssociations.remove(inputDeviceName); } nativeChangeUniqueIdAssociation(mPtr); } @Override // Binder call public InputSensorInfo[] getSensorList(int deviceId) { return nativeGetSensorList(mPtr, deviceId); Loading Loading @@ -2790,13 +2836,13 @@ public class InputManagerService extends IInputManager.Stub * key. * @return Flattened list */ private static List<String> flatten(@NonNull Map<String, Integer> map) { private static <T> String[] flatten(@NonNull Map<String, T> map) { final List<String> list = new ArrayList<>(map.size() * 2); map.forEach((k, v)-> { list.add(k); list.add(v.toString()); }); return list; return list.toArray(new String[0]); } /** Loading Loading @@ -2828,8 +2874,17 @@ public class InputManagerService extends IInputManager.Stub associations.putAll(mRuntimeAssociations); } final List<String> associationList = flatten(associations); return associationList.toArray(new String[0]); return flatten(associations); } // Native callback private String[] getInputUniqueIdAssociations() { final Map<String, String> associations; synchronized (mAssociationsLock) { associations = new HashMap<>(mUniqueIdAssociations); } return flatten(associations); } /** Loading
services/core/jni/com_android_server_input_InputManagerService.cpp +26 −0 Original line number Diff line number Diff line Loading @@ -118,6 +118,7 @@ static struct { jmethodID getVirtualKeyQuietTimeMillis; jmethodID getExcludedDeviceNames; jmethodID getInputPortAssociations; jmethodID getInputUniqueIdAssociations; jmethodID getKeyRepeatTimeout; jmethodID getKeyRepeatDelay; jmethodID getHoverTapTimeout; Loading Loading @@ -579,6 +580,21 @@ void NativeInputManager::getReaderConfiguration(InputReaderConfiguration* outCon } env->DeleteLocalRef(portAssociations); } outConfig->uniqueIdAssociations.clear(); jobjectArray uniqueIdAssociations = jobjectArray( env->CallObjectMethod(mServiceObj, gServiceClassInfo.getInputUniqueIdAssociations)); if (!checkAndClearExceptionFromCallback(env, "getInputUniqueIdAssociations") && uniqueIdAssociations) { jsize length = env->GetArrayLength(uniqueIdAssociations); for (jsize i = 0; i < length / 2; i++) { std::string inputDeviceUniqueId = getStringElementFromJavaArray(env, uniqueIdAssociations, 2 * i); std::string displayUniqueId = getStringElementFromJavaArray(env, uniqueIdAssociations, 2 * i + 1); outConfig->uniqueIdAssociations.insert({inputDeviceUniqueId, displayUniqueId}); } env->DeleteLocalRef(uniqueIdAssociations); } jint hoverTapTimeout = env->CallIntMethod(mServiceObj, gServiceClassInfo.getHoverTapTimeout); Loading Loading @@ -2134,6 +2150,12 @@ static void nativeNotifyPortAssociationsChanged(JNIEnv* env, jclass /* clazz */, InputReaderConfiguration::CHANGE_DISPLAY_INFO); } static void nativeChangeUniqueIdAssociation(JNIEnv* env, jclass /* clazz */, jlong ptr) { NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); im->getInputManager()->getReader()->requestRefreshConfiguration( InputReaderConfiguration::CHANGE_DISPLAY_INFO); } static void nativeSetMotionClassifierEnabled(JNIEnv* /* env */, jclass /* clazz */, jlong ptr, jboolean enabled) { NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); Loading Loading @@ -2316,6 +2338,7 @@ static const JNINativeMethod gInputManagerMethods[] = { (void*)nativeSetCustomPointerIcon}, {"nativeCanDispatchToDisplay", "(JII)Z", (void*)nativeCanDispatchToDisplay}, {"nativeNotifyPortAssociationsChanged", "(J)V", (void*)nativeNotifyPortAssociationsChanged}, {"nativeChangeUniqueIdAssociation", "(J)V", (void*)nativeChangeUniqueIdAssociation}, {"nativeSetMotionClassifierEnabled", "(JZ)V", (void*)nativeSetMotionClassifierEnabled}, {"nativeGetSensorList", "(JI)[Landroid/hardware/input/InputSensorInfo;", (void*)nativeGetSensorList}, Loading Loading @@ -2425,6 +2448,9 @@ int register_android_server_InputManager(JNIEnv* env) { GET_METHOD_ID(gServiceClassInfo.getInputPortAssociations, clazz, "getInputPortAssociations", "()[Ljava/lang/String;"); GET_METHOD_ID(gServiceClassInfo.getInputUniqueIdAssociations, clazz, "getInputUniqueIdAssociations", "()[Ljava/lang/String;"); GET_METHOD_ID(gServiceClassInfo.getKeyRepeatTimeout, clazz, "getKeyRepeatTimeout", "()I"); Loading