summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Kweku Adams <kwekua@google.com> 2023-11-06 17:28:28 +0000
committer Kweku Adams <kwekua@google.com> 2023-11-06 17:49:50 +0000
commit40f718891338faa5836a439a3dcc10035d0701ad (patch)
treee7c45612779b169b24071cbb019d47f0165851ad
parentb1df623732cf5bdd64070c527815d83aae738955 (diff)
Avoid repeated/redundant work.
1. Avoid scheduling the idle alarm if the device is already considered idle. 2. Avoid scheduling the idle alarm again if the currently scheduled alarm is for the same time. Bug: 309292340 Test: atest FrameworksMockingServicesTests:DeviceIdlenessTrackerTest Change-Id: I0cb49041d15e5b2bd880ddc06cb2f1aa95e8c174
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/controllers/idle/DeviceIdlenessTracker.java42
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/job/controllers/idle/DeviceIdlenessTrackerTest.java71
2 files changed, 100 insertions, 13 deletions
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/idle/DeviceIdlenessTracker.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/idle/DeviceIdlenessTracker.java
index 7dd3d1343379..c142482d2eaf 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/idle/DeviceIdlenessTracker.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/idle/DeviceIdlenessTracker.java
@@ -82,6 +82,10 @@ public final class DeviceIdlenessTracker extends BroadcastReceiver implements Id
* be a negative value if the device is not in state to be considered idle.
*/
private long mIdlenessCheckScheduledElapsed = -1;
+ /**
+ * Time (in the elapsed realtime timebase) when the device can be considered idle.
+ */
+ private long mIdleStartElapsed = Long.MAX_VALUE;
private IdlenessListener mIdleListener;
private final UiModeManager.OnProjectionStateChangedListener mOnProjectionStateChangedListener =
@@ -191,11 +195,7 @@ public final class DeviceIdlenessTracker extends BroadcastReceiver implements Id
}
mProjectionActive = projectionActive;
if (mProjectionActive) {
- cancelIdlenessCheck();
- if (mIdle) {
- mIdle = false;
- mIdleListener.reportNewIdleState(mIdle);
- }
+ exitIdle();
} else {
maybeScheduleIdlenessCheck("Projection ended");
}
@@ -209,6 +209,7 @@ public final class DeviceIdlenessTracker extends BroadcastReceiver implements Id
pw.print(" mDockIdle: "); pw.println(mDockIdle);
pw.print(" mProjectionActive: "); pw.println(mProjectionActive);
pw.print(" mIdlenessCheckScheduledElapsed: "); pw.println(mIdlenessCheckScheduledElapsed);
+ pw.print(" mIdleStartElapsed: "); pw.println(mIdleStartElapsed);
}
@Override
@@ -270,11 +271,7 @@ public final class DeviceIdlenessTracker extends BroadcastReceiver implements Id
if (DEBUG) {
Slog.v(TAG, "exiting idle");
}
- cancelIdlenessCheck();
- if (mIdle) {
- mIdle = false;
- mIdleListener.reportNewIdleState(mIdle);
- }
+ exitIdle();
break;
case Intent.ACTION_SCREEN_OFF:
case Intent.ACTION_DREAMING_STARTED:
@@ -302,6 +299,12 @@ public final class DeviceIdlenessTracker extends BroadcastReceiver implements Id
}
private void maybeScheduleIdlenessCheck(String reason) {
+ if (mIdle) {
+ if (DEBUG) {
+ Slog.w(TAG, "Already idle. Redundant reason=" + reason);
+ }
+ return;
+ }
if ((!mScreenOn || mDockIdle) && !mProjectionActive) {
final long nowElapsed = sElapsedRealtimeClock.millis();
final long inactivityThresholdMs = mIsStablePower
@@ -319,19 +322,32 @@ public final class DeviceIdlenessTracker extends BroadcastReceiver implements Id
mIdlenessCheckScheduledElapsed = nowElapsed;
}
final long when = mIdlenessCheckScheduledElapsed + inactivityThresholdMs;
+ if (when == mIdleStartElapsed) {
+ if (DEBUG) {
+ Slog.i(TAG, "No change to idle start time");
+ }
+ return;
+ }
+ mIdleStartElapsed = when;
if (DEBUG) {
Slog.v(TAG, "Scheduling idle : " + reason + " now:" + nowElapsed
- + " checkElapsed=" + mIdlenessCheckScheduledElapsed + " when=" + when);
+ + " checkElapsed=" + mIdlenessCheckScheduledElapsed
+ + " when=" + mIdleStartElapsed);
}
mAlarm.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP,
- when, mIdleWindowSlop, "JS idleness",
+ mIdleStartElapsed, mIdleWindowSlop, "JS idleness",
AppSchedulingModuleThread.getExecutor(), mIdleAlarmListener);
}
}
- private void cancelIdlenessCheck() {
+ private void exitIdle() {
mAlarm.cancel(mIdleAlarmListener);
mIdlenessCheckScheduledElapsed = -1;
+ mIdleStartElapsed = Long.MAX_VALUE;
+ if (mIdle) {
+ mIdle = false;
+ mIdleListener.reportNewIdleState(false);
+ }
}
private void handleIdleTrigger() {
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/idle/DeviceIdlenessTrackerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/idle/DeviceIdlenessTrackerTest.java
index 09935f24cf93..0a56c4541c9e 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/idle/DeviceIdlenessTrackerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/idle/DeviceIdlenessTrackerTest.java
@@ -163,6 +163,77 @@ public class DeviceIdlenessTrackerTest {
}
@Test
+ public void testAlarmSkippedIfAlreadyIdle() {
+ setDeviceConfigLong(KEY_INACTIVITY_IDLE_THRESHOLD_MS, MINUTE_IN_MILLIS);
+ setDeviceConfigLong(KEY_INACTIVITY_STABLE_POWER_IDLE_THRESHOLD_MS, 5 * MINUTE_IN_MILLIS);
+ setBatteryState(false, false);
+
+ Intent dockIdleIntent = new Intent(Intent.ACTION_DOCK_IDLE);
+ mBroadcastReceiver.onReceive(mContext, dockIdleIntent);
+
+ final long nowElapsed = sElapsedRealtimeClock.millis();
+ long expectedAlarmElapsed = nowElapsed + MINUTE_IN_MILLIS;
+
+ ArgumentCaptor<AlarmManager.OnAlarmListener> onAlarmListenerCaptor =
+ ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class);
+
+ InOrder inOrder = inOrder(mAlarmManager);
+ inOrder.verify(mAlarmManager)
+ .setWindow(anyInt(), eq(expectedAlarmElapsed), anyLong(), anyString(),
+ eq(AppSchedulingModuleThread.getExecutor()),
+ onAlarmListenerCaptor.capture());
+
+ AlarmManager.OnAlarmListener onAlarmListener = onAlarmListenerCaptor.getValue();
+
+ advanceElapsedClock(MINUTE_IN_MILLIS);
+
+ onAlarmListener.onAlarm();
+
+ // Now in idle.
+
+ // Trigger SCREEN_OFF. Make sure alarm isn't set again.
+ Intent screenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF);
+ mBroadcastReceiver.onReceive(mContext, screenOffIntent);
+
+ inOrder.verify(mAlarmManager, never())
+ .setWindow(anyInt(), anyLong(), anyLong(), anyString(),
+ eq(AppSchedulingModuleThread.getExecutor()), any());
+ }
+
+ @Test
+ public void testAlarmSkippedIfNoThresholdChange() {
+ setDeviceConfigLong(KEY_INACTIVITY_IDLE_THRESHOLD_MS, 10 * MINUTE_IN_MILLIS);
+ setDeviceConfigLong(KEY_INACTIVITY_STABLE_POWER_IDLE_THRESHOLD_MS, 10 * MINUTE_IN_MILLIS);
+ setBatteryState(false, false);
+
+ Intent screenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF);
+ mBroadcastReceiver.onReceive(mContext, screenOffIntent);
+
+ final long nowElapsed = sElapsedRealtimeClock.millis();
+ long expectedAlarmElapsed = nowElapsed + 10 * MINUTE_IN_MILLIS;
+
+ InOrder inOrder = inOrder(mAlarmManager);
+ inOrder.verify(mAlarmManager)
+ .setWindow(anyInt(), eq(expectedAlarmElapsed), anyLong(), anyString(),
+ eq(AppSchedulingModuleThread.getExecutor()), any());
+
+ // Advanced the clock a little to make sure the tracker continues to use the original time.
+ advanceElapsedClock(MINUTE_IN_MILLIS);
+
+ // Now on stable power. Thresholds are the same, so alarm doesn't need to be rescheduled.
+ setBatteryState(true, true);
+ inOrder.verify(mAlarmManager, never())
+ .setWindow(anyInt(), eq(expectedAlarmElapsed), anyLong(), anyString(),
+ eq(AppSchedulingModuleThread.getExecutor()), any());
+
+ // Not on stable power. Thresholds are the same, so alarm doesn't need to be rescheduled.
+ setBatteryState(false, false);
+ inOrder.verify(mAlarmManager, never())
+ .setWindow(anyInt(), anyLong(), anyLong(), anyString(),
+ eq(AppSchedulingModuleThread.getExecutor()), any());
+ }
+
+ @Test
public void testThresholdChangeWithStablePowerChange() {
setDeviceConfigLong(KEY_INACTIVITY_IDLE_THRESHOLD_MS, 10 * MINUTE_IN_MILLIS);
setDeviceConfigLong(KEY_INACTIVITY_STABLE_POWER_IDLE_THRESHOLD_MS, 5 * MINUTE_IN_MILLIS);