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

Commit 57064556 authored by Robert Horvath's avatar Robert Horvath
Browse files

Introduce Low Power Standby API and wakelock restrictions

In Low Power Standby, additional restrictions are placed on apps that
are in a process state of FOREGROUND_SERVICE or less important
during standby (while the device is non-interactive):
- Wakelocks are disabled
- Network access is blocked
During doze maintenance windows the restrictions are lifted temporarily.

This change introduces the APIs for Low Power Standby, as well as
the wakelock restrictions.

This feature is targeting TVs. To prevent Low Power Standby from being
enabled on other devices, the feature is guarded by the config flag
config_lowPowerStandbySupported.

Bug: 190822356
Test: atest LowPowerStandbyControllerTest PowerManagerServiceTest
Ignore-AOSP-First: New permission only added internally for now.
Change-Id: Ia40f8a0fc4b366860af58ad76c988f93a5d41936
parent f7e59f08
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -31664,6 +31664,7 @@ package android.os {
    method public boolean isDeviceLightIdleMode();
    method public boolean isIgnoringBatteryOptimizations(String);
    method public boolean isInteractive();
    method public boolean isLowPowerStandbyEnabled();
    method public boolean isPowerSaveMode();
    method public boolean isRebootingUserspaceSupported();
    method @Deprecated public boolean isScreenOn();
@@ -31675,6 +31676,7 @@ package android.os {
    field public static final int ACQUIRE_CAUSES_WAKEUP = 268435456; // 0x10000000
    field public static final String ACTION_DEVICE_IDLE_MODE_CHANGED = "android.os.action.DEVICE_IDLE_MODE_CHANGED";
    field public static final String ACTION_DEVICE_LIGHT_IDLE_MODE_CHANGED = "android.os.action.LIGHT_DEVICE_IDLE_MODE_CHANGED";
    field public static final String ACTION_LOW_POWER_STANDBY_ENABLED_CHANGED = "android.os.action.LOW_POWER_STANDBY_ENABLED_CHANGED";
    field public static final String ACTION_POWER_SAVE_MODE_CHANGED = "android.os.action.POWER_SAVE_MODE_CHANGED";
    field @Deprecated public static final int FULL_WAKE_LOCK = 26; // 0x1a
    field public static final int LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF = 2; // 0x2
+3 −0
Original line number Diff line number Diff line
@@ -166,6 +166,7 @@ package android {
    field public static final String MANAGE_GAME_MODE = "android.permission.MANAGE_GAME_MODE";
    field public static final String MANAGE_HOTWORD_DETECTION = "android.permission.MANAGE_HOTWORD_DETECTION";
    field public static final String MANAGE_IPSEC_TUNNELS = "android.permission.MANAGE_IPSEC_TUNNELS";
    field public static final String MANAGE_LOW_POWER_STANDBY = "android.permission.MANAGE_LOW_POWER_STANDBY";
    field public static final String MANAGE_MUSIC_RECOGNITION = "android.permission.MANAGE_MUSIC_RECOGNITION";
    field public static final String MANAGE_NOTIFICATION_LISTENERS = "android.permission.MANAGE_NOTIFICATION_LISTENERS";
    field public static final String MANAGE_ONE_TIME_PERMISSION_SESSIONS = "android.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS";
@@ -9127,11 +9128,13 @@ package android.os {
    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.MANAGE_LOW_POWER_STANDBY, android.Manifest.permission.DEVICE_POWER}) public boolean isLowPowerStandbySupported();
    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(anyOf={android.Manifest.permission.BATTERY_PREDICTION, android.Manifest.permission.DEVICE_POWER}) public void setBatteryDischargePrediction(@NonNull java.time.Duration, boolean);
    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 setFullPowerSavePolicy(@NonNull android.os.BatterySaverPolicyConfig);
    method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_LOW_POWER_STANDBY, android.Manifest.permission.DEVICE_POWER}) public void setLowPowerStandbyEnabled(boolean);
    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);
+3 −0
Original line number Diff line number Diff line
@@ -65,6 +65,9 @@ interface IPowerManager
    boolean isBatteryDischargePredictionPersonalized();
    boolean isDeviceIdleMode();
    boolean isLightDeviceIdleMode();
    boolean isLowPowerStandbySupported();
    boolean isLowPowerStandbyEnabled();
    void setLowPowerStandbyEnabled(boolean enabled);

    @UnsupportedAppUsage
    void reboot(boolean confirm, String reason, boolean wait);
+68 −0
Original line number Diff line number Diff line
@@ -2145,6 +2145,64 @@ public final class PowerManager {
        return isDeviceLightIdleMode();
    }

    /**
     * Returns true if Low Power Standby is supported on this device.
     *
     * @hide
     */
    @SystemApi
    @RequiresPermission(anyOf = {
            android.Manifest.permission.MANAGE_LOW_POWER_STANDBY,
            android.Manifest.permission.DEVICE_POWER
    })
    public boolean isLowPowerStandbySupported() {
        try {
            return mService.isLowPowerStandbySupported();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Returns true if Low Power Standby is enabled.
     *
     * <p>When Low Power Standby is enabled, apps (including apps running foreground services) are
     * subject to additional restrictions while the device is non-interactive, outside of device
     * idle maintenance windows: Their network access is disabled, and any wakelocks they hold are
     * ignored.
     *
     * <p>When Low Power Standby is enabled or disabled, a Intent with action
     * {@link #ACTION_LOW_POWER_STANDBY_ENABLED_CHANGED} is broadcast to registered receivers.
     */
    public boolean isLowPowerStandbyEnabled() {
        try {
            return mService.isLowPowerStandbyEnabled();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Set whether Low Power Standby is enabled.
     * Does nothing if Low Power Standby is not supported.
     *
     * @see #isLowPowerStandbySupported()
     * @see #isLowPowerStandbyEnabled()
     * @hide
     */
    @SystemApi
    @RequiresPermission(anyOf = {
            android.Manifest.permission.MANAGE_LOW_POWER_STANDBY,
            android.Manifest.permission.DEVICE_POWER
    })
    public void setLowPowerStandbyEnabled(boolean enabled) {
        try {
            mService.setLowPowerStandbyEnabled(enabled);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Return whether the given application package name is on the device's power allowlist.
     * Apps can be placed on the allowlist through the settings UI invoked by
@@ -2630,6 +2688,16 @@ public final class PowerManager {
    public static final String ACTION_POWER_SAVE_TEMP_WHITELIST_CHANGED
            = "android.os.action.POWER_SAVE_TEMP_WHITELIST_CHANGED";

    /**
     * Intent that is broadcast when Low Power Standby is enabled or disabled.
     * This broadcast is only sent to registered receivers.
     *
     * @see #isLowPowerStandbyEnabled()
     */
    @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String ACTION_LOW_POWER_STANDBY_ENABLED_CHANGED =
            "android.os.action.LOW_POWER_STANDBY_ENABLED_CHANGED";

    /**
     * Constant for PreIdleTimeout normal mode (default mode, not short nor extend timeout) .
     * @hide
+8 −0
Original line number Diff line number Diff line
@@ -184,6 +184,14 @@ public abstract class PowerManagerInternal {

    public abstract void setDeviceIdleTempWhitelist(int[] appids);

    /**
     * Used by LowPowerStandbyController to notify the power manager that Low Power Standby's
     * active state has changed.
     *
     * @param active {@code true} to activate Low Power Standby, {@code false} to turn it off.
     */
    public abstract void setLowPowerStandbyActive(boolean active);

    public abstract void startUidChanges();

    public abstract void finishUidChanges();
Loading