From 326b311b502067c9e4b3bab596d78d9234eb4828 Mon Sep 17 00:00:00 2001 From: Sudheer Shanka Date: Mon, 27 Nov 2017 14:40:57 -0800 Subject: [PATCH] Allow shell to remove pkgs from powersave-temp-whitelist. Bug: 69365569 Test: cts-tradefed run singleCommand cts-dev -m CtsAppTestCases -t \ android.app.cts.ActivityManagerProcessStateTest Test: manual Change-Id: Iebf782ab1033e5bcbe320ce4006d051ca260017e --- .../android/server/DeviceIdleController.java | 95 ++++++++++++++++--- 1 file changed, 80 insertions(+), 15 deletions(-) diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java index 0921a00b242f5..bafc28117cf04 100644 --- a/services/core/java/com/android/server/DeviceIdleController.java +++ b/services/core/java/com/android/server/DeviceIdleController.java @@ -76,6 +76,7 @@ import android.util.SparseBooleanArray; import android.util.TimeUtils; import android.util.Xml; +import com.android.internal.annotations.GuardedBy; import com.android.internal.app.IBatteryStats; import com.android.internal.os.AtomicFile; import com.android.internal.os.BackgroundThread; @@ -1756,6 +1757,27 @@ public class DeviceIdleController extends SystemService } } + void removePowerSaveTempWhitelistAppChecked(String packageName, int userId) + throws RemoteException { + getContext().enforceCallingPermission( + Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, + "No permission to change device idle whitelist"); + final int callingUid = Binder.getCallingUid(); + userId = ActivityManager.getService().handleIncomingUser( + Binder.getCallingPid(), + callingUid, + userId, + /*allowAll=*/ false, + /*requireFull=*/ false, + "removePowerSaveTempWhitelistApp", null); + final long token = Binder.clearCallingIdentity(); + try { + removePowerSaveTempWhitelistAppInternal(packageName, userId); + } finally { + Binder.restoreCallingIdentity(token); + } + } + /** * Adds an app to the temporary whitelist and resets the endTime for granting the * app an exemption to access network and acquire wakelocks. @@ -1821,6 +1843,32 @@ public class DeviceIdleController extends SystemService } } + /** + * Removes an app from the temporary whitelist and notifies the observers. + */ + private void removePowerSaveTempWhitelistAppInternal(String packageName, int userId) { + try { + final int uid = getContext().getPackageManager().getPackageUidAsUser( + packageName, userId); + final int appId = UserHandle.getAppId(uid); + removePowerSaveTempWhitelistAppDirectInternal(appId); + } catch (NameNotFoundException e) { + } + } + + private void removePowerSaveTempWhitelistAppDirectInternal(int appId) { + synchronized (this) { + final int idx = mTempWhitelistAppIdEndTimes.indexOfKey(appId); + if (idx < 0) { + // Nothing else to do + return; + } + final String reason = mTempWhitelistAppIdEndTimes.valueAt(idx).second; + mTempWhitelistAppIdEndTimes.removeAt(idx); + onAppRemovedFromTempWhitelistLocked(appId, reason); + } + } + private void postTempActiveTimeoutMessage(int uid, long delay) { if (DEBUG) { Slog.d(TAG, "postTempActiveTimeoutMessage: uid=" + uid + ", delay=" + delay); @@ -1842,18 +1890,7 @@ public class DeviceIdleController extends SystemService } if (timeNow >= entry.first.value) { mTempWhitelistAppIdEndTimes.delete(uid); - if (DEBUG) { - Slog.d(TAG, "Removing UID " + uid + " from temp whitelist"); - } - updateTempWhitelistAppIdsLocked(uid, false); - mHandler.obtainMessage(MSG_REPORT_TEMP_APP_WHITELIST_CHANGED, uid, 0) - .sendToTarget(); - reportTempWhitelistChangedLocked(); - try { - mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_FINISH, - entry.second, uid); - } catch (RemoteException e) { - } + onAppRemovedFromTempWhitelistLocked(uid, entry.second); } else { // Need more time if (DEBUG) { @@ -1864,6 +1901,22 @@ public class DeviceIdleController extends SystemService } } + @GuardedBy("this") + private void onAppRemovedFromTempWhitelistLocked(int appId, String reason) { + if (DEBUG) { + Slog.d(TAG, "Removing appId " + appId + " from temp whitelist"); + } + updateTempWhitelistAppIdsLocked(appId, false); + mHandler.obtainMessage(MSG_REPORT_TEMP_APP_WHITELIST_CHANGED, appId, 0) + .sendToTarget(); + reportTempWhitelistChangedLocked(); + try { + mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_TEMP_WHITELIST_FINISH, + reason, appId); + } catch (RemoteException e) { + } + } + public void exitIdleInternal(String reason) { synchronized (this) { becomeActiveLocked(reason, Binder.getCallingUid()); @@ -2700,9 +2753,11 @@ public class DeviceIdleController extends SystemService + "changes made using this won't be persisted across boots"); pw.println(" tempwhitelist"); pw.println(" Print packages that are temporarily whitelisted."); - pw.println(" tempwhitelist [-u USER] [-d DURATION] [package ..]"); - pw.println(" Temporarily place packages in whitelist for DURATION milliseconds."); + pw.println(" tempwhitelist [-u USER] [-d DURATION] [-r] [package]"); + pw.println(" Temporarily place package in whitelist for DURATION milliseconds."); pw.println(" If no DURATION is specified, 10 seconds is used"); + pw.println(" If [-r] option is used, then the package is removed from temp whitelist " + + "and any [-d] is ignored"); } class Shell extends ShellCommand { @@ -2986,6 +3041,7 @@ public class DeviceIdleController extends SystemService } } else if ("tempwhitelist".equals(cmd)) { long duration = 10000; + boolean removePkg = false; String opt; while ((opt=shell.getNextOption()) != null) { if ("-u".equals(opt)) { @@ -3002,16 +3058,25 @@ public class DeviceIdleController extends SystemService return -1; } duration = Long.parseLong(opt); + } else if ("-r".equals(opt)) { + removePkg = true; } } String arg = shell.getNextArg(); if (arg != null) { try { - addPowerSaveTempWhitelistAppChecked(arg, duration, shell.userId, "shell"); + if (removePkg) { + removePowerSaveTempWhitelistAppChecked(arg, shell.userId); + } else { + addPowerSaveTempWhitelistAppChecked(arg, duration, shell.userId, "shell"); + } } catch (Exception e) { pw.println("Failed: " + e); return -1; } + } else if (removePkg) { + pw.println("[-r] requires a package name"); + return -1; } else { dumpTempWhitelistSchedule(pw, false); }