Loading core/java/android/os/BatteryManagerInternal.java +37 −0 Original line number Diff line number Diff line Loading @@ -24,26 +24,63 @@ package android.os; public abstract class BatteryManagerInternal { /** * Returns true if the device is plugged into any of the specified plug types. * * This is a simple accessor that's safe to be called from any locks, but internally it may * wait on the battery service lock. */ public abstract boolean isPowered(int plugTypeSet); /** * Returns the current plug type. * * This is a simple accessor that's safe to be called from any locks, but internally it may * wait on the battery service lock. */ public abstract int getPlugType(); /** * Returns battery level as a percentage. * * This is a simple accessor that's safe to be called from any locks, but internally it may * wait on the battery service lock. */ public abstract int getBatteryLevel(); /** * Instantaneous battery capacity in uA-h, as defined in the HealthInfo HAL struct. * Please note apparently it could be bigger than {@link #getBatteryFullCharge}. * * This is a simple accessor that's safe to be called from any locks, but internally it may * wait on the battery service lock. * * @see android.hardware.health.V1_0.HealthInfo#batteryChargeCounter */ public abstract int getBatteryChargeCounter(); /** * Battery charge value when it is considered to be "full" in uA-h , as defined in the * HealthInfo HAL struct. * * This is a simple accessor that's safe to be called from any locks, but internally it may * wait on the battery service lock. * * @see android.hardware.health.V1_0.HealthInfo#batteryFullCharge */ public abstract int getBatteryFullCharge(); /** * Returns whether we currently consider the battery level to be low. * * This is a simple accessor that's safe to be called from any locks, but internally it may * wait on the battery service lock. */ public abstract boolean getBatteryLevelLow(); /** * Returns a non-zero value if an unsupported charger is attached. * * This is a simple accessor that's safe to be called from any locks, but internally it may * wait on the battery service lock. */ public abstract int getInvalidCharger(); } services/core/java/com/android/server/BatteryService.java +17 −0 Original line number Diff line number Diff line Loading @@ -835,6 +835,9 @@ public final class BatteryService extends SystemService { case "level": mHealthInfo.batteryLevel = Integer.parseInt(value); break; case "counter": mHealthInfo.batteryChargeCounter = Integer.parseInt(value); break; case "temp": mHealthInfo.batteryTemperature = Integer.parseInt(value); break; Loading Loading @@ -1163,6 +1166,20 @@ public final class BatteryService extends SystemService { } } @Override public int getBatteryChargeCounter() { synchronized (mLock) { return mHealthInfo.batteryChargeCounter; } } @Override public int getBatteryFullCharge() { synchronized (mLock) { return mHealthInfo.batteryFullCharge; } } @Override public boolean getBatteryLevelLow() { synchronized (mLock) { Loading services/core/java/com/android/server/EventLogTags.logtags +1 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ option java_package com.android.server 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) 27390 battery_saving_stats (batterySaver|1|5),(interactive|1|5),(doze|1|5),(delta_duration|2|3),(delta_battery_drain|1|6),(total_duration|2|3),(total_battery_drain|1|6) # # Leave IDs through 2740 for more power logs (2730 used by battery_discharge above) Loading services/core/java/com/android/server/power/BatterySaverPolicy.java +3 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import android.util.Slog; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.server.power.batterysaver.BatterySavingStats; import com.android.server.power.batterysaver.CpuFrequencies; import java.io.PrintWriter; Loading Loading @@ -498,6 +499,8 @@ public class BatterySaverPolicy extends ContentObserver { pw.print(" Noninteractive File values:\n"); dumpMap(pw, " ", mFilesForNoninteractive); pw.println(); pw.println(); BatterySavingStats.getInstance().dump(pw, " "); } } Loading services/core/java/com/android/server/power/batterysaver/BatterySaverController.java +52 −2 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.hardware.power.V1_0.PowerHint; import android.net.Uri; import android.os.BatteryManager; import android.os.Handler; import android.os.Looper; import android.os.Message; Loading @@ -50,6 +51,9 @@ import com.android.server.LocalServices; import com.android.server.power.BatterySaverPolicy; import com.android.server.power.BatterySaverPolicy.BatterySaverPolicyListener; import com.android.server.power.PowerManagerService; import com.android.server.power.batterysaver.BatterySavingStats.BatterySaverState; import com.android.server.power.batterysaver.BatterySavingStats.DozeState; import com.android.server.power.batterysaver.BatterySavingStats.InteractiveState; import java.util.ArrayList; Loading @@ -70,6 +74,8 @@ public class BatterySaverController implements BatterySaverPolicyListener { private final BatterySaverPolicy mBatterySaverPolicy; private final BatterySavingStats mBatterySavingStats; private static final String WARNING_LINK_URL = "http://goto.google.com/extreme-battery-saver"; @GuardedBy("mLock") Loading @@ -78,6 +84,9 @@ public class BatterySaverController implements BatterySaverPolicyListener { @GuardedBy("mLock") private boolean mEnabled; @GuardedBy("mLock") private boolean mIsPluggedIn; /** * Previously enabled or not; only for the event logging. Only use it from * {@link #handleBatterySaverStateChanged}. Loading @@ -104,15 +113,28 @@ public class BatterySaverController implements BatterySaverPolicyListener { private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (DEBUG) { Slog.d(TAG, "onReceive: " + intent); } switch (intent.getAction()) { case Intent.ACTION_SCREEN_ON: case Intent.ACTION_SCREEN_OFF: if (!isEnabled()) { updateBatterySavingStats(); 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); break; case Intent.ACTION_BATTERY_CHANGED: synchronized (mLock) { mIsPluggedIn = (intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0); } // Fall-through. case PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED: case PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED: updateBatterySavingStats(); break; } } }; Loading @@ -126,6 +148,7 @@ public class BatterySaverController implements BatterySaverPolicyListener { mBatterySaverPolicy = policy; mBatterySaverPolicy.addListener(this); mFileUpdater = new FileUpdater(context); mBatterySavingStats = BatterySavingStats.getInstance(); // Initialize plugins. final ArrayList<Plugin> plugins = new ArrayList<>(); Loading @@ -149,6 +172,9 @@ public class BatterySaverController implements BatterySaverPolicyListener { public void systemReady() { final IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON); filter.addAction(Intent.ACTION_SCREEN_OFF); filter.addAction(Intent.ACTION_BATTERY_CHANGED); filter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED); filter.addAction(PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED); mContext.registerReceiver(mReceiver, filter); mFileUpdater.systemReady(LocalServices.getService(ActivityManagerInternal.class) Loading Loading @@ -280,7 +306,6 @@ public class BatterySaverController implements BatterySaverPolicyListener { enabled = mEnabled; mIsInteractive = isInteractive; if (enabled) { fileValues = mBatterySaverPolicy.getFileValues(isInteractive); } else { Loading @@ -293,6 +318,8 @@ public class BatterySaverController implements BatterySaverPolicyListener { pmi.powerHint(PowerHint.LOW_POWER, enabled ? 1 : 0); } updateBatterySavingStats(); if (ArrayUtils.isEmpty(fileValues)) { mFileUpdater.restoreDefault(); } else { Loading Loading @@ -332,7 +359,6 @@ public class BatterySaverController implements BatterySaverPolicyListener { mContext.sendBroadcastAsUser(intent, UserHandle.ALL, Manifest.permission.DEVICE_POWER); for (LowPowerModeListener listener : listeners) { final PowerSaveState result = mBatterySaverPolicy.getBatterySaverPolicy( Loading Loading @@ -388,4 +414,28 @@ public class BatterySaverController implements BatterySaverPolicyListener { foregroundUser); } } private void updateBatterySavingStats() { final PowerManager pm = getPowerManager(); if (pm == null) { Slog.wtf(TAG, "PowerManager not initialized"); return; } final boolean isInteractive = pm.isInteractive(); final int dozeMode = pm.isDeviceIdleMode() ? DozeState.DEEP : pm.isLightDeviceIdleMode() ? DozeState.LIGHT : DozeState.NOT_DOZING; synchronized (mLock) { if (mIsPluggedIn) { mBatterySavingStats.startCharging(); return; } mBatterySavingStats.transitionState( mEnabled ? BatterySaverState.ON : BatterySaverState.OFF, isInteractive ? InteractiveState.INTERACTIVE : InteractiveState.NON_INTERACTIVE, dozeMode); } } } Loading
core/java/android/os/BatteryManagerInternal.java +37 −0 Original line number Diff line number Diff line Loading @@ -24,26 +24,63 @@ package android.os; public abstract class BatteryManagerInternal { /** * Returns true if the device is plugged into any of the specified plug types. * * This is a simple accessor that's safe to be called from any locks, but internally it may * wait on the battery service lock. */ public abstract boolean isPowered(int plugTypeSet); /** * Returns the current plug type. * * This is a simple accessor that's safe to be called from any locks, but internally it may * wait on the battery service lock. */ public abstract int getPlugType(); /** * Returns battery level as a percentage. * * This is a simple accessor that's safe to be called from any locks, but internally it may * wait on the battery service lock. */ public abstract int getBatteryLevel(); /** * Instantaneous battery capacity in uA-h, as defined in the HealthInfo HAL struct. * Please note apparently it could be bigger than {@link #getBatteryFullCharge}. * * This is a simple accessor that's safe to be called from any locks, but internally it may * wait on the battery service lock. * * @see android.hardware.health.V1_0.HealthInfo#batteryChargeCounter */ public abstract int getBatteryChargeCounter(); /** * Battery charge value when it is considered to be "full" in uA-h , as defined in the * HealthInfo HAL struct. * * This is a simple accessor that's safe to be called from any locks, but internally it may * wait on the battery service lock. * * @see android.hardware.health.V1_0.HealthInfo#batteryFullCharge */ public abstract int getBatteryFullCharge(); /** * Returns whether we currently consider the battery level to be low. * * This is a simple accessor that's safe to be called from any locks, but internally it may * wait on the battery service lock. */ public abstract boolean getBatteryLevelLow(); /** * Returns a non-zero value if an unsupported charger is attached. * * This is a simple accessor that's safe to be called from any locks, but internally it may * wait on the battery service lock. */ public abstract int getInvalidCharger(); }
services/core/java/com/android/server/BatteryService.java +17 −0 Original line number Diff line number Diff line Loading @@ -835,6 +835,9 @@ public final class BatteryService extends SystemService { case "level": mHealthInfo.batteryLevel = Integer.parseInt(value); break; case "counter": mHealthInfo.batteryChargeCounter = Integer.parseInt(value); break; case "temp": mHealthInfo.batteryTemperature = Integer.parseInt(value); break; Loading Loading @@ -1163,6 +1166,20 @@ public final class BatteryService extends SystemService { } } @Override public int getBatteryChargeCounter() { synchronized (mLock) { return mHealthInfo.batteryChargeCounter; } } @Override public int getBatteryFullCharge() { synchronized (mLock) { return mHealthInfo.batteryFullCharge; } } @Override public boolean getBatteryLevelLow() { synchronized (mLock) { Loading
services/core/java/com/android/server/EventLogTags.logtags +1 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ option java_package com.android.server 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) 27390 battery_saving_stats (batterySaver|1|5),(interactive|1|5),(doze|1|5),(delta_duration|2|3),(delta_battery_drain|1|6),(total_duration|2|3),(total_battery_drain|1|6) # # Leave IDs through 2740 for more power logs (2730 used by battery_discharge above) Loading
services/core/java/com/android/server/power/BatterySaverPolicy.java +3 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import android.util.Slog; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.server.power.batterysaver.BatterySavingStats; import com.android.server.power.batterysaver.CpuFrequencies; import java.io.PrintWriter; Loading Loading @@ -498,6 +499,8 @@ public class BatterySaverPolicy extends ContentObserver { pw.print(" Noninteractive File values:\n"); dumpMap(pw, " ", mFilesForNoninteractive); pw.println(); pw.println(); BatterySavingStats.getInstance().dump(pw, " "); } } Loading
services/core/java/com/android/server/power/batterysaver/BatterySaverController.java +52 −2 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.hardware.power.V1_0.PowerHint; import android.net.Uri; import android.os.BatteryManager; import android.os.Handler; import android.os.Looper; import android.os.Message; Loading @@ -50,6 +51,9 @@ import com.android.server.LocalServices; import com.android.server.power.BatterySaverPolicy; import com.android.server.power.BatterySaverPolicy.BatterySaverPolicyListener; import com.android.server.power.PowerManagerService; import com.android.server.power.batterysaver.BatterySavingStats.BatterySaverState; import com.android.server.power.batterysaver.BatterySavingStats.DozeState; import com.android.server.power.batterysaver.BatterySavingStats.InteractiveState; import java.util.ArrayList; Loading @@ -70,6 +74,8 @@ public class BatterySaverController implements BatterySaverPolicyListener { private final BatterySaverPolicy mBatterySaverPolicy; private final BatterySavingStats mBatterySavingStats; private static final String WARNING_LINK_URL = "http://goto.google.com/extreme-battery-saver"; @GuardedBy("mLock") Loading @@ -78,6 +84,9 @@ public class BatterySaverController implements BatterySaverPolicyListener { @GuardedBy("mLock") private boolean mEnabled; @GuardedBy("mLock") private boolean mIsPluggedIn; /** * Previously enabled or not; only for the event logging. Only use it from * {@link #handleBatterySaverStateChanged}. Loading @@ -104,15 +113,28 @@ public class BatterySaverController implements BatterySaverPolicyListener { private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (DEBUG) { Slog.d(TAG, "onReceive: " + intent); } switch (intent.getAction()) { case Intent.ACTION_SCREEN_ON: case Intent.ACTION_SCREEN_OFF: if (!isEnabled()) { updateBatterySavingStats(); 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); break; case Intent.ACTION_BATTERY_CHANGED: synchronized (mLock) { mIsPluggedIn = (intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0); } // Fall-through. case PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED: case PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED: updateBatterySavingStats(); break; } } }; Loading @@ -126,6 +148,7 @@ public class BatterySaverController implements BatterySaverPolicyListener { mBatterySaverPolicy = policy; mBatterySaverPolicy.addListener(this); mFileUpdater = new FileUpdater(context); mBatterySavingStats = BatterySavingStats.getInstance(); // Initialize plugins. final ArrayList<Plugin> plugins = new ArrayList<>(); Loading @@ -149,6 +172,9 @@ public class BatterySaverController implements BatterySaverPolicyListener { public void systemReady() { final IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON); filter.addAction(Intent.ACTION_SCREEN_OFF); filter.addAction(Intent.ACTION_BATTERY_CHANGED); filter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED); filter.addAction(PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED); mContext.registerReceiver(mReceiver, filter); mFileUpdater.systemReady(LocalServices.getService(ActivityManagerInternal.class) Loading Loading @@ -280,7 +306,6 @@ public class BatterySaverController implements BatterySaverPolicyListener { enabled = mEnabled; mIsInteractive = isInteractive; if (enabled) { fileValues = mBatterySaverPolicy.getFileValues(isInteractive); } else { Loading @@ -293,6 +318,8 @@ public class BatterySaverController implements BatterySaverPolicyListener { pmi.powerHint(PowerHint.LOW_POWER, enabled ? 1 : 0); } updateBatterySavingStats(); if (ArrayUtils.isEmpty(fileValues)) { mFileUpdater.restoreDefault(); } else { Loading Loading @@ -332,7 +359,6 @@ public class BatterySaverController implements BatterySaverPolicyListener { mContext.sendBroadcastAsUser(intent, UserHandle.ALL, Manifest.permission.DEVICE_POWER); for (LowPowerModeListener listener : listeners) { final PowerSaveState result = mBatterySaverPolicy.getBatterySaverPolicy( Loading Loading @@ -388,4 +414,28 @@ public class BatterySaverController implements BatterySaverPolicyListener { foregroundUser); } } private void updateBatterySavingStats() { final PowerManager pm = getPowerManager(); if (pm == null) { Slog.wtf(TAG, "PowerManager not initialized"); return; } final boolean isInteractive = pm.isInteractive(); final int dozeMode = pm.isDeviceIdleMode() ? DozeState.DEEP : pm.isLightDeviceIdleMode() ? DozeState.LIGHT : DozeState.NOT_DOZING; synchronized (mLock) { if (mIsPluggedIn) { mBatterySavingStats.startCharging(); return; } mBatterySavingStats.transitionState( mEnabled ? BatterySaverState.ON : BatterySaverState.OFF, isInteractive ? InteractiveState.INTERACTIVE : InteractiveState.NON_INTERACTIVE, dozeMode); } } }