Loading services/companion/java/com/android/server/companion/virtual/VirtualInputController.java→services/companion/java/com/android/server/companion/virtual/InputController.java +49 −68 Original line number Diff line number Diff line Loading @@ -18,7 +18,7 @@ package com.android.server.companion.virtual; import android.annotation.NonNull; import android.content.AttributionSource; import android.graphics.PointF; import android.content.Context; import android.hardware.input.IVirtualInputDevice; import android.hardware.input.InputManager; import android.hardware.input.VirtualDpadConfig; Loading @@ -28,11 +28,9 @@ import android.hardware.input.VirtualNavigationTouchpadConfig; import android.hardware.input.VirtualRotaryEncoderConfig; import android.hardware.input.VirtualStylusConfig; import android.hardware.input.VirtualTouchscreenConfig; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; import android.util.ArrayMap; import android.util.Slog; import android.view.WindowManager; import com.android.internal.annotations.GuardedBy; Loading @@ -46,9 +44,7 @@ import java.util.Iterator; import java.util.Map; /** Controls virtual input devices, including device lifecycle and event dispatch. */ class VirtualInputController { private static final String TAG = "InputController"; class InputController { private final Object mLock = new Object(); Loading @@ -60,17 +56,20 @@ class VirtualInputController { private final InputManager mInputManager; private final WindowManager mWindowManager; private final AttributionSource mAttributionSource; private final InputDeviceListener mInputDeviceListener = new InputDeviceListener(); @VisibleForTesting VirtualInputController(@NonNull InputManager inputManager, @NonNull WindowManager windowManager, AttributionSource attributionSource) { InputController(@NonNull Context context, AttributionSource attributionSource) { mInputManagerInternal = LocalServices.getService(InputManagerInternal.class); mInputManager = inputManager; mWindowManager = windowManager; mInputManager = context.getSystemService(InputManager.class); mWindowManager = context.getSystemService(WindowManager.class); mAttributionSource = attributionSource; mInputManager.registerInputDeviceListener( mInputDeviceListener, context.getMainThreadHandler()); } void close() { mInputManager.unregisterInputDeviceListener(mInputDeviceListener); synchronized (mLock) { final Iterator<Map.Entry<IBinder, IVirtualInputDevice>> iterator = mInputDevices.entrySet().iterator(); Loading Loading @@ -146,36 +145,6 @@ class VirtualInputController { return device; } void unregisterInputDevice(@NonNull IBinder token) { synchronized (mLock) { final IVirtualInputDevice inputDeviceDescriptor = mInputDevices.remove(token); if (inputDeviceDescriptor == null) { Slog.w(TAG, "Could not unregister input device for given token."); } else { Binder.withCleanCallingIdentity(() -> mInputManagerInternal.closeVirtualInputDevice(token)); } } } /** * @return the device id for a given token (identifiying a device) */ int getInputDeviceId(IBinder token) { synchronized (mLock) { final IVirtualInputDevice inputDeviceDescriptor = mInputDevices.get(token); if (inputDeviceDescriptor == null) { throw new IllegalArgumentException("Could not get device id for given token"); } try { return inputDeviceDescriptor.getInputDeviceId(); } catch (RemoteException e) { e.rethrowFromSystemServer(); } } return -1; } void setShowPointerIcon(boolean visible, int displayId) { mInputManagerInternal.setPointerIconVisible(visible, displayId); } Loading @@ -192,25 +161,6 @@ class VirtualInputController { mWindowManager.setDisplayImePolicy(displayId, policy); } public PointF getCursorPosition(@NonNull IBinder token) { synchronized (mLock) { final IVirtualInputDevice inputDeviceDescriptor = mInputDevices.get(token); if (inputDeviceDescriptor == null) { throw new IllegalArgumentException( "Could not get cursor position for input device for given token"); } return Binder.withCleanCallingIdentity(() -> { try { return mInputManager.getCursorPosition( inputDeviceDescriptor.getAssociatedDisplayId()); } catch (RemoteException e) { e.rethrowFromSystemServer(); return null; } }); } } public void dump(@NonNull PrintWriter fout) { final String prefix = " "; fout.println(prefix + "InputController: "); Loading @@ -232,19 +182,50 @@ class VirtualInputController { } } @VisibleForTesting void removeDeviceForTesting(IBinder token) { synchronized (mLock) { mInputDevices.remove(token); } } boolean isInputDevicePresent(int inputDeviceId) { synchronized (mLock) { return getTokenForInputDeviceIdLocked(inputDeviceId) != null; } } @GuardedBy("mLock") private IBinder getTokenForInputDeviceIdLocked(int inputDeviceId) { try { for (int i = 0; i < mInputDevices.size(); ++i) { IVirtualInputDevice device = mInputDevices.valueAt(i); if (device.getInputDeviceId() == inputDeviceId) { return true; return mInputDevices.keyAt(i); } } } catch (RemoteException e) { e.rethrowFromSystemServer(); } return null; } private class InputDeviceListener implements InputManager.InputDeviceListener { @Override public void onInputDeviceAdded(int deviceId) {} @Override public void onInputDeviceChanged(int deviceId) {} @Override public void onInputDeviceRemoved(int deviceId) { synchronized (mLock) { IBinder token = getTokenForInputDeviceIdLocked(deviceId); if (token != null) { mInputDevices.remove(token); } } } return false; } } services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java +3 −6 Original line number Diff line number Diff line Loading @@ -77,7 +77,6 @@ import android.hardware.display.DisplayManagerInternal; import android.hardware.display.IVirtualDisplayCallback; import android.hardware.display.VirtualDisplayConfig; import android.hardware.input.IVirtualInputDevice; import android.hardware.input.InputManager; import android.hardware.input.VirtualDpadConfig; import android.hardware.input.VirtualKeyboardConfig; import android.hardware.input.VirtualMouseConfig; Loading Loading @@ -195,7 +194,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub private final int mDeviceId; @Nullable private final String mPersistentDeviceId; private final VirtualInputController mInputController; private final InputController mInputController; private final SensorController mSensorController; private final CameraAccessController mCameraAccessController; @Nullable private final ViewConfigurationController mViewConfigurationController; Loading Loading @@ -425,7 +424,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub IBinder token, AttributionSource attributionSource, int deviceId, VirtualInputController inputController, InputController inputController, CameraAccessController cameraAccessController, PendingTrampolineCallback pendingTrampolineCallback, IVirtualDeviceActivityListener activityListener, Loading Loading @@ -479,9 +478,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub mBaseVirtualDisplayFlags = flags; if (inputController == null) { mInputController = new VirtualInputController( context.getSystemService(InputManager.class), context.getSystemService(WindowManager.class), mAttributionSource); mInputController = new InputController(mContext, mAttributionSource); } else { mInputController = inputController; } Loading services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java +4 −10 Original line number Diff line number Diff line Loading @@ -79,7 +79,6 @@ import android.hardware.display.IDisplayManager; import android.hardware.display.IVirtualDisplayCallback; import android.hardware.display.VirtualDisplayConfig; import android.hardware.input.IVirtualInputDevice; import android.hardware.input.InputManager; import android.hardware.input.VirtualDpadConfig; import android.hardware.input.VirtualKeyboardConfig; import android.hardware.input.VirtualMouseConfig; Loading Loading @@ -222,7 +221,7 @@ public class VirtualDeviceManagerServiceTest { private Context mContext; private VirtualDeviceImpl mDeviceImpl; private VirtualInputController mInputController; private InputController mInputController; private SensorController mSensorController; private CameraAccessController mCameraAccessController; private AssociationInfo mAssociationInfo; Loading Loading @@ -322,9 +321,6 @@ public class VirtualDeviceManagerServiceTest { public void setUp() throws Exception { MockitoAnnotations.initMocks(this); LocalServices.removeServiceForTest(DisplayManagerInternal.class); LocalServices.addService(DisplayManagerInternal.class, mDisplayManagerInternalMock); when(mInputManagerInternalMock.createVirtualTouchscreen(any(), any())) .thenReturn(mIVirtualInputDevice); when(mInputManagerInternalMock.createVirtualKeyboard(any(), any())) Loading @@ -350,15 +346,13 @@ public class VirtualDeviceManagerServiceTest { doNothing().when(mContext).sendBroadcastAsUser(any(), any()); when(mContext.getSystemService(Context.DEVICE_POLICY_SERVICE)).thenReturn( mDevicePolicyManagerMock); when(mContext.getSystemService(Context.WINDOW_SERVICE)).thenReturn(mWindowManager); PowerManager powerManager = new PowerManager(mContext, mIPowerManagerMock, mIThermalServiceMock, new Handler(TestableLooper.get(this).getLooper())); when(mContext.getSystemService(Context.POWER_SERVICE)).thenReturn(powerManager); mInputController = new VirtualInputController( InstrumentationRegistry.getInstrumentation().getTargetContext().getSystemService( InputManager.class), mWindowManager, AttributionSource.myAttributionSource()); mInputController = new InputController(mContext, AttributionSource.myAttributionSource()); mCameraAccessController = new CameraAccessController(mContext, mLocalService, mCameraAccessBlockedCallback); Loading Loading @@ -642,7 +636,7 @@ public class VirtualDeviceManagerServiceTest { mInputController.addDeviceForTesting(BINDER, mIVirtualInputDevice); assertThat(mLocalService.isInputDeviceOwnedByVirtualDevice(INPUT_DEVICE_ID)).isTrue(); mInputController.unregisterInputDevice(BINDER); mInputController.removeDeviceForTesting(BINDER); assertThat(mLocalService.isInputDeviceOwnedByVirtualDevice(INPUT_DEVICE_ID)).isFalse(); } Loading Loading
services/companion/java/com/android/server/companion/virtual/VirtualInputController.java→services/companion/java/com/android/server/companion/virtual/InputController.java +49 −68 Original line number Diff line number Diff line Loading @@ -18,7 +18,7 @@ package com.android.server.companion.virtual; import android.annotation.NonNull; import android.content.AttributionSource; import android.graphics.PointF; import android.content.Context; import android.hardware.input.IVirtualInputDevice; import android.hardware.input.InputManager; import android.hardware.input.VirtualDpadConfig; Loading @@ -28,11 +28,9 @@ import android.hardware.input.VirtualNavigationTouchpadConfig; import android.hardware.input.VirtualRotaryEncoderConfig; import android.hardware.input.VirtualStylusConfig; import android.hardware.input.VirtualTouchscreenConfig; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; import android.util.ArrayMap; import android.util.Slog; import android.view.WindowManager; import com.android.internal.annotations.GuardedBy; Loading @@ -46,9 +44,7 @@ import java.util.Iterator; import java.util.Map; /** Controls virtual input devices, including device lifecycle and event dispatch. */ class VirtualInputController { private static final String TAG = "InputController"; class InputController { private final Object mLock = new Object(); Loading @@ -60,17 +56,20 @@ class VirtualInputController { private final InputManager mInputManager; private final WindowManager mWindowManager; private final AttributionSource mAttributionSource; private final InputDeviceListener mInputDeviceListener = new InputDeviceListener(); @VisibleForTesting VirtualInputController(@NonNull InputManager inputManager, @NonNull WindowManager windowManager, AttributionSource attributionSource) { InputController(@NonNull Context context, AttributionSource attributionSource) { mInputManagerInternal = LocalServices.getService(InputManagerInternal.class); mInputManager = inputManager; mWindowManager = windowManager; mInputManager = context.getSystemService(InputManager.class); mWindowManager = context.getSystemService(WindowManager.class); mAttributionSource = attributionSource; mInputManager.registerInputDeviceListener( mInputDeviceListener, context.getMainThreadHandler()); } void close() { mInputManager.unregisterInputDeviceListener(mInputDeviceListener); synchronized (mLock) { final Iterator<Map.Entry<IBinder, IVirtualInputDevice>> iterator = mInputDevices.entrySet().iterator(); Loading Loading @@ -146,36 +145,6 @@ class VirtualInputController { return device; } void unregisterInputDevice(@NonNull IBinder token) { synchronized (mLock) { final IVirtualInputDevice inputDeviceDescriptor = mInputDevices.remove(token); if (inputDeviceDescriptor == null) { Slog.w(TAG, "Could not unregister input device for given token."); } else { Binder.withCleanCallingIdentity(() -> mInputManagerInternal.closeVirtualInputDevice(token)); } } } /** * @return the device id for a given token (identifiying a device) */ int getInputDeviceId(IBinder token) { synchronized (mLock) { final IVirtualInputDevice inputDeviceDescriptor = mInputDevices.get(token); if (inputDeviceDescriptor == null) { throw new IllegalArgumentException("Could not get device id for given token"); } try { return inputDeviceDescriptor.getInputDeviceId(); } catch (RemoteException e) { e.rethrowFromSystemServer(); } } return -1; } void setShowPointerIcon(boolean visible, int displayId) { mInputManagerInternal.setPointerIconVisible(visible, displayId); } Loading @@ -192,25 +161,6 @@ class VirtualInputController { mWindowManager.setDisplayImePolicy(displayId, policy); } public PointF getCursorPosition(@NonNull IBinder token) { synchronized (mLock) { final IVirtualInputDevice inputDeviceDescriptor = mInputDevices.get(token); if (inputDeviceDescriptor == null) { throw new IllegalArgumentException( "Could not get cursor position for input device for given token"); } return Binder.withCleanCallingIdentity(() -> { try { return mInputManager.getCursorPosition( inputDeviceDescriptor.getAssociatedDisplayId()); } catch (RemoteException e) { e.rethrowFromSystemServer(); return null; } }); } } public void dump(@NonNull PrintWriter fout) { final String prefix = " "; fout.println(prefix + "InputController: "); Loading @@ -232,19 +182,50 @@ class VirtualInputController { } } @VisibleForTesting void removeDeviceForTesting(IBinder token) { synchronized (mLock) { mInputDevices.remove(token); } } boolean isInputDevicePresent(int inputDeviceId) { synchronized (mLock) { return getTokenForInputDeviceIdLocked(inputDeviceId) != null; } } @GuardedBy("mLock") private IBinder getTokenForInputDeviceIdLocked(int inputDeviceId) { try { for (int i = 0; i < mInputDevices.size(); ++i) { IVirtualInputDevice device = mInputDevices.valueAt(i); if (device.getInputDeviceId() == inputDeviceId) { return true; return mInputDevices.keyAt(i); } } } catch (RemoteException e) { e.rethrowFromSystemServer(); } return null; } private class InputDeviceListener implements InputManager.InputDeviceListener { @Override public void onInputDeviceAdded(int deviceId) {} @Override public void onInputDeviceChanged(int deviceId) {} @Override public void onInputDeviceRemoved(int deviceId) { synchronized (mLock) { IBinder token = getTokenForInputDeviceIdLocked(deviceId); if (token != null) { mInputDevices.remove(token); } } } return false; } }
services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java +3 −6 Original line number Diff line number Diff line Loading @@ -77,7 +77,6 @@ import android.hardware.display.DisplayManagerInternal; import android.hardware.display.IVirtualDisplayCallback; import android.hardware.display.VirtualDisplayConfig; import android.hardware.input.IVirtualInputDevice; import android.hardware.input.InputManager; import android.hardware.input.VirtualDpadConfig; import android.hardware.input.VirtualKeyboardConfig; import android.hardware.input.VirtualMouseConfig; Loading Loading @@ -195,7 +194,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub private final int mDeviceId; @Nullable private final String mPersistentDeviceId; private final VirtualInputController mInputController; private final InputController mInputController; private final SensorController mSensorController; private final CameraAccessController mCameraAccessController; @Nullable private final ViewConfigurationController mViewConfigurationController; Loading Loading @@ -425,7 +424,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub IBinder token, AttributionSource attributionSource, int deviceId, VirtualInputController inputController, InputController inputController, CameraAccessController cameraAccessController, PendingTrampolineCallback pendingTrampolineCallback, IVirtualDeviceActivityListener activityListener, Loading Loading @@ -479,9 +478,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub mBaseVirtualDisplayFlags = flags; if (inputController == null) { mInputController = new VirtualInputController( context.getSystemService(InputManager.class), context.getSystemService(WindowManager.class), mAttributionSource); mInputController = new InputController(mContext, mAttributionSource); } else { mInputController = inputController; } Loading
services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java +4 −10 Original line number Diff line number Diff line Loading @@ -79,7 +79,6 @@ import android.hardware.display.IDisplayManager; import android.hardware.display.IVirtualDisplayCallback; import android.hardware.display.VirtualDisplayConfig; import android.hardware.input.IVirtualInputDevice; import android.hardware.input.InputManager; import android.hardware.input.VirtualDpadConfig; import android.hardware.input.VirtualKeyboardConfig; import android.hardware.input.VirtualMouseConfig; Loading Loading @@ -222,7 +221,7 @@ public class VirtualDeviceManagerServiceTest { private Context mContext; private VirtualDeviceImpl mDeviceImpl; private VirtualInputController mInputController; private InputController mInputController; private SensorController mSensorController; private CameraAccessController mCameraAccessController; private AssociationInfo mAssociationInfo; Loading Loading @@ -322,9 +321,6 @@ public class VirtualDeviceManagerServiceTest { public void setUp() throws Exception { MockitoAnnotations.initMocks(this); LocalServices.removeServiceForTest(DisplayManagerInternal.class); LocalServices.addService(DisplayManagerInternal.class, mDisplayManagerInternalMock); when(mInputManagerInternalMock.createVirtualTouchscreen(any(), any())) .thenReturn(mIVirtualInputDevice); when(mInputManagerInternalMock.createVirtualKeyboard(any(), any())) Loading @@ -350,15 +346,13 @@ public class VirtualDeviceManagerServiceTest { doNothing().when(mContext).sendBroadcastAsUser(any(), any()); when(mContext.getSystemService(Context.DEVICE_POLICY_SERVICE)).thenReturn( mDevicePolicyManagerMock); when(mContext.getSystemService(Context.WINDOW_SERVICE)).thenReturn(mWindowManager); PowerManager powerManager = new PowerManager(mContext, mIPowerManagerMock, mIThermalServiceMock, new Handler(TestableLooper.get(this).getLooper())); when(mContext.getSystemService(Context.POWER_SERVICE)).thenReturn(powerManager); mInputController = new VirtualInputController( InstrumentationRegistry.getInstrumentation().getTargetContext().getSystemService( InputManager.class), mWindowManager, AttributionSource.myAttributionSource()); mInputController = new InputController(mContext, AttributionSource.myAttributionSource()); mCameraAccessController = new CameraAccessController(mContext, mLocalService, mCameraAccessBlockedCallback); Loading Loading @@ -642,7 +636,7 @@ public class VirtualDeviceManagerServiceTest { mInputController.addDeviceForTesting(BINDER, mIVirtualInputDevice); assertThat(mLocalService.isInputDeviceOwnedByVirtualDevice(INPUT_DEVICE_ID)).isTrue(); mInputController.unregisterInputDevice(BINDER); mInputController.removeDeviceForTesting(BINDER); assertThat(mLocalService.isInputDeviceOwnedByVirtualDevice(INPUT_DEVICE_ID)).isFalse(); } Loading