diff options
-rw-r--r-- | apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java | 47 |
1 files changed, 42 insertions, 5 deletions
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java index cae6cdcf8f1f..54c3db48231d 100644 --- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java +++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java @@ -104,6 +104,7 @@ import android.util.IndentingPrintWriter; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; +import android.util.SparseLongArray; import android.util.TimeUtils; import android.view.Display; import android.widget.Toast; @@ -260,6 +261,13 @@ public class AppStandbyController private final CountDownLatch mAdminDataAvailableLatch = new CountDownLatch(1); + /** + * Set of user IDs and the next time (in the elapsed realtime timebase) when we should check the + * apps' idle states. + */ + @GuardedBy("mPendingIdleStateChecks") + private final SparseLongArray mPendingIdleStateChecks = new SparseLongArray(); + // Cache the active network scorer queried from the network scorer service private volatile String mCachedNetworkScorer = null; // The last time the network scorer service was queried @@ -722,7 +730,14 @@ public class AppStandbyController @Override public void postCheckIdleStates(int userId) { - mHandler.sendMessage(mHandler.obtainMessage(MSG_CHECK_IDLE_STATES, userId, 0)); + if (userId == UserHandle.USER_ALL) { + postOneTimeCheckIdleStates(); + } else { + synchronized (mPendingIdleStateChecks) { + mPendingIdleStateChecks.put(userId, mInjector.elapsedRealtime()); + } + mHandler.obtainMessage(MSG_CHECK_IDLE_STATES).sendToTarget(); + } } @Override @@ -2374,10 +2389,32 @@ public class AppStandbyController break; case MSG_CHECK_IDLE_STATES: - if (checkIdleStates(msg.arg1) && mAppIdleEnabled) { - mHandler.sendMessageDelayed(mHandler.obtainMessage( - MSG_CHECK_IDLE_STATES, msg.arg1, 0), - mCheckIdleIntervalMillis); + removeMessages(MSG_CHECK_IDLE_STATES); + + long earliestCheck = Long.MAX_VALUE; + final long nowElapsed = mInjector.elapsedRealtime(); + synchronized (mPendingIdleStateChecks) { + for (int i = mPendingIdleStateChecks.size() - 1; i >= 0; --i) { + long expirationTime = mPendingIdleStateChecks.valueAt(i); + + if (expirationTime <= nowElapsed) { + final int userId = mPendingIdleStateChecks.keyAt(i); + if (checkIdleStates(userId) && mAppIdleEnabled) { + expirationTime = nowElapsed + mCheckIdleIntervalMillis; + mPendingIdleStateChecks.put(userId, expirationTime); + } else { + mPendingIdleStateChecks.removeAt(i); + continue; + } + } + + earliestCheck = Math.min(earliestCheck, expirationTime); + } + } + if (earliestCheck != Long.MAX_VALUE) { + mHandler.sendMessageDelayed( + mHandler.obtainMessage(MSG_CHECK_IDLE_STATES), + earliestCheck - nowElapsed); } break; |