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

Commit 64123f98 authored by Chilun's avatar Chilun
Browse files

Add createVirtualDisplay in DisplayManager for VirtualDeviceManager

Bug: 201712607
Test: atest DisplayMnagerServiceTest
      Manual
Change-Id: I161f281fc01efb03b0c2544ae2cefb1b89804629
parent 7c95551d
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.TestApi;
import android.app.KeyguardManager;
import android.companion.virtual.IVirtualDevice;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.Resources;
@@ -902,8 +903,16 @@ public final class DisplayManager {
            @NonNull VirtualDisplayConfig virtualDisplayConfig,
            @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler,
            @Nullable Context windowContext) {
        return mGlobal.createVirtualDisplay(mContext, projection, virtualDisplayConfig, callback,
                handler, windowContext);
        return mGlobal.createVirtualDisplay(mContext, projection, null /* virtualDevice */,
                virtualDisplayConfig, callback, handler, windowContext);
    }

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

    /**
+4 −3
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.PropertyInvalidatedCache;
import android.companion.virtual.IVirtualDevice;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.pm.ParceledListSlice;
@@ -582,14 +583,14 @@ public final class DisplayManagerGlobal {
    }

    public VirtualDisplay createVirtualDisplay(@NonNull Context context, MediaProjection projection,
            @NonNull VirtualDisplayConfig virtualDisplayConfig, VirtualDisplay.Callback callback,
            Handler handler, @Nullable Context windowContext) {
            IVirtualDevice virtualDevice, @NonNull VirtualDisplayConfig virtualDisplayConfig,
            VirtualDisplay.Callback callback, Handler handler, @Nullable Context windowContext) {
        VirtualDisplayCallback callbackWrapper = new VirtualDisplayCallback(callback, handler);
        IMediaProjection projectionToken = projection != null ? projection.getProjection() : null;
        int displayId;
        try {
            displayId = mDm.createVirtualDisplay(virtualDisplayConfig, callbackWrapper,
                    projectionToken, context.getPackageName());
                    projectionToken, virtualDevice, context.getPackageName());
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
+0 −26
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@ import android.annotation.IntDef;
import android.annotation.Nullable;
import android.graphics.Point;
import android.hardware.SensorManager;
import android.media.projection.IMediaProjection;
import android.os.Handler;
import android.os.IBinder;
import android.os.PowerManager;
@@ -380,31 +379,6 @@ public abstract class DisplayManagerInternal {
     */
    public abstract void onEarlyInteractivityChange(boolean interactive);

    /**
     * A special API for creates a virtual display with a DisplayPolicyController in system_server.
     * <p>
     * If this method is called without original calling uid, the caller must enforce the
     * corresponding permissions according to the flags.
     *   {@link android.Manifest.permission#CAPTURE_VIDEO_OUTPUT}
     *   {@link android.Manifest.permission#CAPTURE_SECURE_VIDEO_OUTPUT}
     *   {@link android.Manifest.permission#ADD_TRUSTED_DISPLAY}
     *   {@link android.Manifest.permission#INTERNAL_SYSTEM_WINDOW}
     * </p>
     *
     * @param virtualDisplayConfig The arguments for the virtual display configuration. See
     *                             {@link VirtualDisplayConfig} for using it.
     * @param callback Callback to call when the virtual display's state changes, or null if none.
     * @param projection MediaProjection token.
     * @param packageName The package name of the app.
     * @param controller The DisplayWindowPolicyControl that can control what contents are
     *                   allowed to be displayed.
     * @return The newly created virtual display id , or {@link Display#INVALID_DISPLAY} if the
     * virtual display cannot be created.
     */
    public abstract int createVirtualDisplay(VirtualDisplayConfig virtualDisplayConfig,
            IVirtualDisplayCallback callback, IMediaProjection projection, String packageName,
            DisplayWindowPolicyController controller);

    /**
     * Get {@link DisplayWindowPolicyController} associated to the {@link DisplayInfo#displayId}
     *
+3 −2
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.hardware.display;

import android.companion.virtual.IVirtualDevice;
import android.content.pm.ParceledListSlice;
import android.graphics.Point;
import android.hardware.display.BrightnessConfiguration;
@@ -86,10 +87,10 @@ interface IDisplayManager {
    void requestColorMode(int displayId, int colorMode);

    // Requires CAPTURE_VIDEO_OUTPUT, CAPTURE_SECURE_VIDEO_OUTPUT, or an appropriate
    // MediaProjection token for certain combinations of flags.
    // MediaProjection token or VirtualDevice for certain combinations of flags.
    int createVirtualDisplay(in VirtualDisplayConfig virtualDisplayConfig,
            in IVirtualDisplayCallback callback, in IMediaProjection projectionToken,
            String packageName);
            in IVirtualDevice virtualDevice, String packageName);

    // No permissions required, but must be same Uid as the creator.
    void resizeVirtualDisplay(in IVirtualDisplayCallback token,
+52 −1
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import android.os.RemoteException;
import android.util.ExceptionUtils;
import android.util.Slog;
import android.util.SparseArray;
import android.window.DisplayWindowPolicyController;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.DumpUtils;
@@ -38,11 +39,11 @@ import com.android.server.SystemService;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;


/** @hide */
@SuppressLint("LongLogTag")
public class VirtualDeviceManagerService extends SystemService {

@@ -84,6 +85,15 @@ public class VirtualDeviceManagerService extends SystemService {
        publishLocalService(VirtualDeviceManagerInternal.class, new LocalService());
    }

    @GuardedBy("mVirtualDeviceManagerLock")
    private boolean isValidVirtualDeviceLocked(IVirtualDevice virtualDevice) {
        try {
            return mVirtualDevices.contains(virtualDevice.getAssociationId());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    @Override
    public void onUserStarting(@NonNull TargetUser user) {
        super.onUserStarting(user);
@@ -121,6 +131,7 @@ public class VirtualDeviceManagerService extends SystemService {

        private final AssociationInfo mAssociationInfo;
        private final int mOwnerUid;
        private final ArrayList<Integer> mDisplayIds = new ArrayList<>();

        private VirtualDeviceImpl(int ownerUid, IBinder token, AssociationInfo associationInfo) {
            mOwnerUid = ownerUid;
@@ -149,6 +160,24 @@ public class VirtualDeviceManagerService extends SystemService {
        public void binderDied() {
            close();
        }

        DisplayWindowPolicyController onVirtualDisplayCreatedLocked(int displayId) {
            if (mDisplayIds.contains(displayId)) {
                throw new IllegalStateException(
                        "Virtual device already have a virtual display with ID " + displayId);
            }
            mDisplayIds.add(displayId);
            // TODO(b/201712607): Return the corresponding DisplayWindowPolicyController.
            return null;
        }

        void onVirtualDisplayRemovedLocked(int displayId) {
            if (!mDisplayIds.contains(displayId)) {
                throw new IllegalStateException(
                        "Virtual device doesn't have a virtual display with ID " + displayId);
            }
            mDisplayIds.remove(displayId);
        }
    }

    class VirtualDeviceManagerImpl extends IVirtualDeviceManager.Stub {
@@ -229,6 +258,28 @@ public class VirtualDeviceManagerService extends SystemService {

    private final class LocalService extends VirtualDeviceManagerInternal {

        @Override
        public boolean isValidVirtualDevice(IVirtualDevice virtualDevice) {
            synchronized (mVirtualDeviceManagerLock) {
                return isValidVirtualDeviceLocked(virtualDevice);
            }
        }

        @Override
        public DisplayWindowPolicyController onVirtualDisplayCreated(IVirtualDevice virtualDevice,
                int displayId) {
            synchronized (mVirtualDeviceManagerLock) {
                return ((VirtualDeviceImpl) virtualDevice).onVirtualDisplayCreatedLocked(displayId);
            }
        }

        @Override
        public void onVirtualDisplayRemoved(IVirtualDevice virtualDevice, int displayId) {
            synchronized (mVirtualDeviceManagerLock) {
                ((VirtualDeviceImpl) virtualDevice).onVirtualDisplayRemovedLocked(displayId);
            }
        }

        @Override
        public boolean isAppOwnerOfAnyVirtualDevice(int uid) {
            synchronized (mVirtualDeviceManagerLock) {
Loading