diff options
| author | 2018-05-01 00:27:54 +0000 | |
|---|---|---|
| committer | 2018-05-01 00:27:54 +0000 | |
| commit | 639602ef116155834eca6d4408dfbac0c7afc24d (patch) | |
| tree | 56b99d3fd19b893a87372950bad22277dca07225 | |
| parent | 7105f6e81c1719779cd8f765243a432e9bedc886 (diff) | |
| parent | 0f8617a646ebc33e2e85a6c61c9533393318d204 (diff) | |
Merge "Enhance battery saver event log" into pi-dev
4 files changed, 96 insertions, 20 deletions
diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags index 2465ba2e21bd..d86973461ade 100644 --- a/services/core/java/com/android/server/EventLogTags.logtags +++ b/services/core/java/com/android/server/EventLogTags.logtags @@ -33,10 +33,11 @@ option java_package com.android.server # It logs the time remaining before the device would've normally gone to sleep without the request. 2731 power_soft_sleep_requested (savedwaketimems|2) # Power save state has changed. See BatterySaverController.java for the details. -2739 battery_saver_mode (prevOffOrOn|1|5),(nowOffOrOn|1|5),(interactive|1|5),(features|3|5) +2739 battery_saver_mode (prevOffOrOn|1|5),(nowOffOrOn|1|5),(interactive|1|5),(features|3|5),(reason|1|5) 27390 battery_saving_stats (batterySaver|1|5),(interactive|1|5),(doze|1|5),(delta_duration|2|3),(delta_battery_drain|1|1),(delta_battery_drain_percent|1|6),(total_duration|2|3),(total_battery_drain|1|1),(total_battery_drain_percent|1|6) # Note when the user activity timeout has been overriden by ActivityManagerService 27391 user_activity_timeout_override (override|2|3) +27392 battery_saver_setting (threshold|1) # # Leave IDs through 2740 for more power logs (2730 used by battery_discharge above) diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java index c5275333b184..cb84cf3fa72b 100644 --- a/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java +++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java @@ -90,6 +90,16 @@ public class BatterySaverController implements BatterySaverPolicyListener { */ private final Plugin[] mPlugins; + public static final int REASON_AUTOMATIC_ON = 0; + public static final int REASON_AUTOMATIC_OFF = 1; + public static final int REASON_MANUAL_ON = 2; + public static final int REASON_MANUAL_OFF = 3; + public static final int REASON_STICKY_RESTORE = 4; + public static final int REASON_INTERACTIVE_CHANGED = 5; + public static final int REASON_POLICY_CHANGED = 6; + public static final int REASON_PLUGGED_IN = 7; + public static final int REASON_SETTING_CHANGED = 8; + /** * Plugin interface. All methods are guaranteed to be called on the same (handler) thread. */ @@ -113,7 +123,8 @@ public class BatterySaverController implements BatterySaverPolicyListener { return; // No need to send it if not enabled. } // Don't send the broadcast, because we never did so in this case. - mHandler.postStateChanged(/*sendBroadcast=*/ false); + mHandler.postStateChanged(/*sendBroadcast=*/ false, + REASON_INTERACTIVE_CHANGED); break; case Intent.ACTION_BATTERY_CHANGED: synchronized (mLock) { @@ -184,7 +195,7 @@ public class BatterySaverController implements BatterySaverPolicyListener { if (!isEnabled()) { return; // No need to send it if not enabled. } - mHandler.postStateChanged(/*sendBroadcast=*/ true); + mHandler.postStateChanged(/*sendBroadcast=*/ true, REASON_POLICY_CHANGED); } private class MyHandler extends Handler { @@ -199,9 +210,9 @@ public class BatterySaverController implements BatterySaverPolicyListener { super(looper); } - public void postStateChanged(boolean sendBroadcast) { + public void postStateChanged(boolean sendBroadcast, int reason) { obtainMessage(MSG_STATE_CHANGED, sendBroadcast ? - ARG_SEND_BROADCAST : ARG_DONT_SEND_BROADCAST, 0).sendToTarget(); + ARG_SEND_BROADCAST : ARG_DONT_SEND_BROADCAST, reason).sendToTarget(); } public void postSystemReady() { @@ -212,7 +223,9 @@ public class BatterySaverController implements BatterySaverPolicyListener { public void dispatchMessage(Message msg) { switch (msg.what) { case MSG_STATE_CHANGED: - handleBatterySaverStateChanged(msg.arg1 == ARG_SEND_BROADCAST); + handleBatterySaverStateChanged( + msg.arg1 == ARG_SEND_BROADCAST, + msg.arg2); break; case MSG_SYSTEM_READY: @@ -227,14 +240,14 @@ public class BatterySaverController implements BatterySaverPolicyListener { /** * Called by {@link PowerManagerService} to update the battery saver stete. */ - public void enableBatterySaver(boolean enable) { + public void enableBatterySaver(boolean enable, int reason) { synchronized (mLock) { if (mEnabled == enable) { return; } mEnabled = enable; - mHandler.postStateChanged(/*sendBroadcast=*/ true); + mHandler.postStateChanged(/*sendBroadcast=*/ true, reason); } } @@ -275,7 +288,7 @@ public class BatterySaverController implements BatterySaverPolicyListener { * - When battery saver is on the interactive state changes. * - When battery saver is on the battery saver policy changes. */ - void handleBatterySaverStateChanged(boolean sendBroadcast) { + void handleBatterySaverStateChanged(boolean sendBroadcast, int reason) { final LowPowerModeListener[] listeners; final boolean enabled; @@ -287,7 +300,8 @@ public class BatterySaverController implements BatterySaverPolicyListener { mPreviouslyEnabled ? 1 : 0, // Previously off or on. mEnabled ? 1 : 0, // Now off or on. isInteractive ? 1 : 0, // Device interactive state. - mEnabled ? mBatterySaverPolicy.toEventLogString() : ""); + mEnabled ? mBatterySaverPolicy.toEventLogString() : "", + reason); mPreviouslyEnabled = mEnabled; listeners = mListeners.toArray(new LowPowerModeListener[mListeners.size()]); diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java index 28605215e19d..b9f31b126f0b 100644 --- a/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java +++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java @@ -18,6 +18,7 @@ package com.android.server.power.batterysaver; import android.content.ContentResolver; import android.content.Context; import android.database.ContentObserver; +import android.os.Handler; import android.os.UserHandle; import android.provider.Settings; import android.provider.Settings.Global; @@ -27,6 +28,7 @@ import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.os.BackgroundThread; +import com.android.server.EventLogTags; import com.android.server.power.BatterySaverPolicy; import com.android.server.power.BatterySaverStateMachineProto; @@ -95,6 +97,18 @@ public class BatterySaverStateMachine { @GuardedBy("mLock") private boolean mBatterySaverSnoozing; + /** + * Last reason passed to {@link #enableBatterySaverLocked}. + */ + @GuardedBy("mLock") + private int mLastChangedIntReason; + + /** + * Last reason passed to {@link #enableBatterySaverLocked}. + */ + @GuardedBy("mLock") + private String mLastChangedStrReason; + private final ContentObserver mSettingsObserver = new ContentObserver(null) { @Override public void onChange(boolean selfChange) { @@ -149,11 +163,25 @@ public class BatterySaverStateMachine { }); } + /** + * Run a {@link Runnable} on a background handler. + */ @VisibleForTesting void runOnBgThread(Runnable r) { BackgroundThread.getHandler().post(r); } + /** + * Run a {@link Runnable} on a background handler, but lazily. If the same {@link Runnable}, + * it'll be first removed before a new one is posted. + */ + @VisibleForTesting + void runOnBgThreadLazy(Runnable r, int delayMillis) { + final Handler h = BackgroundThread.getHandler(); + h.removeCallbacks(r); + h.postDelayed(r, delayMillis); + } + void refreshSettingsLocked() { final ContentResolver cr = mContext.getContentResolver(); @@ -199,14 +227,23 @@ public class BatterySaverStateMachine { mSettingBatterySaverEnabledSticky = batterySaverEnabledSticky; mSettingBatterySaverTriggerThreshold = batterySaverTriggerThreshold; + if (thresholdChanged) { + // To avoid spamming the event log, we throttle logging here. + runOnBgThreadLazy(mThresholdChangeLogger, 2000); + } + if (enabledChanged) { final String reason = batterySaverEnabled ? "Global.low_power changed to 1" : "Global.low_power changed to 0"; enableBatterySaverLocked(/*enable=*/ batterySaverEnabled, /*manual=*/ true, - reason); + BatterySaverController.REASON_SETTING_CHANGED, reason); } } + private final Runnable mThresholdChangeLogger = () -> { + EventLogTags.writeBatterySaverSetting(mSettingBatterySaverTriggerThreshold); + }; + /** * {@link com.android.server.power.PowerManagerService} calls it when battery state changes. * @@ -257,18 +294,26 @@ public class BatterySaverStateMachine { } if (mIsPowered) { updateSnoozingLocked(false, "Plugged in"); - enableBatterySaverLocked(/*enable=*/ false, /*manual=*/ false, "Plugged in"); + enableBatterySaverLocked(/*enable=*/ false, /*manual=*/ false, + BatterySaverController.REASON_PLUGGED_IN, + "Plugged in"); } else if (mSettingBatterySaverEnabledSticky) { // Re-enable BS. - enableBatterySaverLocked(/*enable=*/ true, /*manual=*/ true, "Sticky restore"); + enableBatterySaverLocked(/*enable=*/ true, /*manual=*/ true, + BatterySaverController.REASON_STICKY_RESTORE, + "Sticky restore"); } else if (mIsBatteryLevelLow) { if (!mBatterySaverSnoozing && isAutoBatterySaverConfigured()) { - enableBatterySaverLocked(/*enable=*/ true, /*manual=*/ false, "Auto ON"); + enableBatterySaverLocked(/*enable=*/ true, /*manual=*/ false, + BatterySaverController.REASON_AUTOMATIC_ON, + "Auto ON"); } } else { // Battery not low - enableBatterySaverLocked(/*enable=*/ false, /*manual=*/ false, "Auto OFF"); + enableBatterySaverLocked(/*enable=*/ false, /*manual=*/ false, + BatterySaverController.REASON_AUTOMATIC_OFF, + "Auto OFF"); } } @@ -284,6 +329,8 @@ public class BatterySaverStateMachine { } synchronized (mLock) { enableBatterySaverLocked(/*enable=*/ enabled, /*manual=*/ true, + (enabled ? BatterySaverController.REASON_MANUAL_ON + : BatterySaverController.REASON_MANUAL_OFF), (enabled ? "Manual ON" : "Manual OFF")); } } @@ -292,10 +339,11 @@ public class BatterySaverStateMachine { * Actually enable / disable battery saver. Write the new state to the global settings * and propagate it to {@link #mBatterySaverController}. */ - private void enableBatterySaverLocked(boolean enable, boolean manual, String reason) { + private void enableBatterySaverLocked(boolean enable, boolean manual, int intReason, + String strReason) { if (DEBUG) { Slog.d(TAG, "enableBatterySaver: enable=" + enable + " manual=" + manual - + " reason=" + reason); + + " reason=" + strReason + "(" + intReason + ")"); } final boolean wasEnabled = mBatterySaverController.isEnabled(); @@ -309,6 +357,8 @@ public class BatterySaverStateMachine { if (DEBUG) Slog.d(TAG, "Can't enable: isPowered"); return; } + mLastChangedIntReason = intReason; + mLastChangedStrReason = strReason; if (manual) { if (enable) { @@ -330,12 +380,12 @@ public class BatterySaverStateMachine { mSettingBatterySaverEnabledSticky = enable; putGlobalSetting(Global.LOW_POWER_MODE_STICKY, enable ? 1 : 0); } - mBatterySaverController.enableBatterySaver(enable); + mBatterySaverController.enableBatterySaver(enable, intReason); if (DEBUG) { Slog.d(TAG, "Battery saver: Enabled=" + enable + " manual=" + manual - + " reason=" + reason); + + " reason=" + strReason + "(" + intReason + ")"); } } @@ -365,6 +415,11 @@ public class BatterySaverStateMachine { pw.print(" Enabled="); pw.println(mBatterySaverController.isEnabled()); + pw.print(" mLastChangedIntReason="); + pw.println(mLastChangedIntReason); + pw.print(" mLastChangedStrReason="); + pw.println(mLastChangedStrReason); + pw.print(" mBootCompleted="); pw.println(mBootCompleted); pw.print(" mSettingsLoaded="); diff --git a/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java b/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java index 1367f583ba38..62fe6b261715 100644 --- a/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java +++ b/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java @@ -17,6 +17,7 @@ package com.android.server.power.batterysaver; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -144,6 +145,11 @@ public class BatterySaverStateMachineTest { void runOnBgThread(Runnable r) { r.run(); } + + @Override + void runOnBgThreadLazy(Runnable r, int delayMillis) { + r.run(); + } } @Before @@ -153,7 +159,7 @@ public class BatterySaverStateMachineTest { mMockBatterySaverController = mock(BatterySaverController.class); doAnswer((inv) -> mDevice.batterySaverEnabled = inv.getArgument(0)) - .when(mMockBatterySaverController).enableBatterySaver(anyBoolean()); + .when(mMockBatterySaverController).enableBatterySaver(anyBoolean(), anyInt()); when(mMockBatterySaverController.isEnabled()) .thenAnswer((inv) -> mDevice.batterySaverEnabled); |