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

Commit 65f19258 authored by Vladimir Komsiyski's avatar Vladimir Komsiyski
Browse files

Close the ImageReader when the session is closed.

Relying on a DisplayListener is clunky and we can't use the
VirtualDispaly.Callback because it's created server-side.

Using the callback proxy by caching the session but need some
additional synchronization because getScreenshot() will throw
if the reader is already closed and it's better to return null

Bug: 439774796
Flag: android.companion.virtualdevice.flags.computer_control_consent
Test: presubmit
Change-Id: I8a9a80234473998db77d7ae8cc3c33c7720769ff
parent 2a22330b
Loading
Loading
Loading
Loading
+21 −5
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import android.view.Display;
import android.view.DisplayInfo;
import android.view.Surface;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;

import java.lang.annotation.ElementType;
@@ -97,9 +98,11 @@ public final class ComputerControlSession implements AutoCloseable {

    @NonNull
    private final IComputerControlSession mSession;
    // TODO(b/439774796): Make this non-nullable.
    private final Object mLock = new Object();
    @GuardedBy("mLock")
    @Nullable
    private final ImageReader mImageReader;
    private ImageReader mImageReader;


    /** @hide */
    public ComputerControlSession(int displayId, @NonNull IVirtualDisplayCallback displayToken,
@@ -157,8 +160,10 @@ public final class ComputerControlSession implements AutoCloseable {
     */
    @Nullable
    public Image getScreenshot() {
        synchronized (mLock) {
            return mImageReader == null ? null : mImageReader.acquireLatestImage();
        }
    }

    /**
     * Sends a tap event to the computer control session at the given location.
@@ -261,6 +266,15 @@ public final class ComputerControlSession implements AutoCloseable {
        }
    }

    private void closeImageReader() {
        synchronized (mLock) {
            if (mImageReader != null) {
                mImageReader.close();
                mImageReader = null;
            }
        }
    }

    /** Callback for computer control session events. */
    public interface Callback {

@@ -299,6 +313,7 @@ public final class ComputerControlSession implements AutoCloseable {

        private final Callback mCallback;
        private final Executor mExecutor;
        private ComputerControlSession mSession;

        public CallbackProxy(@NonNull Executor executor, @NonNull Callback callback) {
            mExecutor = executor;
@@ -315,9 +330,9 @@ public final class ComputerControlSession implements AutoCloseable {
        @Override
        public void onSessionCreated(int displayId, IVirtualDisplayCallback displayToken,
                IComputerControlSession session) {
            mSession = new ComputerControlSession(displayId, displayToken, session);
            Binder.withCleanCallingIdentity(() ->
                    mExecutor.execute(() -> mCallback.onSessionCreated(
                            new ComputerControlSession(displayId, displayToken, session))));
                    mExecutor.execute(() -> mCallback.onSessionCreated(mSession)));
        }

        @Override
@@ -328,6 +343,7 @@ public final class ComputerControlSession implements AutoCloseable {

        @Override
        public void onSessionClosed() {
            mSession.closeImageReader();
            Binder.withCleanCallingIdentity(() ->
                    mExecutor.execute(() -> mCallback.onSessionClosed()));
        }