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

Commit 1feb56be authored by Maurice Lam's avatar Maurice Lam
Browse files

Add parameter annotations to createVirtualDisplay

Also changed the Handler parameter to Executor

Bug: 217742182
Test: atest CtsVirtualDevicesTestCases
Change-Id: I3321927b36361168655f4886825955a642fb6c79
parent 813b8298
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -18344,8 +18344,8 @@ package android.hardware.display {
  }
  public final class DisplayManager {
    method public android.hardware.display.VirtualDisplay createVirtualDisplay(@NonNull String, int, int, int, @Nullable android.view.Surface, int);
    method public android.hardware.display.VirtualDisplay createVirtualDisplay(@NonNull String, int, int, int, @Nullable android.view.Surface, int, @Nullable android.hardware.display.VirtualDisplay.Callback, @Nullable android.os.Handler);
    method public android.hardware.display.VirtualDisplay createVirtualDisplay(@NonNull String, @IntRange(from=1) int, @IntRange(from=1) int, @IntRange(from=1) int, @Nullable android.view.Surface, int);
    method public android.hardware.display.VirtualDisplay createVirtualDisplay(@NonNull String, @IntRange(from=1) int, @IntRange(from=1) int, @IntRange(from=1) int, @Nullable android.view.Surface, int, @Nullable android.hardware.display.VirtualDisplay.Callback, @Nullable android.os.Handler);
    method public android.view.Display getDisplay(int);
    method public android.view.Display[] getDisplays();
    method public android.view.Display[] getDisplays(String);
+1 −1
Original line number Diff line number Diff line
@@ -2751,7 +2751,7 @@ package android.companion.virtual {
    method public void addActivityListener(@NonNull android.companion.virtual.VirtualDeviceManager.ActivityListener, @NonNull java.util.concurrent.Executor);
    method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void close();
    method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.companion.virtual.audio.VirtualAudioDevice createVirtualAudioDevice(@NonNull android.hardware.display.VirtualDisplay, @Nullable java.util.concurrent.Executor, @Nullable android.companion.virtual.audio.VirtualAudioDevice.AudioConfigurationChangeCallback);
    method @Nullable public android.hardware.display.VirtualDisplay createVirtualDisplay(int, int, int, @Nullable android.view.Surface, int, @Nullable android.os.Handler, @Nullable android.hardware.display.VirtualDisplay.Callback);
    method @Nullable public android.hardware.display.VirtualDisplay createVirtualDisplay(@IntRange(from=1) int, @IntRange(from=1) int, @IntRange(from=1) int, @Nullable android.view.Surface, int, @NonNull java.util.concurrent.Executor, @Nullable android.hardware.display.VirtualDisplay.Callback);
    method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualKeyboard createVirtualKeyboard(@NonNull android.hardware.display.VirtualDisplay, @NonNull String, int, int);
    method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualMouse createVirtualMouse(@NonNull android.hardware.display.VirtualDisplay, @NonNull String, int, int);
    method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualTouchscreen createVirtualTouchscreen(@NonNull android.hardware.display.VirtualDisplay, @NonNull String, int, int);
+12 −12
Original line number Diff line number Diff line
@@ -16,10 +16,11 @@

package android.companion.virtual;

import android.annotation.CallbackExecutor;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.app.Activity;
@@ -31,6 +32,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.graphics.Point;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager.VirtualDisplayFlag;
import android.hardware.display.VirtualDisplay;
import android.hardware.display.VirtualDisplayConfig;
import android.hardware.input.VirtualKeyboard;
@@ -46,6 +48,7 @@ import android.os.ResultReceiver;
import android.util.ArrayMap;
import android.view.Surface;

import java.util.Objects;
import java.util.concurrent.Executor;

/**
@@ -210,25 +213,22 @@ public final class VirtualDeviceManager {
         * {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_PUBLIC VIRTUAL_DISPLAY_FLAG_PUBLIC} and
         * {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY
         * VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY}.
         * @param executor The executor on which {@code callback} will be invoked. This is ignored
         * if {@code callback} is {@code null}.
         * @param callback Callback to call when the state of the {@link VirtualDisplay} changes
         * @param handler The handler on which the listener should be invoked, or null
         * if the listener should be invoked on the calling thread's looper.
         * @return The newly created virtual display, or {@code null} if the application could
         * not create the virtual display.
         *
         * @see DisplayManager#createVirtualDisplay
         */
        // Suppress "ExecutorRegistration" because DisplayManager.createVirtualDisplay takes a
        // handler
        @SuppressLint("ExecutorRegistration")
        @Nullable
        public VirtualDisplay createVirtualDisplay(
                int width,
                int height,
                int densityDpi,
                @IntRange(from = 1) int width,
                @IntRange(from = 1) int height,
                @IntRange(from = 1) int densityDpi,
                @Nullable Surface surface,
                int flags,
                @Nullable Handler handler,
                @VirtualDisplayFlag int flags,
                @NonNull @CallbackExecutor Executor executor,
                @Nullable VirtualDisplay.Callback callback) {
            // TODO(b/205343547): Handle display groups properly instead of creating a new display
            //  group for every new virtual display created using this API.
@@ -244,7 +244,7 @@ public final class VirtualDeviceManager {
                            .setFlags(getVirtualDisplayFlags(flags))
                            .build(),
                    callback,
                    handler);
                    Objects.requireNonNull(executor));
        }

        /**
+56 −9
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static android.view.Display.HdrCapabilities.HdrType;
import android.Manifest;
import android.annotation.FloatRange;
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.LongDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -38,6 +39,8 @@ import android.graphics.Point;
import android.media.projection.MediaProjection;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.Looper;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
@@ -48,6 +51,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;


/**
@@ -104,6 +108,25 @@ public final class DisplayManager {
    public static final String DISPLAY_CATEGORY_PRESENTATION =
            "android.hardware.display.category.PRESENTATION";

    /** @hide **/
    @IntDef(prefix = "VIRTUAL_DISPLAY_FLAG_", flag = true, value = {
            VIRTUAL_DISPLAY_FLAG_PUBLIC,
            VIRTUAL_DISPLAY_FLAG_PRESENTATION,
            VIRTUAL_DISPLAY_FLAG_SECURE,
            VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY,
            VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
            VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD,
            VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH,
            VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT,
            VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL,
            VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS,
            VIRTUAL_DISPLAY_FLAG_TRUSTED,
            VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP,
            VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface VirtualDisplayFlag {}

    /**
     * Virtual display flag: Create a public display.
     *
@@ -820,7 +843,11 @@ public final class DisplayManager {
     * VirtualDisplay.Callback, Handler)
     */
    public VirtualDisplay createVirtualDisplay(@NonNull String name,
            int width, int height, int densityDpi, @Nullable Surface surface, int flags) {
            @IntRange(from = 1) int width,
            @IntRange(from = 1) int height,
            @IntRange(from = 1) int densityDpi,
            @Nullable Surface surface,
            @VirtualDisplayFlag int flags) {
        return createVirtualDisplay(name, width, height, densityDpi, surface, flags, null, null);
    }

@@ -868,8 +895,13 @@ public final class DisplayManager {
     * a virtual display with the specified flags.
     */
    public VirtualDisplay createVirtualDisplay(@NonNull String name,
            int width, int height, int densityDpi, @Nullable Surface surface, int flags,
            @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) {
            @IntRange(from = 1) int width,
            @IntRange(from = 1) int height,
            @IntRange(from = 1) int densityDpi,
            @Nullable Surface surface,
            @VirtualDisplayFlag int flags,
            @Nullable VirtualDisplay.Callback callback,
            @Nullable Handler handler) {
        final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(name, width,
                height, densityDpi);
        builder.setFlags(flags);
@@ -882,9 +914,16 @@ public final class DisplayManager {

    // TODO : Remove this hidden API after remove all callers. (Refer to MultiDisplayService)
    /** @hide */
    public VirtualDisplay createVirtualDisplay(@Nullable MediaProjection projection,
            @NonNull String name, int width, int height, int densityDpi, @Nullable Surface surface,
            int flags, @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler,
    public VirtualDisplay createVirtualDisplay(
            @Nullable MediaProjection projection,
            @NonNull String name,
            @IntRange(from = 1) int width,
            @IntRange(from = 1) int height,
            @IntRange(from = 1) int densityDpi,
            @Nullable Surface surface,
            @VirtualDisplayFlag int flags,
            @Nullable VirtualDisplay.Callback callback,
            @Nullable Handler handler,
            @Nullable String uniqueId) {
        final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(name, width,
                height, densityDpi);
@@ -904,16 +943,24 @@ public final class DisplayManager {
            @NonNull VirtualDisplayConfig virtualDisplayConfig,
            @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler,
            @Nullable Context windowContext) {
        Executor executor = null;
        // If callback is null, the executor will not be used. Avoid creating the handler and the
        // handler executor.
        if (callback != null) {
            executor = new HandlerExecutor(
                    Handler.createAsync(handler != null ? handler.getLooper() : Looper.myLooper()));
        }
        return mGlobal.createVirtualDisplay(mContext, projection, null /* virtualDevice */,
                virtualDisplayConfig, callback, handler, windowContext);
                virtualDisplayConfig, callback, executor, windowContext);
    }

    /** @hide */
    public VirtualDisplay createVirtualDisplay(@Nullable IVirtualDevice virtualDevice,
            @NonNull VirtualDisplayConfig virtualDisplayConfig,
            @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) {
            @Nullable VirtualDisplay.Callback callback,
            @NonNull Executor executor) {
        return mGlobal.createVirtualDisplay(mContext, null /* projection */, virtualDevice,
                virtualDisplayConfig, callback, handler, null);
                virtualDisplayConfig, callback, executor, null);
    }

    /**
+20 −42
Original line number Diff line number Diff line
@@ -56,6 +56,8 @@ import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Executor;

/**
 * Manager communication with the display manager service on behalf of
@@ -585,8 +587,9 @@ public final class DisplayManagerGlobal {

    public VirtualDisplay createVirtualDisplay(@NonNull Context context, MediaProjection projection,
            IVirtualDevice virtualDevice, @NonNull VirtualDisplayConfig virtualDisplayConfig,
            VirtualDisplay.Callback callback, Handler handler, @Nullable Context windowContext) {
        VirtualDisplayCallback callbackWrapper = new VirtualDisplayCallback(callback, handler);
            VirtualDisplay.Callback callback, @Nullable Executor executor,
            @Nullable Context windowContext) {
        VirtualDisplayCallback callbackWrapper = new VirtualDisplayCallback(callback, executor);
        IMediaProjection projectionToken = projection != null ? projection.getProjection() : null;
        int displayId;
        try {
@@ -1048,61 +1051,36 @@ public final class DisplayManagerGlobal {
    }

    private final static class VirtualDisplayCallback extends IVirtualDisplayCallback.Stub {
        private VirtualDisplayCallbackDelegate mDelegate;
        @Nullable private final VirtualDisplay.Callback mCallback;
        @Nullable private final Executor mExecutor;

        public VirtualDisplayCallback(VirtualDisplay.Callback callback, Handler handler) {
            if (callback != null) {
                mDelegate = new VirtualDisplayCallbackDelegate(callback, handler);
            }
        VirtualDisplayCallback(VirtualDisplay.Callback callback, Executor executor) {
            mCallback = callback;
            mExecutor = mCallback != null ? Objects.requireNonNull(executor) : null;
        }

        // These methods are called from the binder thread, but the AIDL is oneway, so it should be
        // safe to call the callback on arbitrary executors directly without risking blocking
        // the system.

        @Override // Binder call
        public void onPaused() {
            if (mDelegate != null) {
                mDelegate.sendEmptyMessage(VirtualDisplayCallbackDelegate.MSG_DISPLAY_PAUSED);
            if (mCallback != null) {
                mExecutor.execute(mCallback::onPaused);
            }
        }

        @Override // Binder call
        public void onResumed() {
            if (mDelegate != null) {
                mDelegate.sendEmptyMessage(VirtualDisplayCallbackDelegate.MSG_DISPLAY_RESUMED);
            if (mCallback != null) {
                mExecutor.execute(mCallback::onResumed);
            }
        }

        @Override // Binder call
        public void onStopped() {
            if (mDelegate != null) {
                mDelegate.sendEmptyMessage(VirtualDisplayCallbackDelegate.MSG_DISPLAY_STOPPED);
            }
        }
    }

    private final static class VirtualDisplayCallbackDelegate extends Handler {
        public static final int MSG_DISPLAY_PAUSED = 0;
        public static final int MSG_DISPLAY_RESUMED = 1;
        public static final int MSG_DISPLAY_STOPPED = 2;

        private final VirtualDisplay.Callback mCallback;

        public VirtualDisplayCallbackDelegate(VirtualDisplay.Callback callback,
                Handler handler) {
            super(handler != null ? handler.getLooper() : Looper.myLooper(), null, true /*async*/);
            mCallback = callback;
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_DISPLAY_PAUSED:
                    mCallback.onPaused();
                    break;
                case MSG_DISPLAY_RESUMED:
                    mCallback.onResumed();
                    break;
                case MSG_DISPLAY_STOPPED:
                    mCallback.onStopped();
                    break;
            if (mCallback != null) {
                mExecutor.execute(mCallback::onStopped);
            }
        }
    }
Loading