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

Commit 741d4e21 authored by [D's avatar [D[1;5D
Browse files

Disallow CC session creation if the keyguard is locked

Fix: 437903965
Test: atest
Flag: android.companion.virtualdevice.flags.computer_control_access
Change-Id: I4698cc2234f660f4d4098a8c7f5d075046cd0fdc
parent a8d1cf90
Loading
Loading
Loading
Loading
+13 −3
Original line number Diff line number Diff line
@@ -51,11 +51,21 @@ public final class ComputerControlSession implements AutoCloseable {
     */
    public static final int ERROR_SESSION_LIMIT_REACHED = -1;

    /**
     * Error code indicating that a new session cannot be created because the lock screen (also
     * known as Keyguard) is showing.
     *
     * <p>This is a transient error and the session creation request can be retried later.</p>
     *
     * @see android.app.KeyguardManager#isKeyguardLocked()
     */
    public static final int ERROR_KEYGUARD_LOCKED = -2;

    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(
            prefix = "ERROR_",
            value = {ERROR_SESSION_LIMIT_REACHED})
    @IntDef(prefix = "ERROR_", value = {
            ERROR_SESSION_LIMIT_REACHED,
            ERROR_KEYGUARD_LOCKED})
    @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
    public @interface SessionCreationError {
    }
+20 −7
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.server.companion.virtual.computercontrol;

import android.annotation.NonNull;
import android.app.KeyguardManager;
import android.companion.virtual.IVirtualDevice;
import android.companion.virtual.IVirtualDeviceActivityListener;
import android.companion.virtual.VirtualDeviceParams;
@@ -45,6 +46,7 @@ public class ComputerControlSessionProcessor {
    static final int MAXIMUM_CONCURRENT_SESSIONS = 5;

    private final PackageManager mPackageManager;
    private final KeyguardManager mKeyguardManager;
    private final VirtualDeviceFactory mVirtualDeviceFactory;
    private final WindowManagerInternal mWindowManagerInternal;
    private final ArraySet<IBinder> mSessions = new ArraySet<>();
@@ -53,6 +55,7 @@ public class ComputerControlSessionProcessor {
            Context context, VirtualDeviceFactory virtualDeviceFactory) {
        mVirtualDeviceFactory = virtualDeviceFactory;
        mPackageManager = context.getPackageManager();
        mKeyguardManager = context.getSystemService(KeyguardManager.class);
        mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
    }

@@ -63,15 +66,15 @@ public class ComputerControlSessionProcessor {
            @NonNull AttributionSource attributionSource,
            @NonNull ComputerControlSessionParams params,
            @NonNull IComputerControlSessionCallback callback) {
        if (mKeyguardManager.isKeyguardLocked()) {
            dispatchSessionCreationFailed(
                    callback, params, ComputerControlSession.ERROR_KEYGUARD_LOCKED);
            return;
        }
        synchronized (mSessions) {
            if (mSessions.size() >= MAXIMUM_CONCURRENT_SESSIONS) {
                try {
                    callback.onSessionCreationFailed(
                            ComputerControlSession.ERROR_SESSION_LIMIT_REACHED);
                } catch (RemoteException e) {
                    Slog.e(TAG, "Failed to notify ComputerControlSession " + params.getName()
                            + " about session creation failure");
                }
                dispatchSessionCreationFailed(
                        callback, params, ComputerControlSession.ERROR_SESSION_LIMIT_REACHED);
                return;
            }
            IComputerControlSession session = new ComputerControlSessionImpl(
@@ -88,6 +91,16 @@ public class ComputerControlSessionProcessor {
        }
    }

    private void dispatchSessionCreationFailed(IComputerControlSessionCallback callback,
            ComputerControlSessionParams params, int reason) {
        try {
            callback.onSessionCreationFailed(reason);
        } catch (RemoteException e) {
            Slog.e(TAG, "Failed to notify ComputerControlSession " + params.getName()
                    + " about session creation failure");
        }
    }

    private class OnSessionClosedListener implements ComputerControlSessionImpl.OnClosedListener {
        private final String mSessionName;
        private final IComputerControlSessionCallback mAppCallback;
+20 −2
Original line number Diff line number Diff line
@@ -19,10 +19,12 @@ package com.android.server.companion.virtual.computercontrol;
import static com.android.server.companion.virtual.computercontrol.ComputerControlSessionProcessor.MAXIMUM_CONCURRENT_SESSIONS;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.app.KeyguardManager;
import android.companion.virtual.IVirtualDevice;
import android.companion.virtual.computercontrol.ComputerControlSession;
import android.companion.virtual.computercontrol.ComputerControlSessionParams;
@@ -30,6 +32,7 @@ import android.companion.virtual.computercontrol.IComputerControlSession;
import android.companion.virtual.computercontrol.IComputerControlSessionCallback;
import android.content.AttributionSource;
import android.content.Context;
import android.content.ContextWrapper;
import android.os.Binder;
import android.platform.test.annotations.Presubmit;
import android.view.Surface;
@@ -53,6 +56,8 @@ import org.mockito.MockitoAnnotations;
@RunWith(AndroidJUnit4.class)
public class ComputerControlSessionProcessorTest {

    @Mock
    private KeyguardManager mKeyguardManager;
    @Mock
    private WindowManagerInternal mWindowManagerInternal;
    @Mock
@@ -73,8 +78,7 @@ public class ComputerControlSessionProcessorTest {
            .setDisplayAlwaysUnlocked(true)
            .build();

    private final Context mContext =
            InstrumentationRegistry.getInstrumentation().getTargetContext();
    private Context mContext;
    private ComputerControlSessionProcessor mProcessor;

    private AutoCloseable mMockitoSession;
@@ -86,6 +90,10 @@ public class ComputerControlSessionProcessorTest {
        LocalServices.removeServiceForTest(WindowManagerInternal.class);
        LocalServices.addService(WindowManagerInternal.class, mWindowManagerInternal);

        mContext = spy(new ContextWrapper(
                InstrumentationRegistry.getInstrumentation().getTargetContext()));
        when(mContext.getSystemService(Context.KEYGUARD_SERVICE)).thenReturn(mKeyguardManager);

        when(mVirtualDeviceFactory.createVirtualDevice(any(), any(), any(), any()))
                .thenReturn(mVirtualDevice);
        when(mComputerControlSessionCallback.asBinder()).thenReturn(new Binder());
@@ -97,6 +105,16 @@ public class ComputerControlSessionProcessorTest {
        mMockitoSession.close();
    }

    @Test
    public void keyguardLocked_sessionNotCreated() throws Exception {
        when(mKeyguardManager.isKeyguardLocked()).thenReturn(true);

        mProcessor.processNewSessionRequest(AttributionSource.myAttributionSource(),
                mParams, mComputerControlSessionCallback);
        verify(mComputerControlSessionCallback)
                .onSessionCreationFailed(ComputerControlSession.ERROR_KEYGUARD_LOCKED);
    }

    @Test
    public void maximumNumberOfSessions_isEnforced() throws Exception {
        try {