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

Commit 9c20afa9 authored by Yogisha Dixit's avatar Yogisha Dixit
Browse files

Add APIs in PowerManager for suppressing ambient display.

Added 4 methods:
boolean isAmbientDisplayAvailable()
void suppressAmbientDisplay(String token, boolean suppress)
boolean isAmbientDisplaySuppressedForToken(String token)
boolean isAmbientDisplaySuppressed()

This CL simply adds the API to toggle SUPPRESS_DOZE. The code for
actually turning off doze when the secure setting is updated will be
implemented in a follow-up CL.

Test: manual, atest FrameworksServicesTests:PowerManagerServiceTest
Bug: 147584235, 147587449
Change-Id: I54f46f75fb84aae2ae806690e73eeb427ad8e8e1
parent ce7f6e89
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -7811,10 +7811,14 @@ package android.os {
    method @RequiresPermission(allOf={android.Manifest.permission.READ_DREAM_STATE, android.Manifest.permission.WRITE_DREAM_STATE}) public void dream(long);
    method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public boolean forceSuspend();
    method @RequiresPermission(android.Manifest.permission.POWER_SAVER) public int getPowerSaveModeTrigger();
    method @RequiresPermission(android.Manifest.permission.READ_DREAM_STATE) public boolean isAmbientDisplayAvailable();
    method @RequiresPermission(android.Manifest.permission.READ_DREAM_STATE) public boolean isAmbientDisplaySuppressed();
    method @RequiresPermission(android.Manifest.permission.READ_DREAM_STATE) public boolean isAmbientDisplaySuppressedForToken(@NonNull String);
    method @RequiresPermission(anyOf={android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.POWER_SAVER}) public boolean setAdaptivePowerSaveEnabled(boolean);
    method @RequiresPermission(anyOf={android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.POWER_SAVER}) public boolean setAdaptivePowerSavePolicy(@NonNull android.os.BatterySaverPolicyConfig);
    method @RequiresPermission(android.Manifest.permission.POWER_SAVER) public boolean setDynamicPowerSaveHint(boolean, int);
    method @RequiresPermission(anyOf={android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.POWER_SAVER}) public boolean setPowerSaveModeEnabled(boolean);
    method @RequiresPermission(android.Manifest.permission.WRITE_DREAM_STATE) public void suppressAmbientDisplay(@NonNull String, boolean);
    method @RequiresPermission(anyOf={android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.USER_ACTIVITY}) public void userActivity(long, int, int);
    field public static final int POWER_SAVE_MODE_TRIGGER_DYNAMIC = 1; // 0x1
    field public static final int POWER_SAVE_MODE_TRIGGER_PERCENTAGE = 0; // 0x0
+8 −0
Original line number Diff line number Diff line
@@ -80,6 +80,14 @@ interface IPowerManager

    // controls whether PowerManager should doze after the screen turns off or not
    void setDozeAfterScreenOff(boolean on);
    // returns whether ambient display is available on the device.
    boolean isAmbientDisplayAvailable();
    // suppresses the current ambient display configuration and disables ambient display.
    void suppressAmbientDisplay(String token, boolean suppress);
    // returns whether ambient display is suppressed by the calling app with the given token.
    boolean isAmbientDisplaySuppressedForToken(String token);
    // returns whether ambient display is suppressed by any app with any token.
    boolean isAmbientDisplaySuppressed();

    // Forces the system to suspend even if there are held wakelocks.
    boolean forceSuspend();
+71 −0
Original line number Diff line number Diff line
@@ -1869,6 +1869,77 @@ public final class PowerManager {
        }
    }

    /**
     * Returns true if ambient display is available on the device.
     * @hide
     */
    @SystemApi
    @RequiresPermission(android.Manifest.permission.READ_DREAM_STATE)
    public boolean isAmbientDisplayAvailable() {
        try {
            return mService.isAmbientDisplayAvailable();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * If true, suppresses the current ambient display configuration and disables ambient display.
     *
     * <p>This method has no effect if {@link #isAmbientDisplayAvailable()} is false.
     *
     * @param token A persistable identifier for the ambient display suppression that is unique
     *              within the calling application.
     * @param suppress If set to {@code true}, ambient display will be suppressed. If set to
     *                 {@code false}, ambient display will no longer be suppressed for the given
     *                 token.
     * @hide
     */
    @SystemApi
    @RequiresPermission(android.Manifest.permission.WRITE_DREAM_STATE)
    public void suppressAmbientDisplay(@NonNull String token, boolean suppress) {
        try {
            mService.suppressAmbientDisplay(token, suppress);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Returns true if ambient display is suppressed by the calling app with the given
     * {@code token}.
     *
     * <p>This method will return false if {@link #isAmbientDisplayAvailable()} is false.
     *
     * @param token The identifier of the ambient display suppression.
     * @hide
     */
    @SystemApi
    @RequiresPermission(android.Manifest.permission.READ_DREAM_STATE)
    public boolean isAmbientDisplaySuppressedForToken(@NonNull String token) {
        try {
            return mService.isAmbientDisplaySuppressedForToken(token);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Returns true if ambient display is suppressed by <em>any</em> app with <em>any</em> token.
     *
     * <p>This method will return false if {@link #isAmbientDisplayAvailable()} is false.
     * @hide
     */
    @SystemApi
    @RequiresPermission(android.Manifest.permission.READ_DREAM_STATE)
    public boolean isAmbientDisplaySuppressed() {
        try {
            return mService.isAmbientDisplaySuppressed();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Returns the reason the phone was last shutdown. Calling app must have the
     * {@link android.Manifest.permission#DEVICE_POWER} permission to request this information.
+80 −0
Original line number Diff line number Diff line
@@ -72,6 +72,7 @@ import android.provider.Settings.SettingNotFoundException;
import android.service.dreams.DreamManagerInternal;
import android.service.vr.IVrManager;
import android.service.vr.IVrStateCallbacks;
import android.util.ArraySet;
import android.util.KeyValueListParser;
import android.util.PrintWriterPrinter;
import android.util.Slog;
@@ -109,6 +110,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * The power manager service is responsible for coordinating power management
@@ -565,6 +567,9 @@ public final class PowerManagerService extends SystemService
    // but the DreamService has not yet been told to start (it's an async process).
    private boolean mDozeStartInProgress;

    // Set of all tokens suppressing ambient display.
    private final Set<String> mAmbientDisplaySuppressionTokens = new ArraySet<>();

    private final class ForegroundProfileObserver extends SynchronousUserSwitchObserver {
        @Override
        public void onUserSwitching(@UserIdInt int newUserId) throws RemoteException {
@@ -3357,6 +3362,26 @@ public final class PowerManagerService extends SystemService
        }
    }

    private void suppressAmbientDisplayInternal(String token, boolean suppress) {
        if (DEBUG_SPEW) {
            Slog.d(TAG, "Suppress ambient display for token " + token + ": " + suppress);
        }

        if (suppress) {
            mAmbientDisplaySuppressionTokens.add(token);
        } else {
            mAmbientDisplaySuppressionTokens.remove(token);
        }

        Settings.Secure.putInt(mContext.getContentResolver(),
                Settings.Secure.SUPPRESS_DOZE,
                Math.min(mAmbientDisplaySuppressionTokens.size(), 1));
    }

    private String createAmbientDisplayToken(String token, int callingUid) {
        return callingUid + "_" + token;
    }

    private void boostScreenBrightnessInternal(long eventTime, int uid) {
        synchronized (mLock) {
            if (!mSystemReady || mWakefulness == WAKEFULNESS_ASLEEP
@@ -5006,6 +5031,61 @@ public final class PowerManagerService extends SystemService
            }
        }

        @Override // Binder call
        public boolean isAmbientDisplayAvailable() {
            mContext.enforceCallingOrSelfPermission(
                    android.Manifest.permission.READ_DREAM_STATE, null);

            final long ident = Binder.clearCallingIdentity();
            try {
                return mAmbientDisplayConfiguration.ambientDisplayAvailable();
            } finally {
                Binder.restoreCallingIdentity(ident);
            }
        }

        @Override // Binder call
        public void suppressAmbientDisplay(@NonNull String token, boolean suppress) {
            mContext.enforceCallingOrSelfPermission(
                    android.Manifest.permission.WRITE_DREAM_STATE, null);

            final int uid = Binder.getCallingUid();
            final long ident = Binder.clearCallingIdentity();
            try {
                suppressAmbientDisplayInternal(createAmbientDisplayToken(token, uid), suppress);
            } finally {
                Binder.restoreCallingIdentity(ident);
            }
        }

        @Override // Binder call
        public boolean isAmbientDisplaySuppressedForToken(@NonNull String token) {
            mContext.enforceCallingOrSelfPermission(
                    android.Manifest.permission.READ_DREAM_STATE, null);

            final int uid = Binder.getCallingUid();
            final long ident = Binder.clearCallingIdentity();
            try {
                return mAmbientDisplaySuppressionTokens.contains(
                        createAmbientDisplayToken(token, uid));
            } finally {
                Binder.restoreCallingIdentity(ident);
            }
        }

        @Override // Binder call
        public boolean isAmbientDisplaySuppressed() {
            mContext.enforceCallingOrSelfPermission(
                    android.Manifest.permission.READ_DREAM_STATE, null);

            final long ident = Binder.clearCallingIdentity();
            try {
                return mAmbientDisplaySuppressionTokens.size() > 0;
            } finally {
                Binder.restoreCallingIdentity(ident);
            }
        }

        @Override // Binder call
        public void boostScreenBrightness(long eventTime) {
            if (eventTime > SystemClock.uptimeMillis()) {
+2 −0
Original line number Diff line number Diff line
@@ -74,6 +74,8 @@
    <uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
    <uses-permission android:name="android.permission.DUMP" />
    <uses-permission android:name="android.permission.READ_DREAM_STATE"/>
    <uses-permission android:name="android.permission.WRITE_DREAM_STATE"/>

    <!-- Uses API introduced in O (26) -->
    <uses-sdk android:minSdkVersion="1"
Loading