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

Commit 95fe3813 authored by Vladimir Komsiyski's avatar Vladimir Komsiyski Committed by Android (Google) Code Review
Browse files

Merge "Disallow CC session creation if the keyguard is locked" into main

parents 2f678214 741d4e21
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 {