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

Commit 6731d99b authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "API for setting the power state of a virtual device." into main

parents e40793f4 a5e8b705
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -3510,6 +3510,7 @@ package android.companion.virtual {
    method public int getDeviceId();
    method @FlaggedApi("android.companion.virtual.flags.vdm_public_apis") @Nullable public String getPersistentDeviceId();
    method @NonNull public java.util.List<android.companion.virtual.sensor.VirtualSensor> getVirtualSensorList();
    method @FlaggedApi("android.companion.virtualdevice.flags.device_aware_display_power") @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void goToSleep();
    method public void launchPendingIntent(int, @NonNull android.app.PendingIntent, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.IntConsumer);
    method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void registerIntentInterceptor(@NonNull android.content.IntentFilter, @NonNull java.util.concurrent.Executor, @NonNull android.companion.virtual.VirtualDeviceManager.IntentInterceptorCallback);
    method public void removeActivityListener(@NonNull android.companion.virtual.VirtualDeviceManager.ActivityListener);
@@ -3521,6 +3522,7 @@ package android.companion.virtual {
    method @FlaggedApi("android.companion.virtual.flags.vdm_custom_ime") @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void setDisplayImePolicy(int, int);
    method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void setShowPointerIcon(boolean);
    method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void unregisterIntentInterceptor(@NonNull android.companion.virtual.VirtualDeviceManager.IntentInterceptorCallback);
    method @FlaggedApi("android.companion.virtualdevice.flags.device_aware_display_power") @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void wakeUp();
  }
  public final class VirtualDeviceParams implements android.os.Parcelable {
+12 −0
Original line number Diff line number Diff line
@@ -93,6 +93,18 @@ interface IVirtualDevice {
     */
    boolean canCreateMirrorDisplays();

    /*
     * Turns off all trusted non-mirror displays of the virtual device.
     */
    @EnforcePermission("CREATE_VIRTUAL_DEVICE")
    void goToSleep();

    /**
     * Turns on all trusted non-mirror displays of the virtual device.
     */
    @EnforcePermission("CREATE_VIRTUAL_DEVICE")
    void wakeUp();

    /**
     * Closes the virtual device and frees all associated resources.
     */
+18 −0
Original line number Diff line number Diff line
@@ -251,6 +251,24 @@ public class VirtualDeviceInternal {
        }
    }

    @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
    void goToSleep() {
        try {
            mVirtualDevice.goToSleep();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
    void wakeUp() {
        try {
            mVirtualDevice.wakeUp();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    void launchPendingIntent(
            int displayId,
            @NonNull PendingIntent pendingIntent,
+39 −0
Original line number Diff line number Diff line
@@ -619,6 +619,45 @@ public final class VirtualDeviceManager {
            return mVirtualDeviceInternal.getVirtualSensorList();
        }

        /**
         * Forces all trusted non-mirror displays of the virtual device to turn off.
         *
         * <p>After this action, if all displays across all devices, including the default one, are
         * off, then the physical device will be put to sleep. If the displays of this virtual
         * device are already off, then nothing will happen.</p>
         *
         * <p>Overrides all the wake locks that are held. This is equivalent to pressing a "virtual
         * power key" to turn off the screen.</p>
         *
         * @see #wakeUp()
         * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_TRUSTED
         * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY
         */
        @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_DEVICE_AWARE_DISPLAY_POWER)
        @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
        public void goToSleep() {
            mVirtualDeviceInternal.goToSleep();
        }

        /**
         * Forces all trusted non-mirror displays of the virtual device to turn on.
         *
         * <p>If the displays of this virtual device are turned off, then they will be turned on.
         * Additionally, if the device is asleep it will be awoken. If the displays of this virtual
         * device are already on, then nothing will happen.</p>
         *
         * <p>This is equivalent to pressing a "virtual power key" to turn on the screen.</p>
         *
         * @see #goToSleep()
         * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_TRUSTED
         * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY
         */
        @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_DEVICE_AWARE_DISPLAY_POWER)
        @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
        public void wakeUp() {
            mVirtualDeviceInternal.wakeUp();
        }

        /**
         * Launches a given pending intent on the give display ID.
         *
+68 −4
Original line number Diff line number Diff line
@@ -99,6 +99,7 @@ import android.os.PermissionEnforcer;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.ArrayMap;
@@ -203,6 +204,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
    private IVirtualDeviceSoundEffectListener mSoundEffectListener;
    private final DisplayManagerGlobal mDisplayManager;
    private final DisplayManagerInternal mDisplayManagerInternal;
    private final PowerManager mPowerManager;
    @GuardedBy("mVirtualDeviceLock")
    private final Map<IBinder, IntentFilter> mIntentInterceptors = new ArrayMap<>();
    @NonNull
@@ -418,6 +420,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
        mDevicePolicies = params.getDevicePolicies();
        mDisplayManager = displayManager;
        mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
        mPowerManager = context.getSystemService(PowerManager.class);
        if (inputController == null) {
            mInputController = new InputController(
                    context.getMainThreadHandler(),
@@ -575,6 +578,52 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
                : mAssociationInfo.getId();
    }

    @Override // Binder call
    @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
    public void goToSleep() {
        super.goToSleep_enforcePermission();
        final long now = SystemClock.uptimeMillis();
        final long ident = Binder.clearCallingIdentity();
        try {
            synchronized (mVirtualDeviceLock) {
                for (int i = 0; i < mVirtualDisplays.size(); i++) {
                    VirtualDisplayWrapper wrapper = mVirtualDisplays.valueAt(i);
                    if (!wrapper.isTrusted() || wrapper.isMirror()) {
                        continue;
                    }
                    int displayId = mVirtualDisplays.keyAt(i);
                    mPowerManager.goToSleep(displayId, now,
                            PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, /* flags= */ 0);
                }
            }
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
    }

    @Override // Binder call
    @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
    public void wakeUp() {
        super.wakeUp_enforcePermission();
        final long now = SystemClock.uptimeMillis();
        final long ident = Binder.clearCallingIdentity();
        try {
            synchronized (mVirtualDeviceLock) {
                for (int i = 0; i < mVirtualDisplays.size(); i++) {
                    VirtualDisplayWrapper wrapper = mVirtualDisplays.valueAt(i);
                    if (!wrapper.isTrusted() || wrapper.isMirror()) {
                        continue;
                    }
                    int displayId = mVirtualDisplays.keyAt(i);
                    mPowerManager.wakeUp(now, PowerManager.WAKE_REASON_POWER_BUTTON,
                            "android.server.companion.virtual:DEVICE_ON", displayId);
                }
            }
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
    }

    @Override // Binder call
    public void launchPendingIntent(int displayId, PendingIntent pendingIntent,
            ResultReceiver resultReceiver) {
@@ -1423,6 +1472,9 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
        boolean isMirrorDisplay =
                mDisplayManagerInternal.getDisplayIdToMirror(displayId) != Display.INVALID_DISPLAY;
        gwpc.setDisplayId(displayId, isMirrorDisplay);
        boolean isTrustedDisplay =
                (mDisplayManagerInternal.getDisplayInfo(displayId).flags & Display.FLAG_TRUSTED)
                        == Display.FLAG_TRUSTED;

        boolean showPointer;
        synchronized (mVirtualDeviceLock) {
@@ -1433,7 +1485,8 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
            }

            PowerManager.WakeLock wakeLock = createAndAcquireWakeLockForDisplay(displayId);
            mVirtualDisplays.put(displayId, new VirtualDisplayWrapper(callback, gwpc, wakeLock));
            mVirtualDisplays.put(displayId, new VirtualDisplayWrapper(callback, gwpc, wakeLock,
                    isTrustedDisplay, isMirrorDisplay));
            showPointer = mDefaultShowPointerIcon;
        }

@@ -1444,8 +1497,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
            mInputController.setDisplayEligibilityForPointerCapture(/* isEligible= */ false,
                    displayId);
            // WM throws a SecurityException if the display is untrusted.
            if ((mDisplayManagerInternal.getDisplayInfo(displayId).flags & Display.FLAG_TRUSTED)
                    == Display.FLAG_TRUSTED) {
            if (isTrustedDisplay) {
                mInputController.setDisplayImePolicy(displayId,
                        WindowManager.DISPLAY_IME_POLICY_LOCAL);
            }
@@ -1732,13 +1784,17 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
        private final IVirtualDisplayCallback mToken;
        private final GenericWindowPolicyController mWindowPolicyController;
        private final PowerManager.WakeLock mWakeLock;
        private final boolean mIsTrusted;
        private final boolean mIsMirror;

        VirtualDisplayWrapper(@NonNull IVirtualDisplayCallback token,
                @NonNull GenericWindowPolicyController windowPolicyController,
                @NonNull PowerManager.WakeLock wakeLock) {
                @NonNull PowerManager.WakeLock wakeLock, boolean isTrusted, boolean isMirror) {
            mToken = Objects.requireNonNull(token);
            mWindowPolicyController = Objects.requireNonNull(windowPolicyController);
            mWakeLock = Objects.requireNonNull(wakeLock);
            mIsTrusted = isTrusted;
            mIsMirror = isMirror;
        }

        GenericWindowPolicyController getWindowPolicyController() {
@@ -1749,6 +1805,14 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
            return mWakeLock;
        }

        boolean isTrusted() {
            return mIsTrusted;
        }

        boolean isMirror() {
            return mIsMirror;
        }

        IVirtualDisplayCallback getToken() {
            return mToken;
        }