From b9d7d27edeb4a4ee3ee4d6f181b1f14cff961b1e Mon Sep 17 00:00:00 2001 From: Raj M Date: Wed, 1 Dec 2021 08:24:32 +0000 Subject: Change the wakeup alarms for "light-doze-maintenance step" to non-wakeup alarms The wakeup alarms for doze-light-maintenance steps are causing battery drain in idle state. In terms of idle state battery optimization, Doze light maintenance step alarms can be changed to non-wakeup alarms as verified it is not critical as well as there is no user impact during our tests over a 50 days of Samsung's internal testing including User Trial. Once it's changed to a non-wakeup alarm, the time gap between maintenance can be increased. But from our real test data, the gap has not increased as much as we worried, so doze-maintenance is working well. Merged-In: Ib9bf9e120c806e61eced99fbfb84cdb19d844e69 Bug: b/197216833, b/185466339 Change-Id: Ida62842bdf8019563466fbf79326bc4d52ff3a99 Test: run `atest FrameworksMockingServicesTests:DeviceIdleControllerTest` --- .../com/android/server/DeviceIdleController.java | 28 +++++++++++++--------- services/art-profile | 2 +- .../android/server/DeviceIdleControllerTest.java | 15 ++++++++---- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java index 45588e831cb9..b28fd22f3c11 100644 --- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java +++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java @@ -3295,7 +3295,7 @@ public class DeviceIdleController extends SystemService if (DEBUG) Slog.d(TAG, "Moved from LIGHT_STATE_ACTIVE to LIGHT_STATE_INACTIVE"); resetLightIdleManagementLocked(); scheduleLightAlarmLocked(mConstants.LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT, - mConstants.FLEX_TIME_SHORT); + mConstants.FLEX_TIME_SHORT, true); EventLogTags.writeDeviceIdleLight(mLightState, "no activity"); } } @@ -3370,7 +3370,7 @@ public class DeviceIdleController extends SystemService mLightState = LIGHT_STATE_PRE_IDLE; EventLogTags.writeDeviceIdleLight(mLightState, reason); scheduleLightAlarmLocked(mConstants.LIGHT_PRE_IDLE_TIMEOUT, - mConstants.FLEX_TIME_SHORT); + mConstants.FLEX_TIME_SHORT, true); break; } // Nothing active, fall through to immediately idle. @@ -3389,7 +3389,7 @@ public class DeviceIdleController extends SystemService } } mMaintenanceStartTime = 0; - scheduleLightAlarmLocked(mNextLightIdleDelay, mNextLightIdleDelayFlex); + scheduleLightAlarmLocked(mNextLightIdleDelay, mNextLightIdleDelayFlex, false); mNextLightIdleDelay = Math.min(mConstants.LIGHT_MAX_IDLE_TIMEOUT, (long) (mNextLightIdleDelay * mConstants.LIGHT_IDLE_FACTOR)); mNextLightIdleDelayFlex = Math.min(mConstants.LIGHT_MAX_IDLE_TIMEOUT_FLEX, @@ -3413,7 +3413,7 @@ public class DeviceIdleController extends SystemService } else if (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, "Moved from LIGHT_STATE_IDLE to LIGHT_STATE_IDLE_MAINTENANCE."); mLightState = LIGHT_STATE_IDLE_MAINTENANCE; @@ -3424,7 +3424,8 @@ public class DeviceIdleController extends SystemService // We'd like to do maintenance, but currently don't have network // 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. - scheduleLightAlarmLocked(mNextLightIdleDelay, mNextLightIdleDelayFlex / 2); + scheduleLightAlarmLocked(mNextLightIdleDelay, + mNextLightIdleDelayFlex / 2, true); if (DEBUG) Slog.d(TAG, "Moved to LIGHT_WAITING_FOR_NETWORK."); mLightState = LIGHT_STATE_WAITING_FOR_NETWORK; EventLogTags.writeDeviceIdleLight(mLightState, reason); @@ -3953,18 +3954,23 @@ public class DeviceIdleController extends SystemService } } - void scheduleLightAlarmLocked(long delay, long flex) { + @GuardedBy("this") + void scheduleLightAlarmLocked(long delay, long flex, boolean wakeup) { if (DEBUG) { - Slog.d(TAG, "scheduleLightAlarmLocked(" + delay + Slog.d(TAG, "scheduleLightAlarmLocked(wakeup=" + wakeup + ", " + delay + (mConstants.USE_WINDOW_ALARMS ? "/" + flex : "") + ")"); } mNextLightAlarmTime = SystemClock.elapsedRealtime() + delay; if (mConstants.USE_WINDOW_ALARMS) { - mAlarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP, mNextLightAlarmTime, flex, - "DeviceIdleController.light", mLightAlarmListener, mHandler); + mAlarmManager.setWindow(wakeup ? AlarmManager.ELAPSED_REALTIME_WAKEUP : + AlarmManager.ELAPSED_REALTIME, + mNextLightAlarmTime, flex, "DeviceIdleController.light", mLightAlarmListener, + mHandler); } else { - mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, mNextLightAlarmTime, - "DeviceIdleController.light", mLightAlarmListener, mHandler); + mAlarmManager.set(wakeup ? AlarmManager.ELAPSED_REALTIME_WAKEUP : + AlarmManager.ELAPSED_REALTIME, + mNextLightAlarmTime, "DeviceIdleController.light", mLightAlarmListener, + mHandler); } } diff --git a/services/art-profile b/services/art-profile index af58bca129f8..2d9e95eebdc5 100644 --- a/services/art-profile +++ b/services/art-profile @@ -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;->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;->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; 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; diff --git a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java index acf50b4569c6..13bc929ac19c 100644 --- a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java @@ -1046,7 +1046,8 @@ public class DeviceIdleControllerTest { verifyLightStateConditions(LIGHT_STATE_IDLE); inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked( 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. @@ -1054,19 +1055,22 @@ public class DeviceIdleControllerTest { verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE); inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked( 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"); verifyLightStateConditions(LIGHT_STATE_IDLE); inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked( 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"); verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE); inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked( 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. mDeviceIdleController.handleMotionDetectedLocked(50, "test"); @@ -1075,7 +1079,8 @@ public class DeviceIdleControllerTest { verifyLightStateConditions(LIGHT_STATE_IDLE); inOrder.verify(mDeviceIdleController).scheduleLightAlarmLocked( 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 /////////////////// -- cgit v1.2.3-59-g8ed1b