Loading services/core/java/com/android/server/input/InputManagerService.java +5 −0 Original line number Diff line number Diff line Loading @@ -4214,6 +4214,11 @@ public class InputManagerService extends IInputManager.Stub } } @Nullable String getPhysicalLocationPath(int deviceId) { return mNative.getPhysicalLocationPath(deviceId); } interface KeyboardBacklightControllerInterface { default void incrementKeyboardBacklight(int deviceId) {} default void decrementKeyboardBacklight(int deviceId) {} Loading services/core/java/com/android/server/input/NativeInputManagerService.java +10 −0 Original line number Diff line number Diff line Loading @@ -345,6 +345,13 @@ interface NativeInputManagerService { */ void setAccessibilityPointerMotionFilterEnabled(boolean enabled); /** * Get the physical location path of the input device, if known. This is also known as the * "phys" identifier. */ @Nullable String getPhysicalLocationPath(int deviceId); /** The native implementation of InputManagerService methods. */ class NativeImpl implements NativeInputManagerService { /** Pointer to native input manager service object, used by native code. */ Loading Loading @@ -673,5 +680,8 @@ interface NativeInputManagerService { @Override public native void setAccessibilityPointerMotionFilterEnabled(boolean enabled); @Override public native String getPhysicalLocationPath(int deviceId); } } services/core/java/com/android/server/input/VirtualInputDeviceController.java +7 −2 Original line number Diff line number Diff line Loading @@ -771,7 +771,8 @@ class VirtualInputDeviceController { private int mInputDeviceId = IInputConstants.INVALID_INPUT_DEVICE_ID; WaitForDevice(String deviceName, int vendorId, int productId, int associatedDisplayId) { WaitForDevice(@NonNull String phys, @NonNull String deviceName, int vendorId, int productId, int associatedDisplayId) { mDeviceName = deviceName; mListener = new InputDeviceListener() { @Override Loading Loading @@ -799,6 +800,9 @@ class VirtualInputDeviceController { if (!device.getName().equals(deviceName)) { return false; } if (!phys.equals(mService.getPhysicalLocationPath(deviceId))) { return false; } final InputDeviceIdentifier id = device.getIdentifier(); if (id.getVendorId() != vendorId || id.getProductId() != productId) { return false; Loading Loading @@ -893,7 +897,8 @@ class VirtualInputDeviceController { if (disableSettingsForVirtualDevices()) { mService.addVirtualDevice(phys); } try (WaitForDevice waiter = new WaitForDevice(deviceName, vendorId, productId, displayId)) { try (WaitForDevice waiter = new WaitForDevice(phys, deviceName, vendorId, productId, displayId)) { ptr = deviceOpener.get(); // See INVALID_PTR in libs/input/VirtualInputDevice.cpp. if (ptr == 0) { Loading services/core/jni/com_android_server_input_InputManagerService.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -3338,6 +3338,12 @@ static void nativeSetAccessibilityPointerMotionFilterEnabled(JNIEnv* env, jobjec im->getInputManager()->getChoreographer().setAccessibilityPointerMotionFilterEnabled(enabled); } static jstring nativeGetPhysicalLocationPath(JNIEnv* env, jobject nativeImplObj, jint deviceId) { NativeInputManager* im = getNativeInputManager(env, nativeImplObj); const auto phys = im->getInputManager()->getReader().getPhysicalLocationPath(deviceId); return !phys.has_value() || phys->empty() ? nullptr : env->NewStringUTF(phys->c_str()); } // ---------------------------------------------------------------------------- static const JNINativeMethod gInputManagerMethods[] = { Loading Loading @@ -3473,6 +3479,7 @@ static const JNINativeMethod gInputManagerMethods[] = { {"setKernelWakeEnabled", "(IZ)Z", (void*)nativeSetKernelWakeEnabled}, {"setAccessibilityPointerMotionFilterEnabled", "(Z)V", (void*)nativeSetAccessibilityPointerMotionFilterEnabled}, {"getPhysicalLocationPath", "(I)Ljava/lang/String;", (void*)nativeGetPhysicalLocationPath}, }; #define FIND_CLASS(var, className) \ Loading tests/Input/src/com/android/server/input/VirtualInputDeviceControllerTest.java +20 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import android.os.RemoteException; import android.platform.test.annotations.Presubmit; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.util.SparseArray; import android.view.DisplayInfo; import android.view.InputDevice; import android.view.KeyEvent; Loading Loading @@ -87,6 +88,8 @@ public class VirtualInputDeviceControllerTest { private InputManagerGlobal.TestSession mInputSession; private final List<InputDevice> mDevices = new ArrayList<>(); private IInputDevicesChangedListener mDevicesChangedListener; // deviceId -> phys private final SparseArray<String> mPhysByDeviceId = new SparseArray<>(); // uniqueId -> displayId private final Map<String, Integer> mDisplayIdMapping = new HashMap<>(); // phys -> uniqueId Loading Loading @@ -131,6 +134,8 @@ public class VirtualInputDeviceControllerTest { .when(mInputManagerService).addVirtualDevice(anyString()); doAnswer(inv -> mVirtualDevices.remove(inv.getArgument(0))) .when(mInputManagerService).removeVirtualDevice(anyString()); doAnswer(inv -> mPhysByDeviceId.get(inv.getArgument(0))) .when(mInputManagerService).getPhysicalLocationPath(anyInt()); // Set a new instance of InputManager for testing that uses the IInputManager mock as the Loading Loading @@ -177,6 +182,7 @@ public class VirtualInputDeviceControllerTest { .setAssociatedDisplayId(mDisplayIdMapping.get(mUniqueIdAssociationByPort.get(phys))) .build(); mDevices.add(device); mPhysByDeviceId.put(device.getId(), phys); try { mDevicesChangedListener.onInputDevicesChanged( mDevices.stream().flatMapToInt( Loading Loading @@ -238,6 +244,20 @@ public class VirtualInputDeviceControllerTest { NAME_2, VENDOR_ID, PRODUCT_ID, TOKEN_1, DISPLAY_ID_2)); } @Test public void createInputDevice_differentDevices_haveUniquePhys() throws RemoteException { final int d1 = mInputController.createDpad(NAME, VENDOR_ID, PRODUCT_ID, TOKEN_1, DISPLAY_ID_1).getInputDeviceId(); final int d2 = mInputController.createDpad(NAME_2, VENDOR_ID, PRODUCT_ID, TOKEN_2, DISPLAY_ID_1).getInputDeviceId(); final String phys1 = mPhysByDeviceId.get(d1); final String phys2 = mPhysByDeviceId.get(d2); assertThat(phys1).isNotEmpty(); assertThat(phys2).isNotEmpty(); assertThat(phys1).isNotEqualTo(phys2); } @Test public void getCursorPosition_returnsPositionFromService() { mInputController.createMouse(NAME, VENDOR_ID, PRODUCT_ID, TOKEN_1, DISPLAY_ID_1); Loading Loading
services/core/java/com/android/server/input/InputManagerService.java +5 −0 Original line number Diff line number Diff line Loading @@ -4214,6 +4214,11 @@ public class InputManagerService extends IInputManager.Stub } } @Nullable String getPhysicalLocationPath(int deviceId) { return mNative.getPhysicalLocationPath(deviceId); } interface KeyboardBacklightControllerInterface { default void incrementKeyboardBacklight(int deviceId) {} default void decrementKeyboardBacklight(int deviceId) {} Loading
services/core/java/com/android/server/input/NativeInputManagerService.java +10 −0 Original line number Diff line number Diff line Loading @@ -345,6 +345,13 @@ interface NativeInputManagerService { */ void setAccessibilityPointerMotionFilterEnabled(boolean enabled); /** * Get the physical location path of the input device, if known. This is also known as the * "phys" identifier. */ @Nullable String getPhysicalLocationPath(int deviceId); /** The native implementation of InputManagerService methods. */ class NativeImpl implements NativeInputManagerService { /** Pointer to native input manager service object, used by native code. */ Loading Loading @@ -673,5 +680,8 @@ interface NativeInputManagerService { @Override public native void setAccessibilityPointerMotionFilterEnabled(boolean enabled); @Override public native String getPhysicalLocationPath(int deviceId); } }
services/core/java/com/android/server/input/VirtualInputDeviceController.java +7 −2 Original line number Diff line number Diff line Loading @@ -771,7 +771,8 @@ class VirtualInputDeviceController { private int mInputDeviceId = IInputConstants.INVALID_INPUT_DEVICE_ID; WaitForDevice(String deviceName, int vendorId, int productId, int associatedDisplayId) { WaitForDevice(@NonNull String phys, @NonNull String deviceName, int vendorId, int productId, int associatedDisplayId) { mDeviceName = deviceName; mListener = new InputDeviceListener() { @Override Loading Loading @@ -799,6 +800,9 @@ class VirtualInputDeviceController { if (!device.getName().equals(deviceName)) { return false; } if (!phys.equals(mService.getPhysicalLocationPath(deviceId))) { return false; } final InputDeviceIdentifier id = device.getIdentifier(); if (id.getVendorId() != vendorId || id.getProductId() != productId) { return false; Loading Loading @@ -893,7 +897,8 @@ class VirtualInputDeviceController { if (disableSettingsForVirtualDevices()) { mService.addVirtualDevice(phys); } try (WaitForDevice waiter = new WaitForDevice(deviceName, vendorId, productId, displayId)) { try (WaitForDevice waiter = new WaitForDevice(phys, deviceName, vendorId, productId, displayId)) { ptr = deviceOpener.get(); // See INVALID_PTR in libs/input/VirtualInputDevice.cpp. if (ptr == 0) { Loading
services/core/jni/com_android_server_input_InputManagerService.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -3338,6 +3338,12 @@ static void nativeSetAccessibilityPointerMotionFilterEnabled(JNIEnv* env, jobjec im->getInputManager()->getChoreographer().setAccessibilityPointerMotionFilterEnabled(enabled); } static jstring nativeGetPhysicalLocationPath(JNIEnv* env, jobject nativeImplObj, jint deviceId) { NativeInputManager* im = getNativeInputManager(env, nativeImplObj); const auto phys = im->getInputManager()->getReader().getPhysicalLocationPath(deviceId); return !phys.has_value() || phys->empty() ? nullptr : env->NewStringUTF(phys->c_str()); } // ---------------------------------------------------------------------------- static const JNINativeMethod gInputManagerMethods[] = { Loading Loading @@ -3473,6 +3479,7 @@ static const JNINativeMethod gInputManagerMethods[] = { {"setKernelWakeEnabled", "(IZ)Z", (void*)nativeSetKernelWakeEnabled}, {"setAccessibilityPointerMotionFilterEnabled", "(Z)V", (void*)nativeSetAccessibilityPointerMotionFilterEnabled}, {"getPhysicalLocationPath", "(I)Ljava/lang/String;", (void*)nativeGetPhysicalLocationPath}, }; #define FIND_CLASS(var, className) \ Loading
tests/Input/src/com/android/server/input/VirtualInputDeviceControllerTest.java +20 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import android.os.RemoteException; import android.platform.test.annotations.Presubmit; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.util.SparseArray; import android.view.DisplayInfo; import android.view.InputDevice; import android.view.KeyEvent; Loading Loading @@ -87,6 +88,8 @@ public class VirtualInputDeviceControllerTest { private InputManagerGlobal.TestSession mInputSession; private final List<InputDevice> mDevices = new ArrayList<>(); private IInputDevicesChangedListener mDevicesChangedListener; // deviceId -> phys private final SparseArray<String> mPhysByDeviceId = new SparseArray<>(); // uniqueId -> displayId private final Map<String, Integer> mDisplayIdMapping = new HashMap<>(); // phys -> uniqueId Loading Loading @@ -131,6 +134,8 @@ public class VirtualInputDeviceControllerTest { .when(mInputManagerService).addVirtualDevice(anyString()); doAnswer(inv -> mVirtualDevices.remove(inv.getArgument(0))) .when(mInputManagerService).removeVirtualDevice(anyString()); doAnswer(inv -> mPhysByDeviceId.get(inv.getArgument(0))) .when(mInputManagerService).getPhysicalLocationPath(anyInt()); // Set a new instance of InputManager for testing that uses the IInputManager mock as the Loading Loading @@ -177,6 +182,7 @@ public class VirtualInputDeviceControllerTest { .setAssociatedDisplayId(mDisplayIdMapping.get(mUniqueIdAssociationByPort.get(phys))) .build(); mDevices.add(device); mPhysByDeviceId.put(device.getId(), phys); try { mDevicesChangedListener.onInputDevicesChanged( mDevices.stream().flatMapToInt( Loading Loading @@ -238,6 +244,20 @@ public class VirtualInputDeviceControllerTest { NAME_2, VENDOR_ID, PRODUCT_ID, TOKEN_1, DISPLAY_ID_2)); } @Test public void createInputDevice_differentDevices_haveUniquePhys() throws RemoteException { final int d1 = mInputController.createDpad(NAME, VENDOR_ID, PRODUCT_ID, TOKEN_1, DISPLAY_ID_1).getInputDeviceId(); final int d2 = mInputController.createDpad(NAME_2, VENDOR_ID, PRODUCT_ID, TOKEN_2, DISPLAY_ID_1).getInputDeviceId(); final String phys1 = mPhysByDeviceId.get(d1); final String phys2 = mPhysByDeviceId.get(d2); assertThat(phys1).isNotEmpty(); assertThat(phys2).isNotEmpty(); assertThat(phys1).isNotEqualTo(phys2); } @Test public void getCursorPosition_returnsPositionFromService() { mInputController.createMouse(NAME, VENDOR_ID, PRODUCT_ID, TOKEN_1, DISPLAY_ID_1); Loading