Merge "Device idle fixes: issue #22209630 and issue #22225665" into mnc-dev

This commit is contained in:
Dianne Hackborn
2015-07-01 22:33:30 +00:00
committed by Android (Google) Code Review
5 changed files with 141 additions and 65 deletions

View File

@@ -216,6 +216,17 @@ public final class UserHandle implements Parcelable {
} }
} }
/**
* Generate a text representation of the uid, breaking out its individual
* components -- user, app, isolated, etc.
* @hide
*/
public static String formatUid(int uid) {
StringBuilder sb = new StringBuilder();
formatUid(sb, uid);
return sb.toString();
}
/** /**
* Generate a text representation of the uid, breaking out its individual * Generate a text representation of the uid, breaking out its individual
* components -- user, app, isolated, etc. * components -- user, app, isolated, etc.

View File

@@ -157,16 +157,21 @@ public class DeviceIdleController extends SystemService
*/ */
private final ArrayMap<String, Integer> mPowerSaveWhitelistUserApps = new ArrayMap<>(); private final ArrayMap<String, Integer> mPowerSaveWhitelistUserApps = new ArrayMap<>();
/**
* App IDs of built-in system apps that have been white-listed.
*/
private final SparseBooleanArray mPowerSaveWhitelistSystemAppIds = new SparseBooleanArray();
/** /**
* App IDs that have been white-listed to opt out of power save restrictions. * App IDs that have been white-listed to opt out of power save restrictions.
*/ */
private final SparseBooleanArray mPowerSaveWhitelistAppIds = new SparseBooleanArray(); private final SparseBooleanArray mPowerSaveWhitelistAllAppIds = new SparseBooleanArray();
/** /**
* Current app IDs that are in the complete power save white list. This array can * Current app IDs that are in the complete power save white list. This array can
* be shared with others because it will not be modified once set. * be shared with others because it will not be modified once set.
*/ */
private int[] mPowerSaveWhitelistAppIdArray = new int[0]; private int[] mPowerSaveWhitelistAllAppIdArray = new int[0];
/** /**
* List of end times for UIDs that are temporarily marked as being allowed to access * List of end times for UIDs that are temporarily marked as being allowed to access
@@ -478,6 +483,7 @@ public class DeviceIdleController extends SystemService
handleWriteConfigFile(); handleWriteConfigFile();
} break; } break;
case MSG_REPORT_IDLE_ON: { case MSG_REPORT_IDLE_ON: {
EventLogTags.writeDeviceIdleOnStart();
mLocalPowerManager.setDeviceIdleMode(true); mLocalPowerManager.setDeviceIdleMode(true);
try { try {
mNetworkPolicyManager.setDeviceIdleMode(true); mNetworkPolicyManager.setDeviceIdleMode(true);
@@ -485,8 +491,10 @@ public class DeviceIdleController extends SystemService
} catch (RemoteException e) { } catch (RemoteException e) {
} }
getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL); getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL);
EventLogTags.writeDeviceIdleOnComplete();
} break; } break;
case MSG_REPORT_IDLE_OFF: { case MSG_REPORT_IDLE_OFF: {
EventLogTags.writeDeviceIdleOffStart("unknown");
mLocalPowerManager.setDeviceIdleMode(false); mLocalPowerManager.setDeviceIdleMode(false);
try { try {
mNetworkPolicyManager.setDeviceIdleMode(false); mNetworkPolicyManager.setDeviceIdleMode(false);
@@ -494,11 +502,14 @@ public class DeviceIdleController extends SystemService
} catch (RemoteException e) { } catch (RemoteException e) {
} }
getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL); getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL);
EventLogTags.writeDeviceIdleOffComplete();
} break; } break;
case MSG_REPORT_ACTIVE: { case MSG_REPORT_ACTIVE: {
String activeReason = (String)msg.obj; String activeReason = (String)msg.obj;
int activeUid = msg.arg1; int activeUid = msg.arg1;
boolean needBroadcast = msg.arg2 != 0; boolean needBroadcast = msg.arg2 != 0;
EventLogTags.writeDeviceIdleOffStart(
activeReason != null ? activeReason : "unknown");
mLocalPowerManager.setDeviceIdleMode(false); mLocalPowerManager.setDeviceIdleMode(false);
try { try {
mNetworkPolicyManager.setDeviceIdleMode(false); mNetworkPolicyManager.setDeviceIdleMode(false);
@@ -508,6 +519,7 @@ public class DeviceIdleController extends SystemService
if (needBroadcast) { if (needBroadcast) {
getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL); getContext().sendBroadcastAsUser(mIdleIntent, UserHandle.ALL);
} }
EventLogTags.writeDeviceIdleOffComplete();
} break; } break;
case MSG_TEMP_APP_WHITELIST_TIMEOUT: { case MSG_TEMP_APP_WHITELIST_TIMEOUT: {
int uid = msg.arg1; int uid = msg.arg1;
@@ -557,17 +569,18 @@ public class DeviceIdleController extends SystemService
getContext().enforceCallingPermission( getContext().enforceCallingPermission(
Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
"No permission to change device idle whitelist"); "No permission to change device idle whitelist");
final int callingUid = Binder.getCallingUid();
userId = ActivityManagerNative.getDefault().handleIncomingUser( userId = ActivityManagerNative.getDefault().handleIncomingUser(
Binder.getCallingPid(), Binder.getCallingPid(),
Binder.getCallingUid(), callingUid,
userId, userId,
/*allowAll=*/ false, /*allowAll=*/ false,
/*requireFull=*/ false, /*requireFull=*/ false,
"addPowerSaveTempWhitelistApp", null); "addPowerSaveTempWhitelistApp", null);
final long token = Binder.clearCallingIdentity(); final long token = Binder.clearCallingIdentity();
try { try {
DeviceIdleController.this.addPowerSaveTempWhitelistAppInternal(packageName, DeviceIdleController.this.addPowerSaveTempWhitelistAppInternal(callingUid,
duration, userId); packageName, duration, userId);
} finally { } finally {
Binder.restoreCallingIdentity(token); Binder.restoreCallingIdentity(token);
} }
@@ -586,7 +599,7 @@ public class DeviceIdleController extends SystemService
public final class LocalService { public final class LocalService {
public void addPowerSaveTempWhitelistAppDirect(int appId, long duration) { public void addPowerSaveTempWhitelistAppDirect(int appId, long duration) {
DeviceIdleController.this.addPowerSaveTempWhitelistAppDirectInternal(appId, duration); addPowerSaveTempWhitelistAppDirectInternal(0, appId, duration);
} }
} }
@@ -614,8 +627,9 @@ public class DeviceIdleController extends SystemService
try { try {
ApplicationInfo ai = pm.getApplicationInfo(pkg, 0); ApplicationInfo ai = pm.getApplicationInfo(pkg, 0);
if ((ai.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { if ((ai.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
mPowerSaveWhitelistApps.put(ai.packageName, int appid = UserHandle.getAppId(ai.uid);
UserHandle.getAppId(ai.uid)); mPowerSaveWhitelistApps.put(ai.packageName, appid);
mPowerSaveWhitelistSystemAppIds.put(appid, true);
} }
} catch (PackageManager.NameNotFoundException e) { } catch (PackageManager.NameNotFoundException e) {
} }
@@ -667,14 +681,15 @@ public class DeviceIdleController extends SystemService
mSensingAlarmIntent = PendingIntent.getBroadcast(getContext(), 0, intentSensing, 0); mSensingAlarmIntent = PendingIntent.getBroadcast(getContext(), 0, intentSensing, 0);
mIdleIntent = new Intent(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED); mIdleIntent = new Intent(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
mIdleIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); mIdleIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
| Intent.FLAG_RECEIVER_FOREGROUND);
IntentFilter filter = new IntentFilter(); IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_BATTERY_CHANGED); filter.addAction(Intent.ACTION_BATTERY_CHANGED);
filter.addAction(ACTION_STEP_IDLE_STATE); filter.addAction(ACTION_STEP_IDLE_STATE);
getContext().registerReceiver(mReceiver, filter); getContext().registerReceiver(mReceiver, filter);
mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAppIdArray); mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
mDisplayManager.registerDisplayListener(mDisplayListener, null); mDisplayManager.registerDisplayListener(mDisplayListener, null);
updateDisplayLocked(); updateDisplayLocked();
@@ -747,7 +762,7 @@ public class DeviceIdleController extends SystemService
public int[] getAppIdWhitelistInternal() { public int[] getAppIdWhitelistInternal() {
synchronized (this) { synchronized (this) {
return mPowerSaveWhitelistAppIdArray; return mPowerSaveWhitelistAllAppIdArray;
} }
} }
@@ -761,12 +776,12 @@ public class DeviceIdleController extends SystemService
* Adds an app to the temporary whitelist and resets the endTime for granting the * Adds an app to the temporary whitelist and resets the endTime for granting the
* app an exemption to access network and acquire wakelocks. * app an exemption to access network and acquire wakelocks.
*/ */
public void addPowerSaveTempWhitelistAppInternal(String packageName, long duration, public void addPowerSaveTempWhitelistAppInternal(int callingUid, String packageName,
int userId) { long duration, int userId) {
try { try {
int uid = getContext().getPackageManager().getPackageUid(packageName, userId); int uid = getContext().getPackageManager().getPackageUid(packageName, userId);
int appId = UserHandle.getAppId(uid); int appId = UserHandle.getAppId(uid);
addPowerSaveTempWhitelistAppDirectInternal(appId, duration); addPowerSaveTempWhitelistAppDirectInternal(callingUid, appId, duration);
} catch (NameNotFoundException e) { } catch (NameNotFoundException e) {
} }
} }
@@ -775,9 +790,17 @@ public class DeviceIdleController extends SystemService
* Adds an app to the temporary whitelist and resets the endTime for granting the * Adds an app to the temporary whitelist and resets the endTime for granting the
* app an exemption to access network and acquire wakelocks. * app an exemption to access network and acquire wakelocks.
*/ */
public void addPowerSaveTempWhitelistAppDirectInternal(int appId, long duration) { public void addPowerSaveTempWhitelistAppDirectInternal(int callingUid, int appId,
long duration) {
final long timeNow = SystemClock.elapsedRealtime(); final long timeNow = SystemClock.elapsedRealtime();
synchronized (this) { synchronized (this) {
int callingAppId = UserHandle.getAppId(callingUid);
if (callingAppId >= Process.FIRST_APPLICATION_UID) {
if (!mPowerSaveWhitelistSystemAppIds.get(callingAppId)) {
throw new SecurityException("Calling app " + UserHandle.formatUid(callingUid)
+ " is not on whitelist");
}
}
duration = Math.min(duration, mConstants.MAX_TEMP_APP_WHITELIST_DURATION); duration = Math.min(duration, mConstants.MAX_TEMP_APP_WHITELIST_DURATION);
long currentEndTime = mTempWhitelistAppIdEndTimes.get(appId); long currentEndTime = mTempWhitelistAppIdEndTimes.get(appId);
// Set the new end time // Set the new end time
@@ -1026,25 +1049,25 @@ public class DeviceIdleController extends SystemService
} }
private void updateWhitelistAppIdsLocked() { private void updateWhitelistAppIdsLocked() {
mPowerSaveWhitelistAppIds.clear(); mPowerSaveWhitelistAllAppIds.clear();
for (int i=0; i<mPowerSaveWhitelistApps.size(); i++) { for (int i=0; i<mPowerSaveWhitelistApps.size(); i++) {
mPowerSaveWhitelistAppIds.put(mPowerSaveWhitelistApps.valueAt(i), true); mPowerSaveWhitelistAllAppIds.put(mPowerSaveWhitelistApps.valueAt(i), true);
} }
for (int i=0; i<mPowerSaveWhitelistUserApps.size(); i++) { for (int i=0; i<mPowerSaveWhitelistUserApps.size(); i++) {
mPowerSaveWhitelistAppIds.put(mPowerSaveWhitelistUserApps.valueAt(i), true); mPowerSaveWhitelistAllAppIds.put(mPowerSaveWhitelistUserApps.valueAt(i), true);
} }
int size = mPowerSaveWhitelistAppIds.size(); int size = mPowerSaveWhitelistAllAppIds.size();
int[] appids = new int[size]; int[] appids = new int[size];
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
appids[i] = mPowerSaveWhitelistAppIds.keyAt(i); appids[i] = mPowerSaveWhitelistAllAppIds.keyAt(i);
} }
mPowerSaveWhitelistAppIdArray = appids; mPowerSaveWhitelistAllAppIdArray = appids;
if (mLocalPowerManager != null) { if (mLocalPowerManager != null) {
if (DEBUG) { if (DEBUG) {
Slog.d(TAG, "Setting wakelock whitelist to " Slog.d(TAG, "Setting wakelock whitelist to "
+ Arrays.toString(mPowerSaveWhitelistAppIdArray)); + Arrays.toString(mPowerSaveWhitelistAllAppIdArray));
} }
mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAppIdArray); mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
} }
} }
@@ -1245,25 +1268,40 @@ public class DeviceIdleController extends SystemService
// Ignore, we always dump all. // Ignore, we always dump all.
} else if ("step".equals(arg)) { } else if ("step".equals(arg)) {
synchronized (this) { synchronized (this) {
stepIdleStateLocked(); long token = Binder.clearCallingIdentity();
pw.print("Stepped to: "); pw.println(stateToString(mState)); try {
stepIdleStateLocked();
pw.print("Stepped to: "); pw.println(stateToString(mState));
} finally {
Binder.restoreCallingIdentity(token);
}
} }
return; return;
} else if ("disable".equals(arg)) { } else if ("disable".equals(arg)) {
synchronized (this) { synchronized (this) {
if (mEnabled) { long token = Binder.clearCallingIdentity();
mEnabled = false; try {
becomeActiveLocked("disabled", Process.myUid()); if (mEnabled) {
pw.println("Idle mode disabled"); mEnabled = false;
becomeActiveLocked("disabled", Process.myUid());
pw.println("Idle mode disabled");
}
} finally {
Binder.restoreCallingIdentity(token);
} }
} }
return; return;
} else if ("enable".equals(arg)) { } else if ("enable".equals(arg)) {
synchronized (this) { synchronized (this) {
if (!mEnabled) { long token = Binder.clearCallingIdentity();
mEnabled = true; try {
becomeInactiveIfAppropriateLocked(); if (!mEnabled) {
pw.println("Idle mode enabled"); mEnabled = true;
becomeInactiveIfAppropriateLocked();
pw.println("Idle mode enabled");
}
} finally {
Binder.restoreCallingIdentity(token);
} }
} }
return; return;
@@ -1273,40 +1311,50 @@ public class DeviceIdleController extends SystemService
} }
return; return;
} else if ("whitelist".equals(arg)) { } else if ("whitelist".equals(arg)) {
i++; long token = Binder.clearCallingIdentity();
while (i < args.length) { try {
arg = args[i];
i++; i++;
if (arg.length() < 1 || (arg.charAt(0) != '-' while (i < args.length) {
&& arg.charAt(0) != '+')) { arg = args[i];
pw.println("Package must be prefixed with + or -: " + arg); i++;
return; if (arg.length() < 1 || (arg.charAt(0) != '-'
} && arg.charAt(0) != '+')) {
char op = arg.charAt(0); pw.println("Package must be prefixed with + or -: " + arg);
String pkg = arg.substring(1); return;
if (op == '+') { }
if (addPowerSaveWhitelistAppInternal(pkg)) { char op = arg.charAt(0);
pw.println("Added: " + pkg); String pkg = arg.substring(1);
if (op == '+') {
if (addPowerSaveWhitelistAppInternal(pkg)) {
pw.println("Added: " + pkg);
} else {
pw.println("Unknown package: " + pkg);
}
} else { } else {
pw.println("Unknown package: " + pkg); if (removePowerSaveWhitelistAppInternal(pkg)) {
} pw.println("Removed: " + pkg);
} else { }
if (removePowerSaveWhitelistAppInternal(pkg)) {
pw.println("Removed: " + pkg);
} }
} }
} finally {
Binder.restoreCallingIdentity(token);
} }
return; return;
} else if ("tempwhitelist".equals(arg)) { } else if ("tempwhitelist".equals(arg)) {
i++; long token = Binder.clearCallingIdentity();
if (i >= args.length) { try {
pw.println("At least one package name must be specified");
return;
}
while (i < args.length) {
arg = args[i];
i++; i++;
addPowerSaveTempWhitelistAppInternal(arg, 10000L, userId); if (i >= args.length) {
pw.println("At least one package name must be specified");
return;
}
while (i < args.length) {
arg = args[i];
i++;
addPowerSaveTempWhitelistAppInternal(0, arg, 10000L, userId);
}
} finally {
Binder.restoreCallingIdentity(token);
} }
} else if (arg.length() > 0 && arg.charAt(0) == '-'){ } else if (arg.length() > 0 && arg.charAt(0) == '-'){
pw.println("Unknown option: " + arg); pw.println("Unknown option: " + arg);
@@ -1337,12 +1385,12 @@ public class DeviceIdleController extends SystemService
pw.println(mPowerSaveWhitelistUserApps.keyAt(i)); pw.println(mPowerSaveWhitelistUserApps.keyAt(i));
} }
} }
size = mPowerSaveWhitelistAppIds.size(); size = mPowerSaveWhitelistAllAppIds.size();
if (size > 0) { if (size > 0) {
pw.println(" Whitelist app ids:"); pw.println(" Whitelist all app ids:");
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
pw.print(" "); pw.print(" ");
pw.print(mPowerSaveWhitelistAppIds.keyAt(i)); pw.print(mPowerSaveWhitelistAllAppIds.keyAt(i));
pw.println(); pw.println();
} }
} }

View File

@@ -183,6 +183,12 @@ option java_package com.android.server
34000 device_idle (state|1|5), (reason|3) 34000 device_idle (state|1|5), (reason|3)
34001 device_idle_step 34001 device_idle_step
34002 device_idle_wake_from_idle (is_idle|1|5), (reason|3) 34002 device_idle_wake_from_idle (is_idle|1|5), (reason|3)
34003 device_idle_on_start
34004 device_idle_on_phase (what|3)
34005 device_idle_on_complete
34006 device_idle_off_start (reason|3)
34007 device_idle_off_phase (what|3)
34008 device_idle_off_complete
# --------------------------- # ---------------------------
# DisplayManagerService.java # DisplayManagerService.java
@@ -224,8 +230,8 @@ option java_package com.android.server
# --------------------------- # ---------------------------
# IdleMaintenanceService.java # IdleMaintenanceService.java
# --------------------------- # ---------------------------
2753 idle_maintenance_window_start (time|2|3), (lastUserActivity|2|3), (batteryLevel|1|6), (batteryCharging|1|5) 51500 idle_maintenance_window_start (time|2|3), (lastUserActivity|2|3), (batteryLevel|1|6), (batteryCharging|1|5)
2754 idle_maintenance_window_finish (time|2|3), (lastUserActivity|2|3), (batteryLevel|1|6), (batteryCharging|1|5) 51501 idle_maintenance_window_finish (time|2|3), (lastUserActivity|2|3), (batteryLevel|1|6), (batteryCharging|1|5)
# --------------------------- # ---------------------------
# MountService.java # MountService.java

View File

@@ -146,6 +146,7 @@ import android.util.SparseIntArray;
import android.util.TrustedTime; import android.util.TrustedTime;
import android.util.Xml; import android.util.Xml;
import com.android.server.EventLogTags;
import libcore.io.IoUtils; import libcore.io.IoUtils;
import com.android.internal.R; import com.android.internal.R;
@@ -1764,7 +1765,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
if (mDeviceIdleMode != enabled) { if (mDeviceIdleMode != enabled) {
mDeviceIdleMode = enabled; mDeviceIdleMode = enabled;
if (mSystemReady) { if (mSystemReady) {
updateRulesForGlobalChangeLocked(true); updateRulesForDeviceIdleLocked();
}
if (enabled) {
EventLogTags.writeDeviceIdleOnPhase("net");
} else {
EventLogTags.writeDeviceIdleOffPhase("net");
} }
} }
} }

View File

@@ -2311,6 +2311,11 @@ public final class PowerManagerService extends SystemService
if (mDeviceIdleMode != enabled) { if (mDeviceIdleMode != enabled) {
mDeviceIdleMode = enabled; mDeviceIdleMode = enabled;
updateWakeLockDisabledStatesLocked(); updateWakeLockDisabledStatesLocked();
if (enabled) {
EventLogTags.writeDeviceIdleOnPhase("power");
} else {
EventLogTags.writeDeviceIdleOffPhase("power");
}
} }
} }
} }