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

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

Computer Control session close callback.

Bug: 432678191
Test: atest
Flag: android.companion.virtualdevice.flags.computer_control_access
Change-Id: Id824927726dd7d9e8edf097acd332e3eea20cb58
parent d7822e89
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -127,11 +127,17 @@ public final class ComputerControlSession implements AutoCloseable {
    /** Callback for computer control session events. */
    public interface Callback {

        /** Called when the session request was successfully fulfilled. */
        /** Called when the session has been successfully created. */
        void onSessionCreated(@NonNull ComputerControlSession session);

        /** Called when the session failed to be created. */
        void onSessionCreationFailed(@SessionCreationError int errorCode);

        /**
         * Called when the session has been closed, either via an explicit call to {@link #close()},
         * or due to an automatic closure event, triggered by the framework.
         */
        void onSessionClosed();
    }

    /** @hide */
@@ -157,5 +163,11 @@ public final class ComputerControlSession implements AutoCloseable {
            Binder.withCleanCallingIdentity(() ->
                    mExecutor.execute(() -> mCallback.onSessionCreationFailed(errorCode)));
        }

        @Override
        public void onSessionClosed() {
            Binder.withCleanCallingIdentity(() ->
                    mExecutor.execute(() -> mCallback.onSessionClosed()));
        }
    }
}
+3 −0
Original line number Diff line number Diff line
@@ -30,4 +30,7 @@ oneway interface IComputerControlSessionCallback {

    /** Called when the session failed to be created. */
    void onSessionCreationFailed(int errorCode);

    /** Called when the session has been closed. */
    void onSessionClosed();
}
+25 −4
Original line number Diff line number Diff line
@@ -76,7 +76,8 @@ public class ComputerControlSessionProcessor {
            }
            IComputerControlSession session = new ComputerControlSessionImpl(
                    callback.asBinder(), params, attributionSource, mPackageManager,
                    mVirtualDeviceFactory, mWindowManagerInternal, this::onSessionClosed);
                    mVirtualDeviceFactory, mWindowManagerInternal,
                    new OnSessionClosedListener(params.getName(), callback));
            mSessions.add(session.asBinder());
            try {
                callback.onSessionCreated(session);
@@ -87,9 +88,29 @@ public class ComputerControlSessionProcessor {
        }
    }

    private void onSessionClosed(IBinder token) {
    private class OnSessionClosedListener implements ComputerControlSessionImpl.OnClosedListener {
        private final String mSessionName;
        private final IComputerControlSessionCallback mAppCallback;

        OnSessionClosedListener(@NonNull String sessionName,
                @NonNull IComputerControlSessionCallback appCallback) {
            mSessionName = sessionName;
            mAppCallback = appCallback;
        }

        @Override
        public void onClosed(IBinder token) {
            synchronized (mSessions) {
            mSessions.remove(token);
                if (!mSessions.remove(token)) {
                    return;
                }
            }
            try {
                mAppCallback.onSessionClosed();
            } catch (RemoteException e) {
                Slog.w(TAG, "Failed to notify ComputerControlSession " + mSessionName
                        + " about session closure");
            }
        }
    }

+15 −2
Original line number Diff line number Diff line
@@ -31,11 +31,15 @@ import android.companion.virtual.computercontrol.IComputerControlSessionCallback
import android.content.AttributionSource;
import android.content.Context;
import android.os.Binder;
import android.platform.test.annotations.Presubmit;
import android.view.Surface;

import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;

import com.android.server.LocalServices;
import com.android.server.wm.WindowManagerInternal;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -45,9 +49,12 @@ import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

@Presubmit
@RunWith(AndroidJUnit4.class)
public class ComputerControlSessionProcessorTest {

    @Mock
    private WindowManagerInternal mWindowManagerInternal;
    @Mock
    private ComputerControlSessionProcessor.VirtualDeviceFactory mVirtualDeviceFactory;
    @Mock
@@ -76,6 +83,9 @@ public class ComputerControlSessionProcessorTest {
    public void setUp() {
        mMockitoSession = MockitoAnnotations.openMocks(this);

        LocalServices.removeServiceForTest(WindowManagerInternal.class);
        LocalServices.addService(WindowManagerInternal.class, mWindowManagerInternal);

        when(mVirtualDeviceFactory.createVirtualDevice(any(), any(), any(), any()))
                .thenReturn(mVirtualDevice);
        when(mComputerControlSessionCallback.asBinder()).thenReturn(new Binder());
@@ -103,16 +113,19 @@ public class ComputerControlSessionProcessorTest {
                    .onSessionCreationFailed(ComputerControlSession.ERROR_SESSION_LIMIT_REACHED);

            mSessionArgumentCaptor.getAllValues().getFirst().close();
            mSessionArgumentCaptor.getAllValues().getFirst().close();
            verify(mComputerControlSessionCallback, times(1)).onSessionClosed();

            mProcessor.processNewSessionRequest(AttributionSource.myAttributionSource(),
                    mParams, mComputerControlSessionCallback);
            verify(mComputerControlSessionCallback,
                    times(MAXIMUM_CONCURRENT_SESSIONS + 1))
            verify(mComputerControlSessionCallback, times(MAXIMUM_CONCURRENT_SESSIONS + 1))
                    .onSessionCreated(mSessionArgumentCaptor.capture());
        } finally {
            for (IComputerControlSession session : mSessionArgumentCaptor.getAllValues()) {
                session.close();
            }
            verify(mComputerControlSessionCallback, times(MAXIMUM_CONCURRENT_SESSIONS + 1))
                    .onSessionClosed();
        }
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import android.hardware.input.VirtualKeyboardConfig;
import android.hardware.input.VirtualTouchscreenConfig;
import android.os.Binder;
import android.os.IBinder;
import android.platform.test.annotations.Presubmit;
import android.view.Surface;
import android.view.WindowManager;

@@ -56,6 +57,7 @@ import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

@Presubmit
@RunWith(AndroidJUnit4.class)
public class ComputerControlSessionTest {