Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7579eb82 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Clean up VDM's InputController" into main

parents 2aeee525 a761b905
Loading
Loading
Loading
Loading
+49 −68
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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();

@@ -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();
@@ -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);
    }
@@ -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: ");
@@ -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;
    }
}
+3 −6
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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,
@@ -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;
        }
+4 −10
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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()))
@@ -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);

@@ -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();
    }