summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Makoto Onuki <omakoto@google.com> 2018-05-01 00:27:54 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2018-05-01 00:27:54 +0000
commit639602ef116155834eca6d4408dfbac0c7afc24d (patch)
tree56b99d3fd19b893a87372950bad22277dca07225
parent7105f6e81c1719779cd8f765243a432e9bedc886 (diff)
parent0f8617a646ebc33e2e85a6c61c9533393318d204 (diff)
Merge "Enhance battery saver event log" into pi-dev
-rw-r--r--services/core/java/com/android/server/EventLogTags.logtags3
-rw-r--r--services/core/java/com/android/server/power/batterysaver/BatterySaverController.java32
-rw-r--r--services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java73
-rw-r--r--services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java8
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);