From c2400c83d11a5858565b0ccde6d585fa40c1bbf4 Mon Sep 17 00:00:00 2001 From: Kweku Adams Date: Wed, 9 Oct 2019 15:56:04 -0700 Subject: [PATCH] Add API to whitelist multiple apps at once. This adds an API to be able to add multiple apps to the power save whitelist at the same time while only sending out the POWER_WHITELIST_CHAGNED broadcast once. Bug: 140141678 Test: atest com.android.server.DeviceIdleControllerTest Test: atest android.alarmmanager.cts.AppStandbyTests Change-Id: I66cfd5410b85368647faea704ada1bc1ac563510 --- .../java/android/os/DeviceIdleManager.java | 18 +++++++ .../android/os/IDeviceIdleController.aidl | 1 + .../android/server/DeviceIdleController.java | 52 ++++++++++++++----- api/test-current.txt | 1 + 4 files changed, 59 insertions(+), 13 deletions(-) diff --git a/apex/jobscheduler/framework/java/android/os/DeviceIdleManager.java b/apex/jobscheduler/framework/java/android/os/DeviceIdleManager.java index 9039f921b3bae..e27670c34fb20 100644 --- a/apex/jobscheduler/framework/java/android/os/DeviceIdleManager.java +++ b/apex/jobscheduler/framework/java/android/os/DeviceIdleManager.java @@ -17,10 +17,13 @@ package android.os; import android.annotation.NonNull; +import android.annotation.RequiresPermission; import android.annotation.SystemService; import android.annotation.TestApi; import android.content.Context; +import java.util.List; + /** * Access to the service that keeps track of device idleness and drives low power mode based on * that. @@ -66,4 +69,19 @@ public class DeviceIdleManager { return new String[0]; } } + + /** + * Add the specified packages to the power save whitelist. + * + * @return the number of packages that were successfully added to the whitelist + */ + @RequiresPermission(android.Manifest.permission.DEVICE_POWER) + public int addPowerSaveWhitelistApps(@NonNull List packageNames) { + try { + return mService.addPowerSaveWhitelistApps(packageNames); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + return 0; + } + } } diff --git a/apex/jobscheduler/framework/java/android/os/IDeviceIdleController.aidl b/apex/jobscheduler/framework/java/android/os/IDeviceIdleController.aidl index 9d5becbf77cde..20fb000b36d39 100644 --- a/apex/jobscheduler/framework/java/android/os/IDeviceIdleController.aidl +++ b/apex/jobscheduler/framework/java/android/os/IDeviceIdleController.aidl @@ -21,6 +21,7 @@ import android.os.UserHandle; /** @hide */ interface IDeviceIdleController { void addPowerSaveWhitelistApp(String name); + int addPowerSaveWhitelistApps(in List packageNames); void removePowerSaveWhitelistApp(String name); /* Removes an app from the system whitelist. Calling restoreSystemPowerWhitelistApp will add the app back into the system whitelist */ diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java index d6661c2c86160..3819ee2d2e030 100644 --- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java +++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java @@ -106,6 +106,8 @@ import java.io.IOException; import java.io.PrintWriter; import java.nio.charset.StandardCharsets; import java.util.Arrays; +import java.util.Collections; +import java.util.List; import java.util.stream.Collectors; /** @@ -1441,11 +1443,20 @@ public class DeviceIdleController extends SystemService if (DEBUG) { Slog.i(TAG, "addPowerSaveWhitelistApp(name = " + name + ")"); } + addPowerSaveWhitelistApps(Collections.singletonList(name)); + } + + @Override + public int addPowerSaveWhitelistApps(List packageNames) { + if (DEBUG) { + Slog.i(TAG, + "addPowerSaveWhitelistApps(name = " + packageNames + ")"); + } getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null); long ident = Binder.clearCallingIdentity(); try { - addPowerSaveWhitelistAppInternal(name); + return addPowerSaveWhitelistAppsInternal(packageNames); } finally { Binder.restoreCallingIdentity(ident); } @@ -2069,21 +2080,35 @@ public class DeviceIdleController extends SystemService } } - public boolean addPowerSaveWhitelistAppInternal(String name) { + private int addPowerSaveWhitelistAppsInternal(List pkgNames) { + int numAdded = 0; + int numErrors = 0; synchronized (this) { - try { - ApplicationInfo ai = getContext().getPackageManager().getApplicationInfo(name, - PackageManager.MATCH_ANY_USER); - if (mPowerSaveWhitelistUserApps.put(name, UserHandle.getAppId(ai.uid)) == null) { - reportPowerSaveWhitelistChangedLocked(); - updateWhitelistAppIdsLocked(); - writeConfigFileLocked(); + for (int i = pkgNames.size() - 1; i >= 0; --i) { + final String name = pkgNames.get(i); + if (name == null) { + numErrors++; + continue; } - return true; - } catch (PackageManager.NameNotFoundException e) { - return false; + try { + ApplicationInfo ai = getContext().getPackageManager().getApplicationInfo(name, + PackageManager.MATCH_ANY_USER); + if (mPowerSaveWhitelistUserApps.put(name, UserHandle.getAppId(ai.uid)) + == null) { + numAdded++; + } + } catch (PackageManager.NameNotFoundException e) { + Slog.e(TAG, "Tried to add unknown package to power save whitelist: " + name); + numErrors++; + } + } + if (numAdded > 0) { + reportPowerSaveWhitelistChangedLocked(); + updateWhitelistAppIdsLocked(); + writeConfigFileLocked(); } } + return pkgNames.size() - numErrors; } public boolean removePowerSaveWhitelistAppInternal(String name) { @@ -3922,7 +3947,8 @@ public class DeviceIdleController extends SystemService char op = arg.charAt(0); String pkg = arg.substring(1); if (op == '+') { - if (addPowerSaveWhitelistAppInternal(pkg)) { + if (addPowerSaveWhitelistAppsInternal(Collections.singletonList(pkg)) + == 1) { pw.println("Added: " + pkg); } else { pw.println("Unknown package: " + pkg); diff --git a/api/test-current.txt b/api/test-current.txt index 70837a84adfdb..67b50e4ccb683 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -1740,6 +1740,7 @@ package android.os { } public class DeviceIdleManager { + method @RequiresPermission("android.permission.DEVICE_POWER") public int addPowerSaveWhitelistApps(@NonNull java.util.List); method @NonNull public String[] getSystemPowerWhitelist(); method @NonNull public String[] getSystemPowerWhitelistExceptIdle(); }