Loading core/java/android/os/BatteryManager.java +4 −0 Original line number Diff line number Diff line Loading @@ -117,4 +117,8 @@ public class BatteryManager { public static final int BATTERY_PLUGGED_USB = 2; /** Power source is wireless. */ public static final int BATTERY_PLUGGED_WIRELESS = 4; /** @hide */ public static final int BATTERY_PLUGGED_ANY = BATTERY_PLUGGED_AC | BATTERY_PLUGGED_USB | BATTERY_PLUGGED_WIRELESS; } services/java/com/android/server/BatteryService.java +167 −137 Original line number Diff line number Diff line Loading @@ -40,11 +40,9 @@ import android.util.Slog; import java.io.File; import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.util.Arrays; /** Loading @@ -69,12 +67,12 @@ import java.util.Arrays; * a degree Centigrade</p> * <p>"technology" - String, the type of battery installed, e.g. "Li-ion"</p> */ public class BatteryService extends Binder { public final class BatteryService extends Binder { private static final String TAG = BatteryService.class.getSimpleName(); private static final boolean LOCAL_LOGV = false; private static final boolean DEBUG = false; static final int BATTERY_SCALE = 100; // battery capacity is a percentage private static final int BATTERY_SCALE = 100; // battery capacity is a percentage // Used locally for determining when to make a last ditch effort to log // discharge stats before the device dies. Loading @@ -92,6 +90,9 @@ public class BatteryService extends Binder { private final Context mContext; private final IBatteryStats mBatteryStats; private final Object mLock = new Object(); /* Begin native fields: All of these fields are set by native code. */ private boolean mAcOnline; private boolean mUsbOnline; private boolean mWirelessOnline; Loading @@ -103,7 +104,7 @@ public class BatteryService extends Binder { private int mBatteryTemperature; private String mBatteryTechnology; private boolean mBatteryLevelCritical; private int mInvalidCharger; /* End native fields. */ private int mLastBatteryStatus; private int mLastBatteryHealth; Loading @@ -112,6 +113,8 @@ public class BatteryService extends Binder { private int mLastBatteryVoltage; private int mLastBatteryTemperature; private boolean mLastBatteryLevelCritical; private int mInvalidCharger; private int mLastInvalidCharger; private int mLowBatteryWarningLevel; Loading @@ -128,6 +131,8 @@ public class BatteryService extends Binder { private boolean mSentLowBatteryBroadcast = false; private native void native_update(); public BatteryService(Context context, LightsService lights) { mContext = context; mLed = new Led(context, lights); Loading @@ -146,83 +151,74 @@ public class BatteryService extends Binder { // watch for invalid charger messages if the invalid_charger switch exists if (new File("/sys/devices/virtual/switch/invalid_charger/state").exists()) { mInvalidChargerObserver.startObserving("DEVPATH=/devices/virtual/switch/invalid_charger"); mInvalidChargerObserver.startObserving( "DEVPATH=/devices/virtual/switch/invalid_charger"); } // set initial status update(); synchronized (mLock) { updateLocked(); } } public final boolean isPowered() { // assume we are powered if battery state is unknown so the "stay on while plugged in" option will work. return (mAcOnline || mUsbOnline || mWirelessOnline || mBatteryStatus == BatteryManager.BATTERY_STATUS_UNKNOWN); void systemReady() { // check our power situation now that it is safe to display the shutdown dialog. synchronized (mLock) { shutdownIfNoPowerLocked(); shutdownIfOverTempLocked(); } } /** * Returns true if the device is plugged into any of the specified plug types. */ public boolean isPowered(int plugTypeSet) { synchronized (mLock) { return isPoweredLocked(plugTypeSet); } } public final boolean isPowered(int plugTypeSet) { private boolean isPoweredLocked(int plugTypeSet) { // assume we are powered if battery state is unknown so // the "stay on while plugged in" option will work. if (mBatteryStatus == BatteryManager.BATTERY_STATUS_UNKNOWN) { return true; } if (plugTypeSet == 0) { return false; } int plugTypeBit = 0; if (mAcOnline) { plugTypeBit |= BatteryManager.BATTERY_PLUGGED_AC; } if (mUsbOnline) { plugTypeBit |= BatteryManager.BATTERY_PLUGGED_USB; } if (mWirelessOnline) { plugTypeBit |= BatteryManager.BATTERY_PLUGGED_WIRELESS; } return (plugTypeSet & plugTypeBit) != 0; } public final int getPlugType() { return mPlugType; if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_AC) != 0 && mAcOnline) { return true; } private UEventObserver mPowerSupplyObserver = new UEventObserver() { @Override public void onUEvent(UEventObserver.UEvent event) { update(); if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_USB) != 0 && mUsbOnline) { return true; } }; private UEventObserver mInvalidChargerObserver = new UEventObserver() { @Override public void onUEvent(UEventObserver.UEvent event) { int invalidCharger = "1".equals(event.get("SWITCH_STATE")) ? 1 : 0; if (mInvalidCharger != invalidCharger) { mInvalidCharger = invalidCharger; update(); if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_WIRELESS) != 0 && mWirelessOnline) { return true; } return false; } }; // returns battery level as a percentage public final int getBatteryLevel() { /** * Returns battery level as a percentage. */ public int getBatteryLevel() { synchronized (mLock) { return mBatteryLevel; } } // true if battery level is below the first warning threshold public final boolean isBatteryLow() { /** * Returns true if battery level is below the first warning threshold. */ public boolean isBatteryLow() { synchronized (mLock) { return mBatteryPresent && mBatteryLevel <= mLowBatteryWarningLevel; } void systemReady() { // check our power situation now that it is safe to display the shutdown dialog. shutdownIfNoPower(); shutdownIfOverTemp(); } private final void shutdownIfNoPower() { private void shutdownIfNoPowerLocked() { // shut down gracefully if our battery is critically low and we are not powered. // wait until the system has booted before attempting to display the shutdown dialog. if (mBatteryLevel == 0 && !isPowered() && ActivityManagerNative.isSystemReady()) { if (mBatteryLevel == 0 && !isPoweredLocked(BatteryManager.BATTERY_PLUGGED_ANY) && ActivityManagerNative.isSystemReady()) { Intent intent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN); intent.putExtra(Intent.EXTRA_KEY_CONFIRM, false); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); Loading @@ -230,7 +226,7 @@ public class BatteryService extends Binder { } } private final void shutdownIfOverTemp() { private void shutdownIfOverTempLocked() { // shut down gracefully if temperature is too high (> 68.0C by default) // wait until the system has booted before attempting to display the // shutdown dialog. Loading @@ -243,18 +239,19 @@ public class BatteryService extends Binder { } } private native void native_update(); private synchronized final void update() { private void updateLocked() { // Update the values of mAcOnline, et. all. native_update(); processValues(); // Process the new values. processValuesLocked(); } private void processValues() { private void processValuesLocked() { boolean logOutlier = false; long dischargeDuration = 0; mBatteryLevelCritical = mBatteryLevel <= mCriticalBatteryLevel; mBatteryLevelCritical = (mBatteryLevel <= mCriticalBatteryLevel); if (mAcOnline) { mPlugType = BatteryManager.BATTERY_PLUGGED_AC; } else if (mUsbOnline) { Loading @@ -265,6 +262,22 @@ public class BatteryService extends Binder { mPlugType = BATTERY_PLUGGED_NONE; } if (DEBUG) { Slog.d(TAG, "Processing new values: " + "mAcOnline=" + mAcOnline + ", mUsbOnline=" + mUsbOnline + ", mWirelessOnline=" + mWirelessOnline + ", mBatteryStatus=" + mBatteryStatus + ", mBatteryHealth=" + mBatteryHealth + ", mBatteryPresent=" + mBatteryPresent + ", mBatteryLevel=" + mBatteryLevel + ", mBatteryTechnology=" + mBatteryTechnology + ", mBatteryVoltage=" + mBatteryVoltage + ", mBatteryTemperature=" + mBatteryTemperature + ", mBatteryLevelCritical=" + mBatteryLevelCritical + ", mPlugType=" + mPlugType); } // Let the battery stats keep track of the current level. try { mBatteryStats.setBatteryState(mBatteryStatus, mBatteryHealth, Loading @@ -274,8 +287,8 @@ public class BatteryService extends Binder { // Should never happen. } shutdownIfNoPower(); shutdownIfOverTemp(); shutdownIfNoPowerLocked(); shutdownIfOverTempLocked(); if (mBatteryStatus != mLastBatteryStatus || mBatteryHealth != mLastBatteryHealth || Loading Loading @@ -342,7 +355,7 @@ public class BatteryService extends Binder { && mBatteryLevel <= mLowBatteryWarningLevel && (oldPlugged || mLastBatteryLevel > mLowBatteryWarningLevel); sendIntent(); sendIntentLocked(); // Separate broadcast is sent for power connected / not connected // since the standard intent will not wake any applications and some Loading Loading @@ -373,7 +386,7 @@ public class BatteryService extends Binder { // This needs to be done after sendIntent() so that we get the lastest battery stats. if (logOutlier && dischargeDuration != 0) { logOutlier(dischargeDuration); logOutlierLocked(dischargeDuration); } mLastBatteryStatus = mBatteryStatus; Loading @@ -388,13 +401,13 @@ public class BatteryService extends Binder { } } private final void sendIntent() { private void sendIntentLocked() { // Pack up the values and broadcast them to everyone Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING); int icon = getIcon(mBatteryLevel); int icon = getIconLocked(mBatteryLevel); intent.putExtra(BatteryManager.EXTRA_STATUS, mBatteryStatus); intent.putExtra(BatteryManager.EXTRA_HEALTH, mBatteryHealth); Loading @@ -408,22 +421,22 @@ public class BatteryService extends Binder { intent.putExtra(BatteryManager.EXTRA_TECHNOLOGY, mBatteryTechnology); intent.putExtra(BatteryManager.EXTRA_INVALID_CHARGER, mInvalidCharger); if (false) { Slog.d(TAG, "level:" + mBatteryLevel + " scale:" + BATTERY_SCALE + " status:" + mBatteryStatus + " health:" + mBatteryHealth + " present:" + mBatteryPresent + " voltage: " + mBatteryVoltage + " temperature: " + mBatteryTemperature + " technology: " + mBatteryTechnology + " AC powered:" + mAcOnline + " USB powered:" + mUsbOnline + " Wireless powered:" + mWirelessOnline + " icon:" + icon + " invalid charger:" + mInvalidCharger); if (DEBUG) { Slog.d(TAG, "Sending ACTION_BATTERY_CHANGED. level:" + mBatteryLevel + ", scale:" + BATTERY_SCALE + ", status:" + mBatteryStatus + ", health:" + mBatteryHealth + ", present:" + mBatteryPresent + ", voltage: " + mBatteryVoltage + ", temperature: " + mBatteryTemperature + ", technology: " + mBatteryTechnology + ", AC powered:" + mAcOnline + ", USB powered:" + mUsbOnline + ", Wireless powered:" + mWirelessOnline + ", icon:" + icon + ", invalid charger:" + mInvalidCharger); } ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.USER_ALL); } private final void logBatteryStats() { private void logBatteryStatsLocked() { IBinder batteryInfoService = ServiceManager.getService(BATTERY_STATS_SERVICE_NAME); if (batteryInfoService == null) return; Loading Loading @@ -461,7 +474,7 @@ public class BatteryService extends Binder { } } private final void logOutlier(long duration) { private void logOutlierLocked(long duration) { ContentResolver cr = mContext.getContentResolver(); String dischargeThresholdString = Settings.Global.getString(cr, Settings.Global.BATTERY_DISCHARGE_THRESHOLD); Loading @@ -475,11 +488,11 @@ public class BatteryService extends Binder { if (duration <= durationThreshold && mDischargeStartLevel - mBatteryLevel >= dischargeThreshold) { // If the discharge cycle is bad enough we want to know about it. logBatteryStats(); logBatteryStatsLocked(); } if (LOCAL_LOGV) Slog.v(TAG, "duration threshold: " + durationThreshold + if (DEBUG) Slog.v(TAG, "duration threshold: " + durationThreshold + " discharge threshold: " + dischargeThreshold); if (LOCAL_LOGV) Slog.v(TAG, "duration: " + duration + " discharge: " + if (DEBUG) Slog.v(TAG, "duration: " + duration + " discharge: " + (mDischargeStartLevel - mBatteryLevel)); } catch (NumberFormatException e) { Slog.e(TAG, "Invalid DischargeThresholds GService string: " + Loading @@ -489,14 +502,15 @@ public class BatteryService extends Binder { } } private final int getIcon(int level) { private int getIconLocked(int level) { if (mBatteryStatus == BatteryManager.BATTERY_STATUS_CHARGING) { return com.android.internal.R.drawable.stat_sys_battery_charge; } else if (mBatteryStatus == BatteryManager.BATTERY_STATUS_DISCHARGING) { return com.android.internal.R.drawable.stat_sys_battery; } else if (mBatteryStatus == BatteryManager.BATTERY_STATUS_NOT_CHARGING || mBatteryStatus == BatteryManager.BATTERY_STATUS_FULL) { if (isPowered() && mBatteryLevel >= 100) { if (isPoweredLocked(BatteryManager.BATTERY_PLUGGED_ANY) && mBatteryLevel >= 100) { return com.android.internal.R.drawable.stat_sys_battery_charge; } else { return com.android.internal.R.drawable.stat_sys_battery; Loading @@ -517,8 +531,8 @@ public class BatteryService extends Binder { return; } synchronized (mLock) { if (args == null || args.length == 0 || "-a".equals(args[0])) { synchronized (this) { pw.println("Current Battery Service state:"); pw.println(" AC powered: " + mAcOnline); pw.println(" USB powered: " + mUsbOnline); Loading @@ -531,7 +545,6 @@ public class BatteryService extends Binder { pw.println(" voltage:" + mBatteryVoltage); pw.println(" temperature: " + mBatteryTemperature); pw.println(" technology: " + mBatteryTechnology); } } else if (false) { // DO NOT SUBMIT WITH THIS TURNED ON if (args.length == 3 && "set".equals(args[0])) { Loading @@ -555,7 +568,7 @@ public class BatteryService extends Binder { update = false; } if (update) { processValues(); processValuesLocked(); } } catch (NumberFormatException ex) { pw.println("Bad value: " + value); Loading @@ -563,41 +576,58 @@ public class BatteryService extends Binder { } } } } private final UEventObserver mPowerSupplyObserver = new UEventObserver() { @Override public void onUEvent(UEventObserver.UEvent event) { synchronized (mLock) { updateLocked(); } } }; class Led { private LightsService mLightsService; private LightsService.Light mBatteryLight; private final UEventObserver mInvalidChargerObserver = new UEventObserver() { @Override public void onUEvent(UEventObserver.UEvent event) { final int invalidCharger = "1".equals(event.get("SWITCH_STATE")) ? 1 : 0; synchronized (mLock) { if (mInvalidCharger != invalidCharger) { mInvalidCharger = invalidCharger; updateLocked(); } } } }; private int mBatteryLowARGB; private int mBatteryMediumARGB; private int mBatteryFullARGB; private int mBatteryLedOn; private int mBatteryLedOff; private final class Led { private final LightsService.Light mBatteryLight; private boolean mBatteryCharging; private boolean mBatteryLow; private boolean mBatteryFull; private final int mBatteryLowARGB; private final int mBatteryMediumARGB; private final int mBatteryFullARGB; private final int mBatteryLedOn; private final int mBatteryLedOff; Led(Context context, LightsService lights) { mLightsService = lights; public Led(Context context, LightsService lights) { mBatteryLight = lights.getLight(LightsService.LIGHT_ID_BATTERY); mBatteryLowARGB = mContext.getResources().getInteger( mBatteryLowARGB = context.getResources().getInteger( com.android.internal.R.integer.config_notificationsBatteryLowARGB); mBatteryMediumARGB = mContext.getResources().getInteger( mBatteryMediumARGB = context.getResources().getInteger( com.android.internal.R.integer.config_notificationsBatteryMediumARGB); mBatteryFullARGB = mContext.getResources().getInteger( mBatteryFullARGB = context.getResources().getInteger( com.android.internal.R.integer.config_notificationsBatteryFullARGB); mBatteryLedOn = mContext.getResources().getInteger( mBatteryLedOn = context.getResources().getInteger( com.android.internal.R.integer.config_notificationsBatteryLedOn); mBatteryLedOff = mContext.getResources().getInteger( mBatteryLedOff = context.getResources().getInteger( com.android.internal.R.integer.config_notificationsBatteryLedOff); } /** * Synchronize on BatteryService. */ void updateLightsLocked() { public void updateLightsLocked() { final int level = mBatteryLevel; final int status = mBatteryStatus; if (level < mLowBatteryWarningLevel) { Loading services/java/com/android/server/Watchdog.java +2 −1 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.BatteryManager; import android.os.Debug; import android.os.Handler; import android.os.Message; Loading Loading @@ -329,7 +330,7 @@ public class Watchdog extends Thread { * text of why it is not a good time. */ String shouldWeBeBrutalLocked(long curTime) { if (mBattery == null || !mBattery.isPowered()) { if (mBattery == null || !mBattery.isPowered(BatteryManager.BATTERY_PLUGGED_ANY)) { return "battery"; } Loading services/java/com/android/server/power/PowerManagerService.java +6 −1 Original line number Diff line number Diff line Loading @@ -1014,7 +1014,12 @@ public final class PowerManagerService extends IPowerManager.Stub private void updateIsPoweredLocked(int dirty) { if ((dirty & DIRTY_BATTERY_STATE) != 0) { boolean wasPowered = mIsPowered; mIsPowered = mBatteryService.isPowered(); mIsPowered = mBatteryService.isPowered(BatteryManager.BATTERY_PLUGGED_ANY); if (DEBUG) { Slog.d(TAG, "updateIsPoweredLocked: wasPowered=" + wasPowered + ", mIsPowered=" + mIsPowered); } if (wasPowered != mIsPowered) { mDirty |= DIRTY_IS_POWERED; Loading Loading
core/java/android/os/BatteryManager.java +4 −0 Original line number Diff line number Diff line Loading @@ -117,4 +117,8 @@ public class BatteryManager { public static final int BATTERY_PLUGGED_USB = 2; /** Power source is wireless. */ public static final int BATTERY_PLUGGED_WIRELESS = 4; /** @hide */ public static final int BATTERY_PLUGGED_ANY = BATTERY_PLUGGED_AC | BATTERY_PLUGGED_USB | BATTERY_PLUGGED_WIRELESS; }
services/java/com/android/server/BatteryService.java +167 −137 Original line number Diff line number Diff line Loading @@ -40,11 +40,9 @@ import android.util.Slog; import java.io.File; import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.util.Arrays; /** Loading @@ -69,12 +67,12 @@ import java.util.Arrays; * a degree Centigrade</p> * <p>"technology" - String, the type of battery installed, e.g. "Li-ion"</p> */ public class BatteryService extends Binder { public final class BatteryService extends Binder { private static final String TAG = BatteryService.class.getSimpleName(); private static final boolean LOCAL_LOGV = false; private static final boolean DEBUG = false; static final int BATTERY_SCALE = 100; // battery capacity is a percentage private static final int BATTERY_SCALE = 100; // battery capacity is a percentage // Used locally for determining when to make a last ditch effort to log // discharge stats before the device dies. Loading @@ -92,6 +90,9 @@ public class BatteryService extends Binder { private final Context mContext; private final IBatteryStats mBatteryStats; private final Object mLock = new Object(); /* Begin native fields: All of these fields are set by native code. */ private boolean mAcOnline; private boolean mUsbOnline; private boolean mWirelessOnline; Loading @@ -103,7 +104,7 @@ public class BatteryService extends Binder { private int mBatteryTemperature; private String mBatteryTechnology; private boolean mBatteryLevelCritical; private int mInvalidCharger; /* End native fields. */ private int mLastBatteryStatus; private int mLastBatteryHealth; Loading @@ -112,6 +113,8 @@ public class BatteryService extends Binder { private int mLastBatteryVoltage; private int mLastBatteryTemperature; private boolean mLastBatteryLevelCritical; private int mInvalidCharger; private int mLastInvalidCharger; private int mLowBatteryWarningLevel; Loading @@ -128,6 +131,8 @@ public class BatteryService extends Binder { private boolean mSentLowBatteryBroadcast = false; private native void native_update(); public BatteryService(Context context, LightsService lights) { mContext = context; mLed = new Led(context, lights); Loading @@ -146,83 +151,74 @@ public class BatteryService extends Binder { // watch for invalid charger messages if the invalid_charger switch exists if (new File("/sys/devices/virtual/switch/invalid_charger/state").exists()) { mInvalidChargerObserver.startObserving("DEVPATH=/devices/virtual/switch/invalid_charger"); mInvalidChargerObserver.startObserving( "DEVPATH=/devices/virtual/switch/invalid_charger"); } // set initial status update(); synchronized (mLock) { updateLocked(); } } public final boolean isPowered() { // assume we are powered if battery state is unknown so the "stay on while plugged in" option will work. return (mAcOnline || mUsbOnline || mWirelessOnline || mBatteryStatus == BatteryManager.BATTERY_STATUS_UNKNOWN); void systemReady() { // check our power situation now that it is safe to display the shutdown dialog. synchronized (mLock) { shutdownIfNoPowerLocked(); shutdownIfOverTempLocked(); } } /** * Returns true if the device is plugged into any of the specified plug types. */ public boolean isPowered(int plugTypeSet) { synchronized (mLock) { return isPoweredLocked(plugTypeSet); } } public final boolean isPowered(int plugTypeSet) { private boolean isPoweredLocked(int plugTypeSet) { // assume we are powered if battery state is unknown so // the "stay on while plugged in" option will work. if (mBatteryStatus == BatteryManager.BATTERY_STATUS_UNKNOWN) { return true; } if (plugTypeSet == 0) { return false; } int plugTypeBit = 0; if (mAcOnline) { plugTypeBit |= BatteryManager.BATTERY_PLUGGED_AC; } if (mUsbOnline) { plugTypeBit |= BatteryManager.BATTERY_PLUGGED_USB; } if (mWirelessOnline) { plugTypeBit |= BatteryManager.BATTERY_PLUGGED_WIRELESS; } return (plugTypeSet & plugTypeBit) != 0; } public final int getPlugType() { return mPlugType; if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_AC) != 0 && mAcOnline) { return true; } private UEventObserver mPowerSupplyObserver = new UEventObserver() { @Override public void onUEvent(UEventObserver.UEvent event) { update(); if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_USB) != 0 && mUsbOnline) { return true; } }; private UEventObserver mInvalidChargerObserver = new UEventObserver() { @Override public void onUEvent(UEventObserver.UEvent event) { int invalidCharger = "1".equals(event.get("SWITCH_STATE")) ? 1 : 0; if (mInvalidCharger != invalidCharger) { mInvalidCharger = invalidCharger; update(); if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_WIRELESS) != 0 && mWirelessOnline) { return true; } return false; } }; // returns battery level as a percentage public final int getBatteryLevel() { /** * Returns battery level as a percentage. */ public int getBatteryLevel() { synchronized (mLock) { return mBatteryLevel; } } // true if battery level is below the first warning threshold public final boolean isBatteryLow() { /** * Returns true if battery level is below the first warning threshold. */ public boolean isBatteryLow() { synchronized (mLock) { return mBatteryPresent && mBatteryLevel <= mLowBatteryWarningLevel; } void systemReady() { // check our power situation now that it is safe to display the shutdown dialog. shutdownIfNoPower(); shutdownIfOverTemp(); } private final void shutdownIfNoPower() { private void shutdownIfNoPowerLocked() { // shut down gracefully if our battery is critically low and we are not powered. // wait until the system has booted before attempting to display the shutdown dialog. if (mBatteryLevel == 0 && !isPowered() && ActivityManagerNative.isSystemReady()) { if (mBatteryLevel == 0 && !isPoweredLocked(BatteryManager.BATTERY_PLUGGED_ANY) && ActivityManagerNative.isSystemReady()) { Intent intent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN); intent.putExtra(Intent.EXTRA_KEY_CONFIRM, false); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); Loading @@ -230,7 +226,7 @@ public class BatteryService extends Binder { } } private final void shutdownIfOverTemp() { private void shutdownIfOverTempLocked() { // shut down gracefully if temperature is too high (> 68.0C by default) // wait until the system has booted before attempting to display the // shutdown dialog. Loading @@ -243,18 +239,19 @@ public class BatteryService extends Binder { } } private native void native_update(); private synchronized final void update() { private void updateLocked() { // Update the values of mAcOnline, et. all. native_update(); processValues(); // Process the new values. processValuesLocked(); } private void processValues() { private void processValuesLocked() { boolean logOutlier = false; long dischargeDuration = 0; mBatteryLevelCritical = mBatteryLevel <= mCriticalBatteryLevel; mBatteryLevelCritical = (mBatteryLevel <= mCriticalBatteryLevel); if (mAcOnline) { mPlugType = BatteryManager.BATTERY_PLUGGED_AC; } else if (mUsbOnline) { Loading @@ -265,6 +262,22 @@ public class BatteryService extends Binder { mPlugType = BATTERY_PLUGGED_NONE; } if (DEBUG) { Slog.d(TAG, "Processing new values: " + "mAcOnline=" + mAcOnline + ", mUsbOnline=" + mUsbOnline + ", mWirelessOnline=" + mWirelessOnline + ", mBatteryStatus=" + mBatteryStatus + ", mBatteryHealth=" + mBatteryHealth + ", mBatteryPresent=" + mBatteryPresent + ", mBatteryLevel=" + mBatteryLevel + ", mBatteryTechnology=" + mBatteryTechnology + ", mBatteryVoltage=" + mBatteryVoltage + ", mBatteryTemperature=" + mBatteryTemperature + ", mBatteryLevelCritical=" + mBatteryLevelCritical + ", mPlugType=" + mPlugType); } // Let the battery stats keep track of the current level. try { mBatteryStats.setBatteryState(mBatteryStatus, mBatteryHealth, Loading @@ -274,8 +287,8 @@ public class BatteryService extends Binder { // Should never happen. } shutdownIfNoPower(); shutdownIfOverTemp(); shutdownIfNoPowerLocked(); shutdownIfOverTempLocked(); if (mBatteryStatus != mLastBatteryStatus || mBatteryHealth != mLastBatteryHealth || Loading Loading @@ -342,7 +355,7 @@ public class BatteryService extends Binder { && mBatteryLevel <= mLowBatteryWarningLevel && (oldPlugged || mLastBatteryLevel > mLowBatteryWarningLevel); sendIntent(); sendIntentLocked(); // Separate broadcast is sent for power connected / not connected // since the standard intent will not wake any applications and some Loading Loading @@ -373,7 +386,7 @@ public class BatteryService extends Binder { // This needs to be done after sendIntent() so that we get the lastest battery stats. if (logOutlier && dischargeDuration != 0) { logOutlier(dischargeDuration); logOutlierLocked(dischargeDuration); } mLastBatteryStatus = mBatteryStatus; Loading @@ -388,13 +401,13 @@ public class BatteryService extends Binder { } } private final void sendIntent() { private void sendIntentLocked() { // Pack up the values and broadcast them to everyone Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING); int icon = getIcon(mBatteryLevel); int icon = getIconLocked(mBatteryLevel); intent.putExtra(BatteryManager.EXTRA_STATUS, mBatteryStatus); intent.putExtra(BatteryManager.EXTRA_HEALTH, mBatteryHealth); Loading @@ -408,22 +421,22 @@ public class BatteryService extends Binder { intent.putExtra(BatteryManager.EXTRA_TECHNOLOGY, mBatteryTechnology); intent.putExtra(BatteryManager.EXTRA_INVALID_CHARGER, mInvalidCharger); if (false) { Slog.d(TAG, "level:" + mBatteryLevel + " scale:" + BATTERY_SCALE + " status:" + mBatteryStatus + " health:" + mBatteryHealth + " present:" + mBatteryPresent + " voltage: " + mBatteryVoltage + " temperature: " + mBatteryTemperature + " technology: " + mBatteryTechnology + " AC powered:" + mAcOnline + " USB powered:" + mUsbOnline + " Wireless powered:" + mWirelessOnline + " icon:" + icon + " invalid charger:" + mInvalidCharger); if (DEBUG) { Slog.d(TAG, "Sending ACTION_BATTERY_CHANGED. level:" + mBatteryLevel + ", scale:" + BATTERY_SCALE + ", status:" + mBatteryStatus + ", health:" + mBatteryHealth + ", present:" + mBatteryPresent + ", voltage: " + mBatteryVoltage + ", temperature: " + mBatteryTemperature + ", technology: " + mBatteryTechnology + ", AC powered:" + mAcOnline + ", USB powered:" + mUsbOnline + ", Wireless powered:" + mWirelessOnline + ", icon:" + icon + ", invalid charger:" + mInvalidCharger); } ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.USER_ALL); } private final void logBatteryStats() { private void logBatteryStatsLocked() { IBinder batteryInfoService = ServiceManager.getService(BATTERY_STATS_SERVICE_NAME); if (batteryInfoService == null) return; Loading Loading @@ -461,7 +474,7 @@ public class BatteryService extends Binder { } } private final void logOutlier(long duration) { private void logOutlierLocked(long duration) { ContentResolver cr = mContext.getContentResolver(); String dischargeThresholdString = Settings.Global.getString(cr, Settings.Global.BATTERY_DISCHARGE_THRESHOLD); Loading @@ -475,11 +488,11 @@ public class BatteryService extends Binder { if (duration <= durationThreshold && mDischargeStartLevel - mBatteryLevel >= dischargeThreshold) { // If the discharge cycle is bad enough we want to know about it. logBatteryStats(); logBatteryStatsLocked(); } if (LOCAL_LOGV) Slog.v(TAG, "duration threshold: " + durationThreshold + if (DEBUG) Slog.v(TAG, "duration threshold: " + durationThreshold + " discharge threshold: " + dischargeThreshold); if (LOCAL_LOGV) Slog.v(TAG, "duration: " + duration + " discharge: " + if (DEBUG) Slog.v(TAG, "duration: " + duration + " discharge: " + (mDischargeStartLevel - mBatteryLevel)); } catch (NumberFormatException e) { Slog.e(TAG, "Invalid DischargeThresholds GService string: " + Loading @@ -489,14 +502,15 @@ public class BatteryService extends Binder { } } private final int getIcon(int level) { private int getIconLocked(int level) { if (mBatteryStatus == BatteryManager.BATTERY_STATUS_CHARGING) { return com.android.internal.R.drawable.stat_sys_battery_charge; } else if (mBatteryStatus == BatteryManager.BATTERY_STATUS_DISCHARGING) { return com.android.internal.R.drawable.stat_sys_battery; } else if (mBatteryStatus == BatteryManager.BATTERY_STATUS_NOT_CHARGING || mBatteryStatus == BatteryManager.BATTERY_STATUS_FULL) { if (isPowered() && mBatteryLevel >= 100) { if (isPoweredLocked(BatteryManager.BATTERY_PLUGGED_ANY) && mBatteryLevel >= 100) { return com.android.internal.R.drawable.stat_sys_battery_charge; } else { return com.android.internal.R.drawable.stat_sys_battery; Loading @@ -517,8 +531,8 @@ public class BatteryService extends Binder { return; } synchronized (mLock) { if (args == null || args.length == 0 || "-a".equals(args[0])) { synchronized (this) { pw.println("Current Battery Service state:"); pw.println(" AC powered: " + mAcOnline); pw.println(" USB powered: " + mUsbOnline); Loading @@ -531,7 +545,6 @@ public class BatteryService extends Binder { pw.println(" voltage:" + mBatteryVoltage); pw.println(" temperature: " + mBatteryTemperature); pw.println(" technology: " + mBatteryTechnology); } } else if (false) { // DO NOT SUBMIT WITH THIS TURNED ON if (args.length == 3 && "set".equals(args[0])) { Loading @@ -555,7 +568,7 @@ public class BatteryService extends Binder { update = false; } if (update) { processValues(); processValuesLocked(); } } catch (NumberFormatException ex) { pw.println("Bad value: " + value); Loading @@ -563,41 +576,58 @@ public class BatteryService extends Binder { } } } } private final UEventObserver mPowerSupplyObserver = new UEventObserver() { @Override public void onUEvent(UEventObserver.UEvent event) { synchronized (mLock) { updateLocked(); } } }; class Led { private LightsService mLightsService; private LightsService.Light mBatteryLight; private final UEventObserver mInvalidChargerObserver = new UEventObserver() { @Override public void onUEvent(UEventObserver.UEvent event) { final int invalidCharger = "1".equals(event.get("SWITCH_STATE")) ? 1 : 0; synchronized (mLock) { if (mInvalidCharger != invalidCharger) { mInvalidCharger = invalidCharger; updateLocked(); } } } }; private int mBatteryLowARGB; private int mBatteryMediumARGB; private int mBatteryFullARGB; private int mBatteryLedOn; private int mBatteryLedOff; private final class Led { private final LightsService.Light mBatteryLight; private boolean mBatteryCharging; private boolean mBatteryLow; private boolean mBatteryFull; private final int mBatteryLowARGB; private final int mBatteryMediumARGB; private final int mBatteryFullARGB; private final int mBatteryLedOn; private final int mBatteryLedOff; Led(Context context, LightsService lights) { mLightsService = lights; public Led(Context context, LightsService lights) { mBatteryLight = lights.getLight(LightsService.LIGHT_ID_BATTERY); mBatteryLowARGB = mContext.getResources().getInteger( mBatteryLowARGB = context.getResources().getInteger( com.android.internal.R.integer.config_notificationsBatteryLowARGB); mBatteryMediumARGB = mContext.getResources().getInteger( mBatteryMediumARGB = context.getResources().getInteger( com.android.internal.R.integer.config_notificationsBatteryMediumARGB); mBatteryFullARGB = mContext.getResources().getInteger( mBatteryFullARGB = context.getResources().getInteger( com.android.internal.R.integer.config_notificationsBatteryFullARGB); mBatteryLedOn = mContext.getResources().getInteger( mBatteryLedOn = context.getResources().getInteger( com.android.internal.R.integer.config_notificationsBatteryLedOn); mBatteryLedOff = mContext.getResources().getInteger( mBatteryLedOff = context.getResources().getInteger( com.android.internal.R.integer.config_notificationsBatteryLedOff); } /** * Synchronize on BatteryService. */ void updateLightsLocked() { public void updateLightsLocked() { final int level = mBatteryLevel; final int status = mBatteryStatus; if (level < mLowBatteryWarningLevel) { Loading
services/java/com/android/server/Watchdog.java +2 −1 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.BatteryManager; import android.os.Debug; import android.os.Handler; import android.os.Message; Loading Loading @@ -329,7 +330,7 @@ public class Watchdog extends Thread { * text of why it is not a good time. */ String shouldWeBeBrutalLocked(long curTime) { if (mBattery == null || !mBattery.isPowered()) { if (mBattery == null || !mBattery.isPowered(BatteryManager.BATTERY_PLUGGED_ANY)) { return "battery"; } Loading
services/java/com/android/server/power/PowerManagerService.java +6 −1 Original line number Diff line number Diff line Loading @@ -1014,7 +1014,12 @@ public final class PowerManagerService extends IPowerManager.Stub private void updateIsPoweredLocked(int dirty) { if ((dirty & DIRTY_BATTERY_STATE) != 0) { boolean wasPowered = mIsPowered; mIsPowered = mBatteryService.isPowered(); mIsPowered = mBatteryService.isPowered(BatteryManager.BATTERY_PLUGGED_ANY); if (DEBUG) { Slog.d(TAG, "updateIsPoweredLocked: wasPowered=" + wasPowered + ", mIsPowered=" + mIsPowered); } if (wasPowered != mIsPowered) { mDirty |= DIRTY_IS_POWERED; Loading