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 20ee06405a864..4ee46f453bca5 100644 --- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java +++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java @@ -105,6 +105,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; /** @@ -1549,11 +1551,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); } @@ -2188,21 +2199,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) { @@ -4070,7 +4095,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 700be90a206ea..fa28daf6f5e3f 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -1741,6 +1741,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(); }