Change some light idle alarms to non-wakeup.

Changing some light idle alarms to non-wakeup to reduce the number of
alarms that could potentially wake up the device. If the CPU is already
in suspend, we don't need to wake it up just to officially enter doze
light. We can just wait until the CPU wakes up to do the transition. On
a particularly active device, this won't change the time we enter Doze
light much, but on a quiet device, the Doze light and maintenance
windows may be shifted significantly.

Bug: 185466339
Bug: 197216833
Test: atest DeviceIdleTest
Test: atest FrameworksMockingServicesTests:DeviceIdleControllerTest
Change-Id: Ib9bf9e120c806e61eced99fbfb84cdb19d844e69
This commit is contained in:
Kweku Adams
2021-12-03 11:53:02 -08:00
parent ef6564cbfb
commit 27dd7080fc
3 changed files with 26 additions and 15 deletions

View File

@@ -3343,7 +3343,7 @@ public class DeviceIdleController extends SystemService
if (DEBUG) Slog.d(TAG, "Moved from LIGHT_STATE_ACTIVE to LIGHT_STATE_INACTIVE"); if (DEBUG) Slog.d(TAG, "Moved from LIGHT_STATE_ACTIVE to LIGHT_STATE_INACTIVE");
resetLightIdleManagementLocked(); resetLightIdleManagementLocked();
scheduleLightAlarmLocked(mConstants.LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT, scheduleLightAlarmLocked(mConstants.LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT,
mConstants.FLEX_TIME_SHORT); mConstants.FLEX_TIME_SHORT, true);
EventLogTags.writeDeviceIdleLight(mLightState, "no activity"); EventLogTags.writeDeviceIdleLight(mLightState, "no activity");
} }
} }
@@ -3424,7 +3424,7 @@ public class DeviceIdleController extends SystemService
mLightState = LIGHT_STATE_PRE_IDLE; mLightState = LIGHT_STATE_PRE_IDLE;
EventLogTags.writeDeviceIdleLight(mLightState, reason); EventLogTags.writeDeviceIdleLight(mLightState, reason);
scheduleLightAlarmLocked(mConstants.LIGHT_PRE_IDLE_TIMEOUT, scheduleLightAlarmLocked(mConstants.LIGHT_PRE_IDLE_TIMEOUT,
mConstants.FLEX_TIME_SHORT); mConstants.FLEX_TIME_SHORT, true);
break; break;
} }
// Nothing active, fall through to immediately idle. // Nothing active, fall through to immediately idle.
@@ -3443,7 +3443,7 @@ public class DeviceIdleController extends SystemService
} }
} }
mMaintenanceStartTime = 0; mMaintenanceStartTime = 0;
scheduleLightAlarmLocked(mNextLightIdleDelay, mNextLightIdleDelayFlex); scheduleLightAlarmLocked(mNextLightIdleDelay, mNextLightIdleDelayFlex, false);
mNextLightIdleDelay = Math.min(mConstants.LIGHT_MAX_IDLE_TIMEOUT, mNextLightIdleDelay = Math.min(mConstants.LIGHT_MAX_IDLE_TIMEOUT,
(long) (mNextLightIdleDelay * mConstants.LIGHT_IDLE_FACTOR)); (long) (mNextLightIdleDelay * mConstants.LIGHT_IDLE_FACTOR));
mNextLightIdleDelayFlex = Math.min(mConstants.LIGHT_MAX_IDLE_TIMEOUT_FLEX, mNextLightIdleDelayFlex = Math.min(mConstants.LIGHT_MAX_IDLE_TIMEOUT_FLEX,
@@ -3467,7 +3467,7 @@ public class DeviceIdleController extends SystemService
} else if (mCurLightIdleBudget > mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET) { } else if (mCurLightIdleBudget > mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET) {
mCurLightIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET; mCurLightIdleBudget = mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET;
} }
scheduleLightAlarmLocked(mCurLightIdleBudget, mConstants.FLEX_TIME_SHORT); scheduleLightAlarmLocked(mCurLightIdleBudget, mConstants.FLEX_TIME_SHORT, true);
if (DEBUG) Slog.d(TAG, if (DEBUG) Slog.d(TAG,
"Moved from LIGHT_STATE_IDLE to LIGHT_STATE_IDLE_MAINTENANCE."); "Moved from LIGHT_STATE_IDLE to LIGHT_STATE_IDLE_MAINTENANCE.");
mLightState = LIGHT_STATE_IDLE_MAINTENANCE; mLightState = LIGHT_STATE_IDLE_MAINTENANCE;
@@ -3478,7 +3478,8 @@ public class DeviceIdleController extends SystemService
// We'd like to do maintenance, but currently don't have network // We'd like to do maintenance, but currently don't have network
// connectivity... let's try to wait until the network comes back. // connectivity... let's try to wait until the network comes back.
// We'll only wait for another full idle period, however, and then give up. // We'll only wait for another full idle period, however, and then give up.
scheduleLightAlarmLocked(mNextLightIdleDelay, mNextLightIdleDelayFlex / 2); scheduleLightAlarmLocked(mNextLightIdleDelay,
mNextLightIdleDelayFlex / 2, true);
if (DEBUG) Slog.d(TAG, "Moved to LIGHT_WAITING_FOR_NETWORK."); if (DEBUG) Slog.d(TAG, "Moved to LIGHT_WAITING_FOR_NETWORK.");
mLightState = LIGHT_STATE_WAITING_FOR_NETWORK; mLightState = LIGHT_STATE_WAITING_FOR_NETWORK;
EventLogTags.writeDeviceIdleLight(mLightState, reason); EventLogTags.writeDeviceIdleLight(mLightState, reason);
@@ -4034,17 +4035,22 @@ public class DeviceIdleController extends SystemService
} }
@GuardedBy("this") @GuardedBy("this")
void scheduleLightAlarmLocked(long delay, long flex) { void scheduleLightAlarmLocked(long delay, long flex, boolean wakeup) {
if (DEBUG) { if (DEBUG) {
Slog.d(TAG, "scheduleLightAlarmLocked(" + delay Slog.d(TAG, "scheduleLightAlarmLocked(" + delay
+ (mConstants.USE_WINDOW_ALARMS ? "/" + flex : "") + ")"); + (mConstants.USE_WINDOW_ALARMS ? "/" + flex : "")
+ ", wakeup=" + wakeup + ")");
} }
mNextLightAlarmTime = SystemClock.elapsedRealtime() + delay; mNextLightAlarmTime = SystemClock.elapsedRealtime() + delay;
if (mConstants.USE_WINDOW_ALARMS) { if (mConstants.USE_WINDOW_ALARMS) {
mAlarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP, mNextLightAlarmTime, flex, mAlarmManager.setWindow(
wakeup ? AlarmManager.ELAPSED_REALTIME_WAKEUP : AlarmManager.ELAPSED_REALTIME,
mNextLightAlarmTime, flex,
"DeviceIdleController.light", mLightAlarmListener, mHandler); "DeviceIdleController.light", mLightAlarmListener, mHandler);
} else { } else {
mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, mNextLightAlarmTime, mAlarmManager.set(
wakeup ? AlarmManager.ELAPSED_REALTIME_WAKEUP : AlarmManager.ELAPSED_REALTIME,
mNextLightAlarmTime,
"DeviceIdleController.light", mLightAlarmListener, mHandler); "DeviceIdleController.light", mLightAlarmListener, mHandler);
} }
} }

View File

@@ -1464,7 +1464,7 @@ HSPLcom/android/server/DeviceIdleController;->reportTempWhitelistChangedLocked(I
HPLcom/android/server/DeviceIdleController;->resetIdleManagementLocked()V+]Lcom/android/server/AnyMotionDetector;Lcom/android/server/AnyMotionDetector;]Lcom/android/server/DeviceIdleController;Lcom/android/server/DeviceIdleController; HPLcom/android/server/DeviceIdleController;->resetIdleManagementLocked()V+]Lcom/android/server/AnyMotionDetector;Lcom/android/server/AnyMotionDetector;]Lcom/android/server/DeviceIdleController;Lcom/android/server/DeviceIdleController;
HPLcom/android/server/DeviceIdleController;->resetLightIdleManagementLocked()V+]Lcom/android/server/DeviceIdleController;Lcom/android/server/DeviceIdleController; HPLcom/android/server/DeviceIdleController;->resetLightIdleManagementLocked()V+]Lcom/android/server/DeviceIdleController;Lcom/android/server/DeviceIdleController;
HPLcom/android/server/DeviceIdleController;->scheduleAlarmLocked(JZ)V+]Landroid/app/AlarmManager;Landroid/app/AlarmManager; HPLcom/android/server/DeviceIdleController;->scheduleAlarmLocked(JZ)V+]Landroid/app/AlarmManager;Landroid/app/AlarmManager;
HPLcom/android/server/DeviceIdleController;->scheduleLightAlarmLocked(JJ)V+]Landroid/app/AlarmManager;Landroid/app/AlarmManager; HPLcom/android/server/DeviceIdleController;->scheduleLightAlarmLocked(JJZ)V+]Landroid/app/AlarmManager;Landroid/app/AlarmManager;
HPLcom/android/server/DeviceIdleController;->scheduleMotionRegistrationAlarmLocked()V+]Lcom/android/server/DeviceIdleController$Injector;Lcom/android/server/DeviceIdleController$Injector;]Landroid/app/AlarmManager;Landroid/app/AlarmManager; HPLcom/android/server/DeviceIdleController;->scheduleMotionRegistrationAlarmLocked()V+]Lcom/android/server/DeviceIdleController$Injector;Lcom/android/server/DeviceIdleController$Injector;]Landroid/app/AlarmManager;Landroid/app/AlarmManager;
HSPLcom/android/server/DeviceIdleController;->scheduleMotionTimeoutAlarmLocked()V+]Landroid/app/AlarmManager;Landroid/app/AlarmManager;]Lcom/android/server/DeviceIdleController$Injector;Lcom/android/server/DeviceIdleController$Injector; HSPLcom/android/server/DeviceIdleController;->scheduleMotionTimeoutAlarmLocked()V+]Landroid/app/AlarmManager;Landroid/app/AlarmManager;]Lcom/android/server/DeviceIdleController$Injector;Lcom/android/server/DeviceIdleController$Injector;
HPLcom/android/server/DeviceIdleController;->scheduleReportActiveLocked(Ljava/lang/String;I)V+]Lcom/android/server/DeviceIdleController$MyHandler;Lcom/android/server/DeviceIdleController$MyHandler; HPLcom/android/server/DeviceIdleController;->scheduleReportActiveLocked(Ljava/lang/String;I)V+]Lcom/android/server/DeviceIdleController$MyHandler;Lcom/android/server/DeviceIdleController$MyHandler;

View File

@@ -1047,7 +1047,8 @@ public class DeviceIdleControllerTest {
verifyLightStateConditions(LIGHT_STATE_IDLE); verifyLightStateConditions(LIGHT_STATE_IDLE);
inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked( inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked(
longThat(l -> l == mConstants.LIGHT_IDLE_TIMEOUT), longThat(l -> l == mConstants.LIGHT_IDLE_TIMEOUT),
longThat(l -> l == mConstants.LIGHT_IDLE_TIMEOUT_INITIAL_FLEX)); longThat(l -> l == mConstants.LIGHT_IDLE_TIMEOUT_INITIAL_FLEX),
eq(false));
// Should just alternate between IDLE and IDLE_MAINTENANCE now. // Should just alternate between IDLE and IDLE_MAINTENANCE now.
@@ -1055,19 +1056,22 @@ public class DeviceIdleControllerTest {
verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE); verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked( inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked(
longThat(l -> l >= mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET), longThat(l -> l >= mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET),
longThat(l -> l == mConstants.FLEX_TIME_SHORT)); longThat(l -> l == mConstants.FLEX_TIME_SHORT),
eq(true));
mDeviceIdleController.stepLightIdleStateLocked("testing"); mDeviceIdleController.stepLightIdleStateLocked("testing");
verifyLightStateConditions(LIGHT_STATE_IDLE); verifyLightStateConditions(LIGHT_STATE_IDLE);
inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked( inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked(
longThat(l -> l > mConstants.LIGHT_IDLE_TIMEOUT), longThat(l -> l > mConstants.LIGHT_IDLE_TIMEOUT),
longThat(l -> l > mConstants.LIGHT_IDLE_TIMEOUT_INITIAL_FLEX)); longThat(l -> l > mConstants.LIGHT_IDLE_TIMEOUT_INITIAL_FLEX),
eq(false));
mDeviceIdleController.stepLightIdleStateLocked("testing"); mDeviceIdleController.stepLightIdleStateLocked("testing");
verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE); verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked( inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked(
longThat(l -> l >= mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET), longThat(l -> l >= mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET),
longThat(l -> l == mConstants.FLEX_TIME_SHORT)); longThat(l -> l == mConstants.FLEX_TIME_SHORT),
eq(true));
// Test that motion doesn't reset the idle timeout. // Test that motion doesn't reset the idle timeout.
mDeviceIdleController.handleMotionDetectedLocked(50, "test"); mDeviceIdleController.handleMotionDetectedLocked(50, "test");
@@ -1076,7 +1080,8 @@ public class DeviceIdleControllerTest {
verifyLightStateConditions(LIGHT_STATE_IDLE); verifyLightStateConditions(LIGHT_STATE_IDLE);
inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked( inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked(
longThat(l -> l > mConstants.LIGHT_IDLE_TIMEOUT), longThat(l -> l > mConstants.LIGHT_IDLE_TIMEOUT),
longThat(l -> l > mConstants.LIGHT_IDLE_TIMEOUT_INITIAL_FLEX)); longThat(l -> l > mConstants.LIGHT_IDLE_TIMEOUT_INITIAL_FLEX),
eq(false));
} }
///////////////// EXIT conditions /////////////////// ///////////////// EXIT conditions ///////////////////