Handle charging state separately from temporary parole
Don't use the parole state to deal with the plugged-in trigger.
Otherwise standby apps will only be paroled for a few minutes
after plugging in to charge and not the entire duration.
Use a different intent for charging state, since the CHARGING
intent takes several seconds to be received.
A refactor some time ago changed the charging state behavior
that caused this regression.
Bug: 31399882
Change-Id: Ic036de5e136b3151b225473d0c3f440adb3b48e7
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 8284773..04104b5 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -94,7 +94,7 @@
static final String TAG = "UsageStatsService";
- static final boolean DEBUG = false;
+ static final boolean DEBUG = false; // Never submit with true
static final boolean COMPRESS_TIME = false;
private static final long TEN_SECONDS = 10 * 1000;
@@ -139,8 +139,8 @@
long mSystemTimeSnapshot;
boolean mAppIdleEnabled;
- boolean mAppIdleParoled;
- private boolean mScreenOn;
+ boolean mAppIdleTempParoled;
+ boolean mCharging;
private long mLastAppIdleParoledTime;
private volatile boolean mPendingOneTimeCheckIdleStates;
@@ -191,7 +191,7 @@
mAppIdleEnabled = getContext().getResources().getBoolean(
com.android.internal.R.bool.config_enableAutoPowerModes);
if (mAppIdleEnabled) {
- IntentFilter deviceStates = new IntentFilter(BatteryManager.ACTION_CHARGING);
+ IntentFilter deviceStates = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
deviceStates.addAction(BatteryManager.ACTION_DISCHARGING);
deviceStates.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
getContext().registerReceiver(new DeviceStateReceiver(), deviceStates);
@@ -237,7 +237,7 @@
mSystemServicesReady = true;
} else if (phase == PHASE_BOOT_COMPLETED) {
- setAppIdleParoled(getContext().getSystemService(BatteryManager.class).isCharging());
+ setChargingState(getContext().getSystemService(BatteryManager.class).isCharging());
}
}
@@ -284,9 +284,8 @@
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
- if (BatteryManager.ACTION_CHARGING.equals(action)
- || BatteryManager.ACTION_DISCHARGING.equals(action)) {
- setAppIdleParoled(BatteryManager.ACTION_CHARGING.equals(action));
+ if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
+ setChargingState(intent.getIntExtra("plugged", 0) != 0);
} else if (PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED.equals(action)) {
onDeviceIdleModeChanged();
}
@@ -376,12 +375,21 @@
}
}
+ void setChargingState(boolean charging) {
+ synchronized (mLock) {
+ if (mCharging != charging) {
+ mCharging = charging;
+ postParoleStateChanged();
+ }
+ }
+ }
+
/** Paroled here means temporary pardon from being inactive */
void setAppIdleParoled(boolean paroled) {
synchronized (mLock) {
- if (mAppIdleParoled != paroled) {
- mAppIdleParoled = paroled;
- if (DEBUG) Slog.d(TAG, "Changing paroled to " + mAppIdleParoled);
+ if (mAppIdleTempParoled != paroled) {
+ mAppIdleTempParoled = paroled;
+ if (DEBUG) Slog.d(TAG, "Changing paroled to " + mAppIdleTempParoled);
if (paroled) {
postParoleEndTimeout();
} else {
@@ -393,6 +401,12 @@
}
}
+ boolean isParoledOrCharging() {
+ synchronized (mLock) {
+ return mAppIdleTempParoled || mCharging;
+ }
+ }
+
private void postNextParoleTimeout() {
if (DEBUG) Slog.d(TAG, "Posting MSG_CHECK_PAROLE_TIMEOUT");
mHandler.removeMessages(MSG_CHECK_PAROLE_TIMEOUT);
@@ -495,7 +509,7 @@
/** Check if it's been a while since last parole and let idle apps do some work */
void checkParoleTimeout() {
synchronized (mLock) {
- if (!mAppIdleParoled) {
+ if (!mAppIdleTempParoled) {
final long timeSinceLastParole = checkAndGetTimeLocked() - mLastAppIdleParoledTime;
if (timeSinceLastParole > mAppIdleParoleIntervalMillis) {
if (DEBUG) Slog.d(TAG, "Crossed default parole interval");
@@ -786,7 +800,7 @@
}
boolean isAppIdleFilteredOrParoled(String packageName, int userId, long elapsedRealtime) {
- if (mAppIdleParoled) {
+ if (isParoledOrCharging()) {
return false;
}
return isAppIdleFiltered(packageName, getAppId(packageName), userId, elapsedRealtime);
@@ -989,8 +1003,9 @@
}
void informParoleStateChanged() {
+ final boolean paroled = isParoledOrCharging();
for (AppIdleStateChangeListener listener : mPackageAccessListeners) {
- listener.onParoleStateChanged(mAppIdleParoled);
+ listener.onParoleStateChanged(paroled);
}
}
@@ -1072,9 +1087,9 @@
pw.println();
pw.print("mAppIdleEnabled="); pw.print(mAppIdleEnabled);
- pw.print(" mAppIdleParoled="); pw.print(mAppIdleParoled);
- pw.print(" mScreenOn="); pw.println(mScreenOn);
- pw.print("mLastAppIdleParoledTime=");
+ pw.print(" mAppIdleTempParoled="); pw.print(mAppIdleTempParoled);
+ pw.print(" mCharging="); pw.print(mCharging);
+ pw.print(" mLastAppIdleParoledTime=");
TimeUtils.formatDuration(mLastAppIdleParoledTime, pw);
pw.println();
}
@@ -1139,7 +1154,8 @@
break;
case MSG_PAROLE_STATE_CHANGED:
- if (DEBUG) Slog.d(TAG, "Parole state changed: " + mAppIdleParoled);
+ if (DEBUG) Slog.d(TAG, "Parole state: " + mAppIdleTempParoled
+ + ", Charging state:" + mCharging);
informParoleStateChanged();
break;
@@ -1466,7 +1482,7 @@
@Override
public boolean isAppIdleParoleOn() {
- return mAppIdleParoled;
+ return isParoledOrCharging();
}
@Override