Loading core/java/android/app/ActivityManager.java +166 −7 Original line number Diff line number Diff line Loading @@ -1349,12 +1349,26 @@ public class ActivityManager { public static final int RESTRICTION_LEVEL_BACKGROUND_RESTRICTED = 50; /** * The most restricted level where the apps are considered "in-hibernation", * its package visibility to the rest of the system is limited. * The restricted level where the apps are in a force-stopped state. * * @hide */ public static final int RESTRICTION_LEVEL_HIBERNATION = 60; public static final int RESTRICTION_LEVEL_FORCE_STOPPED = 60; /** * The heavily background restricted level, where apps cannot start without an explicit * launch by the user. * * @hide */ public static final int RESTRICTION_LEVEL_USER_LAUNCH_ONLY = 70; /** * A reserved restriction level that is not well-defined. * * @hide */ public static final int RESTRICTION_LEVEL_CUSTOM = 90; /** * Not a valid restriction level, it defines the maximum numerical value of restriction level. Loading @@ -1371,12 +1385,116 @@ public class ActivityManager { RESTRICTION_LEVEL_ADAPTIVE_BUCKET, RESTRICTION_LEVEL_RESTRICTED_BUCKET, RESTRICTION_LEVEL_BACKGROUND_RESTRICTED, RESTRICTION_LEVEL_HIBERNATION, RESTRICTION_LEVEL_FORCE_STOPPED, RESTRICTION_LEVEL_USER_LAUNCH_ONLY, RESTRICTION_LEVEL_CUSTOM, RESTRICTION_LEVEL_MAX, }) @Retention(RetentionPolicy.SOURCE) public @interface RestrictionLevel{} /** * Maximum string length for sub reason for restriction. * * @hide */ public static final int RESTRICTION_SUBREASON_MAX_LENGTH = 16; /** * Restriction reason unknown - do not use directly. * * For use with noteAppRestrictionEnabled() * @hide */ public static final int RESTRICTION_REASON_UNKNOWN = 0; /** * Restriction reason to be used when this is normal behavior for the state. * * For use with noteAppRestrictionEnabled() * @hide */ public static final int RESTRICTION_REASON_DEFAULT = 1; /** * Restriction reason is some kind of timeout that moves the app to a more restricted state. * The threshold should specify how long the app was dormant, in milliseconds. * * For use with noteAppRestrictionEnabled() * @hide */ public static final int RESTRICTION_REASON_DORMANT = 2; /** * Restriction reason to be used when removing a restriction due to direct or indirect usage * of the app, especially to undo any automatic restrictions. * * For use with noteAppRestrictionEnabled() * @hide */ public static final int RESTRICTION_REASON_USAGE = 3; /** * Restriction reason to be used when the user chooses to manually restrict the app, through * UI or command line interface. * * For use with noteAppRestrictionEnabled() * @hide */ public static final int RESTRICTION_REASON_USER = 4; /** * Restriction reason to be used when the user chooses to manually restrict the app on being * prompted by the OS or some anomaly detection algorithm. For example, if the app is causing * high battery drain or affecting system performance and the OS recommends that the user * restrict the app. * * For use with noteAppRestrictionEnabled() * @hide */ public static final int RESTRICTION_REASON_USER_NUDGED = 5; /** * Restriction reason to be used when the OS automatically detects that the app is causing * system health issues such as performance degradation, battery drain, high memory usage, etc. * * For use with noteAppRestrictionEnabled() * @hide */ public static final int RESTRICTION_REASON_SYSTEM_HEALTH = 6; /** * Restriction reason to be used when there is a server-side decision made to restrict an app * that is showing widespread problems on user devices, or violating policy in some way. * * For use with noteAppRestrictionEnabled() * @hide */ public static final int RESTRICTION_REASON_REMOTE_TRIGGER = 7; /** * Restriction reason to be used when some other problem requires restricting the app. * * For use with noteAppRestrictionEnabled() * @hide */ public static final int RESTRICTION_REASON_OTHER = 8; /** @hide */ @IntDef(prefix = { "RESTRICTION_REASON_" }, value = { RESTRICTION_REASON_UNKNOWN, RESTRICTION_REASON_DEFAULT, RESTRICTION_REASON_DORMANT, RESTRICTION_REASON_USAGE, RESTRICTION_REASON_USER, RESTRICTION_REASON_USER_NUDGED, RESTRICTION_REASON_SYSTEM_HEALTH, RESTRICTION_REASON_REMOTE_TRIGGER, RESTRICTION_REASON_OTHER }) @Retention(RetentionPolicy.SOURCE) public @interface RestrictionReason{} /** @hide */ @android.ravenwood.annotation.RavenwoodKeep public static String restrictionLevelToName(@RestrictionLevel int level) { Loading @@ -1393,12 +1511,16 @@ public class ActivityManager { return "restricted_bucket"; case RESTRICTION_LEVEL_BACKGROUND_RESTRICTED: return "background_restricted"; case RESTRICTION_LEVEL_HIBERNATION: return "hibernation"; case RESTRICTION_LEVEL_FORCE_STOPPED: return "stopped"; case RESTRICTION_LEVEL_USER_LAUNCH_ONLY: return "user_only"; case RESTRICTION_LEVEL_CUSTOM: return "custom"; case RESTRICTION_LEVEL_MAX: return "max"; default: return ""; return String.valueOf(level); } } Loading Loading @@ -6126,6 +6248,43 @@ public class ActivityManager { return PowerExemptionManager.REASON_DENIED; } /** * Requests the system to log the reason for restricting/unrestricting an app. This API * should be called before applying any change to the restriction level. * <p> * The {@code enabled} value determines whether the state is being applied or removed. * Not all restrictions are actual restrictions. For example, * {@link #RESTRICTION_LEVEL_ADAPTIVE} is a normal state, where there is default lifecycle * management applied to the app. Also, {@link #RESTRICTION_LEVEL_EXEMPTED} is used when the * app is being put in a power-save allowlist. * * @param packageName the package name of the app * @param uid the uid of the app * @param restrictionLevel the restriction level specified in {@code RestrictionLevel} * @param enabled whether the state is being applied or removed * @param reason the reason for the restriction state change, from {@code RestrictionReason} * @param subReason a string sub reason limited to 16 characters that specifies additional * information about the reason for restriction. * @param threshold for reasons that are due to exceeding some threshold, the threshold value * must be specified. The unit of the threshold depends on the reason and/or * subReason. For time, use milliseconds. For memory, use KB. For count, use * the actual count or normalized as per-hour. For power, use milliwatts. Etc. * * @hide */ @RequiresPermission(Manifest.permission.DEVICE_POWER) public void noteAppRestrictionEnabled(@NonNull String packageName, int uid, @RestrictionLevel int restrictionLevel, boolean enabled, @RestrictionReason int reason, @Nullable String subReason, long threshold) { try { getService().noteAppRestrictionEnabled(packageName, uid, restrictionLevel, enabled, reason, subReason, threshold); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Notifies {@link #getRunningAppProcesses app processes} that the system properties * have changed. Loading core/java/android/app/IActivityManager.aidl +8 −0 Original line number Diff line number Diff line Loading @@ -1009,4 +1009,12 @@ interface IActivityManager { * @param originatingUid The UID of the instrumented app that initialized the override */ void clearAllOverridePermissionStates(int originatingUid); /** * Request the system to log the reason for restricting / unrestricting an app. * @see ActivityManager#noteAppRestrictionEnabled */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.DEVICE_POWER)") void noteAppRestrictionEnabled(in String packageName, int uid, int restrictionType, boolean enabled, int reason, in String subReason, long threshold); } core/tests/coretests/src/android/app/ActivityManagerTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -78,6 +78,6 @@ public class ActivityManagerTest { public void testRestrictionLevel() throws Exception { // For the moment mostly want to confirm we don't crash assertNotNull(ActivityManager.restrictionLevelToName( ActivityManager.RESTRICTION_LEVEL_HIBERNATION)); ActivityManager.RESTRICTION_LEVEL_FORCE_STOPPED)); } } packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerAllowlistBackend.java +55 −2 Original line number Diff line number Diff line Loading @@ -18,12 +18,15 @@ package com.android.settingslib.fuelgauge; import static android.provider.DeviceConfig.NAMESPACE_ACTIVITY_MANAGER; import android.app.ActivityManager; import android.app.AppOpsManager; import android.app.admin.DevicePolicyManager; import android.content.ComponentName; import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.os.IDeviceIdleController; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; Loading Loading @@ -172,27 +175,77 @@ public class PowerAllowlistBackend { /** * Add app into power save allow list. * @param pkg packageName * @param pkg packageName of the app */ // TODO: Fix all callers to pass in UID public void addApp(String pkg) { addApp(pkg, Process.INVALID_UID); } /** * Add app into power save allow list. * @param pkg packageName of the app * @param uid uid of the app */ public void addApp(String pkg, int uid) { try { if (android.app.Flags.appRestrictionsApi()) { if (uid == Process.INVALID_UID) { uid = mAppContext.getSystemService(PackageManager.class).getPackageUid(pkg, 0); } final boolean wasInList = isAllowlisted(pkg, uid); if (!wasInList) { mAppContext.getSystemService(ActivityManager.class).noteAppRestrictionEnabled( pkg, uid, ActivityManager.RESTRICTION_LEVEL_EXEMPTED, true, ActivityManager.RESTRICTION_REASON_USER, "settings", 0); } } mDeviceIdleService.addPowerSaveWhitelistApp(pkg); mAllowlistedApps.add(pkg); } catch (RemoteException e) { Log.w(TAG, "Unable to reach IDeviceIdleController", e); } catch (NameNotFoundException e) { Log.w(TAG, "Unable to find package", e); } } /** * Remove package from power save allow list. * @param pkg * @param pkg packageName of the app */ public void removeApp(String pkg) { removeApp(pkg, Process.INVALID_UID); } /** * Remove package from power save allow list. * @param pkg packageName of the app * @param uid uid of the app */ public void removeApp(String pkg, int uid) { try { if (android.app.Flags.appRestrictionsApi()) { if (uid == Process.INVALID_UID) { uid = mAppContext.getSystemService(PackageManager.class).getPackageUid(pkg, 0); } final boolean wasInList = isAllowlisted(pkg, uid); if (wasInList) { mAppContext.getSystemService(ActivityManager.class).noteAppRestrictionEnabled( pkg, uid, ActivityManager.RESTRICTION_LEVEL_EXEMPTED, false, ActivityManager.RESTRICTION_REASON_USER, "settings", 0); } } mDeviceIdleService.removePowerSaveWhitelistApp(pkg); mAllowlistedApps.remove(pkg); } catch (RemoteException e) { Log.w(TAG, "Unable to reach IDeviceIdleController", e); } catch (NameNotFoundException e) { Log.w(TAG, "Unable to find package", e); } } Loading packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerAllowlistBackendTest.java +3 −3 Original line number Diff line number Diff line Loading @@ -96,7 +96,7 @@ public class PowerAllowlistBackendTest { assertThat(mPowerAllowlistBackend.isAllowlisted(new String[] {PACKAGE_ONE}, UID)).isTrue(); assertThat(mPowerAllowlistBackend.isAllowlisted(new String[] {PACKAGE_TWO}, UID)).isFalse(); mPowerAllowlistBackend.addApp(PACKAGE_TWO); mPowerAllowlistBackend.addApp(PACKAGE_TWO, UID); verify(mDeviceIdleService, atLeastOnce()).addPowerSaveWhitelistApp(PACKAGE_TWO); assertThat(mPowerAllowlistBackend.isAllowlisted(PACKAGE_ONE, UID)).isTrue(); Loading @@ -104,7 +104,7 @@ public class PowerAllowlistBackendTest { assertThat(mPowerAllowlistBackend.isAllowlisted( new String[] {PACKAGE_ONE, PACKAGE_TWO}, UID)).isTrue(); mPowerAllowlistBackend.removeApp(PACKAGE_TWO); mPowerAllowlistBackend.removeApp(PACKAGE_TWO, UID); verify(mDeviceIdleService, atLeastOnce()).removePowerSaveWhitelistApp(PACKAGE_TWO); assertThat(mPowerAllowlistBackend.isAllowlisted(PACKAGE_ONE, UID)).isTrue(); Loading @@ -112,7 +112,7 @@ public class PowerAllowlistBackendTest { assertThat(mPowerAllowlistBackend.isAllowlisted(new String[] {PACKAGE_ONE}, UID)).isTrue(); assertThat(mPowerAllowlistBackend.isAllowlisted(new String[] {PACKAGE_TWO}, UID)).isFalse(); mPowerAllowlistBackend.removeApp(PACKAGE_ONE); mPowerAllowlistBackend.removeApp(PACKAGE_ONE, UID); verify(mDeviceIdleService, atLeastOnce()).removePowerSaveWhitelistApp(PACKAGE_ONE); assertThat(mPowerAllowlistBackend.isAllowlisted(PACKAGE_ONE, UID)).isFalse(); Loading Loading
core/java/android/app/ActivityManager.java +166 −7 Original line number Diff line number Diff line Loading @@ -1349,12 +1349,26 @@ public class ActivityManager { public static final int RESTRICTION_LEVEL_BACKGROUND_RESTRICTED = 50; /** * The most restricted level where the apps are considered "in-hibernation", * its package visibility to the rest of the system is limited. * The restricted level where the apps are in a force-stopped state. * * @hide */ public static final int RESTRICTION_LEVEL_HIBERNATION = 60; public static final int RESTRICTION_LEVEL_FORCE_STOPPED = 60; /** * The heavily background restricted level, where apps cannot start without an explicit * launch by the user. * * @hide */ public static final int RESTRICTION_LEVEL_USER_LAUNCH_ONLY = 70; /** * A reserved restriction level that is not well-defined. * * @hide */ public static final int RESTRICTION_LEVEL_CUSTOM = 90; /** * Not a valid restriction level, it defines the maximum numerical value of restriction level. Loading @@ -1371,12 +1385,116 @@ public class ActivityManager { RESTRICTION_LEVEL_ADAPTIVE_BUCKET, RESTRICTION_LEVEL_RESTRICTED_BUCKET, RESTRICTION_LEVEL_BACKGROUND_RESTRICTED, RESTRICTION_LEVEL_HIBERNATION, RESTRICTION_LEVEL_FORCE_STOPPED, RESTRICTION_LEVEL_USER_LAUNCH_ONLY, RESTRICTION_LEVEL_CUSTOM, RESTRICTION_LEVEL_MAX, }) @Retention(RetentionPolicy.SOURCE) public @interface RestrictionLevel{} /** * Maximum string length for sub reason for restriction. * * @hide */ public static final int RESTRICTION_SUBREASON_MAX_LENGTH = 16; /** * Restriction reason unknown - do not use directly. * * For use with noteAppRestrictionEnabled() * @hide */ public static final int RESTRICTION_REASON_UNKNOWN = 0; /** * Restriction reason to be used when this is normal behavior for the state. * * For use with noteAppRestrictionEnabled() * @hide */ public static final int RESTRICTION_REASON_DEFAULT = 1; /** * Restriction reason is some kind of timeout that moves the app to a more restricted state. * The threshold should specify how long the app was dormant, in milliseconds. * * For use with noteAppRestrictionEnabled() * @hide */ public static final int RESTRICTION_REASON_DORMANT = 2; /** * Restriction reason to be used when removing a restriction due to direct or indirect usage * of the app, especially to undo any automatic restrictions. * * For use with noteAppRestrictionEnabled() * @hide */ public static final int RESTRICTION_REASON_USAGE = 3; /** * Restriction reason to be used when the user chooses to manually restrict the app, through * UI or command line interface. * * For use with noteAppRestrictionEnabled() * @hide */ public static final int RESTRICTION_REASON_USER = 4; /** * Restriction reason to be used when the user chooses to manually restrict the app on being * prompted by the OS or some anomaly detection algorithm. For example, if the app is causing * high battery drain or affecting system performance and the OS recommends that the user * restrict the app. * * For use with noteAppRestrictionEnabled() * @hide */ public static final int RESTRICTION_REASON_USER_NUDGED = 5; /** * Restriction reason to be used when the OS automatically detects that the app is causing * system health issues such as performance degradation, battery drain, high memory usage, etc. * * For use with noteAppRestrictionEnabled() * @hide */ public static final int RESTRICTION_REASON_SYSTEM_HEALTH = 6; /** * Restriction reason to be used when there is a server-side decision made to restrict an app * that is showing widespread problems on user devices, or violating policy in some way. * * For use with noteAppRestrictionEnabled() * @hide */ public static final int RESTRICTION_REASON_REMOTE_TRIGGER = 7; /** * Restriction reason to be used when some other problem requires restricting the app. * * For use with noteAppRestrictionEnabled() * @hide */ public static final int RESTRICTION_REASON_OTHER = 8; /** @hide */ @IntDef(prefix = { "RESTRICTION_REASON_" }, value = { RESTRICTION_REASON_UNKNOWN, RESTRICTION_REASON_DEFAULT, RESTRICTION_REASON_DORMANT, RESTRICTION_REASON_USAGE, RESTRICTION_REASON_USER, RESTRICTION_REASON_USER_NUDGED, RESTRICTION_REASON_SYSTEM_HEALTH, RESTRICTION_REASON_REMOTE_TRIGGER, RESTRICTION_REASON_OTHER }) @Retention(RetentionPolicy.SOURCE) public @interface RestrictionReason{} /** @hide */ @android.ravenwood.annotation.RavenwoodKeep public static String restrictionLevelToName(@RestrictionLevel int level) { Loading @@ -1393,12 +1511,16 @@ public class ActivityManager { return "restricted_bucket"; case RESTRICTION_LEVEL_BACKGROUND_RESTRICTED: return "background_restricted"; case RESTRICTION_LEVEL_HIBERNATION: return "hibernation"; case RESTRICTION_LEVEL_FORCE_STOPPED: return "stopped"; case RESTRICTION_LEVEL_USER_LAUNCH_ONLY: return "user_only"; case RESTRICTION_LEVEL_CUSTOM: return "custom"; case RESTRICTION_LEVEL_MAX: return "max"; default: return ""; return String.valueOf(level); } } Loading Loading @@ -6126,6 +6248,43 @@ public class ActivityManager { return PowerExemptionManager.REASON_DENIED; } /** * Requests the system to log the reason for restricting/unrestricting an app. This API * should be called before applying any change to the restriction level. * <p> * The {@code enabled} value determines whether the state is being applied or removed. * Not all restrictions are actual restrictions. For example, * {@link #RESTRICTION_LEVEL_ADAPTIVE} is a normal state, where there is default lifecycle * management applied to the app. Also, {@link #RESTRICTION_LEVEL_EXEMPTED} is used when the * app is being put in a power-save allowlist. * * @param packageName the package name of the app * @param uid the uid of the app * @param restrictionLevel the restriction level specified in {@code RestrictionLevel} * @param enabled whether the state is being applied or removed * @param reason the reason for the restriction state change, from {@code RestrictionReason} * @param subReason a string sub reason limited to 16 characters that specifies additional * information about the reason for restriction. * @param threshold for reasons that are due to exceeding some threshold, the threshold value * must be specified. The unit of the threshold depends on the reason and/or * subReason. For time, use milliseconds. For memory, use KB. For count, use * the actual count or normalized as per-hour. For power, use milliwatts. Etc. * * @hide */ @RequiresPermission(Manifest.permission.DEVICE_POWER) public void noteAppRestrictionEnabled(@NonNull String packageName, int uid, @RestrictionLevel int restrictionLevel, boolean enabled, @RestrictionReason int reason, @Nullable String subReason, long threshold) { try { getService().noteAppRestrictionEnabled(packageName, uid, restrictionLevel, enabled, reason, subReason, threshold); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Notifies {@link #getRunningAppProcesses app processes} that the system properties * have changed. Loading
core/java/android/app/IActivityManager.aidl +8 −0 Original line number Diff line number Diff line Loading @@ -1009,4 +1009,12 @@ interface IActivityManager { * @param originatingUid The UID of the instrumented app that initialized the override */ void clearAllOverridePermissionStates(int originatingUid); /** * Request the system to log the reason for restricting / unrestricting an app. * @see ActivityManager#noteAppRestrictionEnabled */ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.DEVICE_POWER)") void noteAppRestrictionEnabled(in String packageName, int uid, int restrictionType, boolean enabled, int reason, in String subReason, long threshold); }
core/tests/coretests/src/android/app/ActivityManagerTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -78,6 +78,6 @@ public class ActivityManagerTest { public void testRestrictionLevel() throws Exception { // For the moment mostly want to confirm we don't crash assertNotNull(ActivityManager.restrictionLevelToName( ActivityManager.RESTRICTION_LEVEL_HIBERNATION)); ActivityManager.RESTRICTION_LEVEL_FORCE_STOPPED)); } }
packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerAllowlistBackend.java +55 −2 Original line number Diff line number Diff line Loading @@ -18,12 +18,15 @@ package com.android.settingslib.fuelgauge; import static android.provider.DeviceConfig.NAMESPACE_ACTIVITY_MANAGER; import android.app.ActivityManager; import android.app.AppOpsManager; import android.app.admin.DevicePolicyManager; import android.content.ComponentName; import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.os.IDeviceIdleController; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; Loading Loading @@ -172,27 +175,77 @@ public class PowerAllowlistBackend { /** * Add app into power save allow list. * @param pkg packageName * @param pkg packageName of the app */ // TODO: Fix all callers to pass in UID public void addApp(String pkg) { addApp(pkg, Process.INVALID_UID); } /** * Add app into power save allow list. * @param pkg packageName of the app * @param uid uid of the app */ public void addApp(String pkg, int uid) { try { if (android.app.Flags.appRestrictionsApi()) { if (uid == Process.INVALID_UID) { uid = mAppContext.getSystemService(PackageManager.class).getPackageUid(pkg, 0); } final boolean wasInList = isAllowlisted(pkg, uid); if (!wasInList) { mAppContext.getSystemService(ActivityManager.class).noteAppRestrictionEnabled( pkg, uid, ActivityManager.RESTRICTION_LEVEL_EXEMPTED, true, ActivityManager.RESTRICTION_REASON_USER, "settings", 0); } } mDeviceIdleService.addPowerSaveWhitelistApp(pkg); mAllowlistedApps.add(pkg); } catch (RemoteException e) { Log.w(TAG, "Unable to reach IDeviceIdleController", e); } catch (NameNotFoundException e) { Log.w(TAG, "Unable to find package", e); } } /** * Remove package from power save allow list. * @param pkg * @param pkg packageName of the app */ public void removeApp(String pkg) { removeApp(pkg, Process.INVALID_UID); } /** * Remove package from power save allow list. * @param pkg packageName of the app * @param uid uid of the app */ public void removeApp(String pkg, int uid) { try { if (android.app.Flags.appRestrictionsApi()) { if (uid == Process.INVALID_UID) { uid = mAppContext.getSystemService(PackageManager.class).getPackageUid(pkg, 0); } final boolean wasInList = isAllowlisted(pkg, uid); if (wasInList) { mAppContext.getSystemService(ActivityManager.class).noteAppRestrictionEnabled( pkg, uid, ActivityManager.RESTRICTION_LEVEL_EXEMPTED, false, ActivityManager.RESTRICTION_REASON_USER, "settings", 0); } } mDeviceIdleService.removePowerSaveWhitelistApp(pkg); mAllowlistedApps.remove(pkg); } catch (RemoteException e) { Log.w(TAG, "Unable to reach IDeviceIdleController", e); } catch (NameNotFoundException e) { Log.w(TAG, "Unable to find package", e); } } Loading
packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerAllowlistBackendTest.java +3 −3 Original line number Diff line number Diff line Loading @@ -96,7 +96,7 @@ public class PowerAllowlistBackendTest { assertThat(mPowerAllowlistBackend.isAllowlisted(new String[] {PACKAGE_ONE}, UID)).isTrue(); assertThat(mPowerAllowlistBackend.isAllowlisted(new String[] {PACKAGE_TWO}, UID)).isFalse(); mPowerAllowlistBackend.addApp(PACKAGE_TWO); mPowerAllowlistBackend.addApp(PACKAGE_TWO, UID); verify(mDeviceIdleService, atLeastOnce()).addPowerSaveWhitelistApp(PACKAGE_TWO); assertThat(mPowerAllowlistBackend.isAllowlisted(PACKAGE_ONE, UID)).isTrue(); Loading @@ -104,7 +104,7 @@ public class PowerAllowlistBackendTest { assertThat(mPowerAllowlistBackend.isAllowlisted( new String[] {PACKAGE_ONE, PACKAGE_TWO}, UID)).isTrue(); mPowerAllowlistBackend.removeApp(PACKAGE_TWO); mPowerAllowlistBackend.removeApp(PACKAGE_TWO, UID); verify(mDeviceIdleService, atLeastOnce()).removePowerSaveWhitelistApp(PACKAGE_TWO); assertThat(mPowerAllowlistBackend.isAllowlisted(PACKAGE_ONE, UID)).isTrue(); Loading @@ -112,7 +112,7 @@ public class PowerAllowlistBackendTest { assertThat(mPowerAllowlistBackend.isAllowlisted(new String[] {PACKAGE_ONE}, UID)).isTrue(); assertThat(mPowerAllowlistBackend.isAllowlisted(new String[] {PACKAGE_TWO}, UID)).isFalse(); mPowerAllowlistBackend.removeApp(PACKAGE_ONE); mPowerAllowlistBackend.removeApp(PACKAGE_ONE, UID); verify(mDeviceIdleService, atLeastOnce()).removePowerSaveWhitelistApp(PACKAGE_ONE); assertThat(mPowerAllowlistBackend.isAllowlisted(PACKAGE_ONE, UID)).isFalse(); Loading