BatteryService.java revision 633a1740ce5951ccb5d478ba2795f6f4fada1646
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.server; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.app.IBatteryStats; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.server.am.BatteryStatsService; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.ActivityManagerNative; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ContentResolver; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.BatteryManager; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Binder; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Debug; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ServiceManager; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemClock; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.UEventObserver; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.provider.Checkin; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.provider.Settings; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.EventLog; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileDescriptor; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileInputStream; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileOutputStream; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.PrintWriter; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>BatteryService monitors the charging status, and charge level of the device 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * battery. When these values change this service broadcasts the new values 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to all {@link android.content.BroadcastReceiver IntentReceivers} that are 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * watching the {@link android.content.Intent#ACTION_BATTERY_CHANGED 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * BATTERY_CHANGED} action.</p> 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The new values are stored in the Intent data and can be retrieved by 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * calling {@link android.content.Intent#getExtra Intent.getExtra} with the 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * following keys:</p> 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>"scale" - int, the maximum value for the charge level</p> 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>"level" - int, charge level, from 0 through "scale" inclusive</p> 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>"status" - String, the current charging status.<br /> 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>"health" - String, the current battery health.<br /> 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>"present" - boolean, true if the battery is present<br /> 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>"icon-small" - int, suggested small icon to use for this state</p> 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>"plugged" - int, 0 if the device is not plugged in; 1 if plugged 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * into an AC power adapter; 2 if plugged in via USB.</p> 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>"voltage" - int, current battery voltage in millivolts</p> 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>"temperature" - int, current battery temperature in tenths of 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a degree Centigrade</p> 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>"technology" - String, the type of battery installed, e.g. "Li-ion"</p> 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass BatteryService extends Binder { 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = BatteryService.class.getSimpleName(); 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final boolean LOCAL_LOGV = false; 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final int LOG_BATTERY_LEVEL = 2722; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final int LOG_BATTERY_STATUS = 2723; 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final int LOG_BATTERY_DISCHARGE_STATUS = 2730; 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final int BATTERY_SCALE = 100; // battery capacity is a percentage 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Used locally for determining when to make a last ditch effort to log 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // discharge stats before the device dies. 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int CRITICAL_BATTERY_LEVEL = 4; 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int DUMP_MAX_LENGTH = 24 * 1024; 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String[] DUMPSYS_ARGS = new String[] { "-c", "-u" }; 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String BATTERY_STATS_SERVICE_NAME = "batteryinfo"; 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String DUMPSYS_DATA_PATH = "/data/system/"; 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This should probably be exposed in the API, though it's not critical 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int BATTERY_PLUGGED_NONE = 0; 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Context mContext; 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final IBatteryStats mBatteryStats; 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mAcOnline; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mUsbOnline; 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mBatteryStatus; 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mBatteryHealth; 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mBatteryPresent; 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mBatteryLevel; 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mBatteryVoltage; 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mBatteryTemperature; 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private String mBatteryTechnology; 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mBatteryLevelCritical; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mLastBatteryStatus; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mLastBatteryHealth; 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mLastBatteryPresent; 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mLastBatteryLevel; 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mLastBatteryVoltage; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mLastBatteryTemperature; 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mLastBatteryLevelCritical; 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mPlugType; 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mLastPlugType = -1; // Extra state so we can detect first run 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mDischargeStartTime; 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mDischargeStartLevel; 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public BatteryService(Context context) { 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBatteryStats = BatteryStatsService.getService(); 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUEventObserver.startObserving("SUBSYSTEM=power_supply"); 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // set initial status 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update(); 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean isPowered() { 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // assume we are powered if battery state is unknown so the "stay on while plugged in" option will work. 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mAcOnline || mUsbOnline || mBatteryStatus == BatteryManager.BATTERY_STATUS_UNKNOWN); 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean isPowered(int plugTypeSet) { 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // assume we are powered if battery state is unknown so 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the "stay on while plugged in" option will work. 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBatteryStatus == BatteryManager.BATTERY_STATUS_UNKNOWN) { 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (plugTypeSet == 0) { 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int plugTypeBit = 0; 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAcOnline) { 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project plugTypeBit |= BatteryManager.BATTERY_PLUGGED_AC; 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mUsbOnline) { 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project plugTypeBit |= BatteryManager.BATTERY_PLUGGED_USB; 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (plugTypeSet & plugTypeBit) != 0; 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int getPlugType() { 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mPlugType; 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private UEventObserver mUEventObserver = new UEventObserver() { 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onUEvent(UEventObserver.UEvent event) { 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update(); 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // returns battery level as a percentage 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int getBatteryLevel() { 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBatteryLevel; 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_update(); 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private synchronized final void update() { 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_update(); 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project boolean logOutlier = false; 180105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project long dischargeDuration = 0; 181105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBatteryLevelCritical = mBatteryLevel <= CRITICAL_BATTERY_LEVEL; 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAcOnline) { 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlugType = BatteryManager.BATTERY_PLUGGED_AC; 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (mUsbOnline) { 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlugType = BatteryManager.BATTERY_PLUGGED_USB; 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlugType = BATTERY_PLUGGED_NONE; 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBatteryStatus != mLastBatteryStatus || 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBatteryHealth != mLastBatteryHealth || 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBatteryPresent != mLastBatteryPresent || 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBatteryLevel != mLastBatteryLevel || 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlugType != mLastPlugType || 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBatteryVoltage != mLastBatteryVoltage || 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBatteryTemperature != mLastBatteryTemperature) { 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPlugType != mLastPlugType) { 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mLastPlugType == BATTERY_PLUGGED_NONE) { 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // discharging -> charging 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // There's no value in this data unless we've discharged at least once and the 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // battery level has changed; so don't log until it does. 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDischargeStartTime != 0 && mDischargeStartLevel != mBatteryLevel) { 205105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project dischargeDuration = SystemClock.elapsedRealtime() - mDischargeStartTime; 206105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project logOutlier = true; 207105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project EventLog.writeEvent(LOG_BATTERY_DISCHARGE_STATUS, dischargeDuration, 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDischargeStartLevel, mBatteryLevel); 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // make sure we see a discharge event before logging again 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDischargeStartTime = 0; 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (mPlugType == BATTERY_PLUGGED_NONE) { 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // charging -> discharging or we just powered up 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDischargeStartTime = SystemClock.elapsedRealtime(); 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDischargeStartLevel = mBatteryLevel; 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBatteryStatus != mLastBatteryStatus || 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBatteryHealth != mLastBatteryHealth || 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBatteryPresent != mLastBatteryPresent || 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlugType != mLastPlugType) { 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EventLog.writeEvent(LOG_BATTERY_STATUS, 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBatteryStatus, mBatteryHealth, mBatteryPresent ? 1 : 0, 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlugType, mBatteryTechnology); 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBatteryLevel != mLastBatteryLevel || 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBatteryVoltage != mLastBatteryVoltage || 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBatteryTemperature != mLastBatteryTemperature) { 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EventLog.writeEvent(LOG_BATTERY_LEVEL, 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBatteryLevel, mBatteryVoltage, mBatteryTemperature); 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 232633a1740ce5951ccb5d478ba2795f6f4fada1646Evan Millar if (mBatteryLevel != mLastBatteryLevel && mPlugType == BATTERY_PLUGGED_NONE) { 233633a1740ce5951ccb5d478ba2795f6f4fada1646Evan Millar // If the battery level has changed and we are on battery, update the current level. 234633a1740ce5951ccb5d478ba2795f6f4fada1646Evan Millar // This is used for discharge cycle tracking so this shouldn't be updated while the 235633a1740ce5951ccb5d478ba2795f6f4fada1646Evan Millar // battery is charging. 236633a1740ce5951ccb5d478ba2795f6f4fada1646Evan Millar try { 237633a1740ce5951ccb5d478ba2795f6f4fada1646Evan Millar mBatteryStats.recordCurrentLevel(mBatteryLevel); 238633a1740ce5951ccb5d478ba2795f6f4fada1646Evan Millar } catch (RemoteException e) { 239633a1740ce5951ccb5d478ba2795f6f4fada1646Evan Millar // Should never happen. 240633a1740ce5951ccb5d478ba2795f6f4fada1646Evan Millar } 241633a1740ce5951ccb5d478ba2795f6f4fada1646Evan Millar } 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBatteryLevelCritical && !mLastBatteryLevelCritical && 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlugType == BATTERY_PLUGGED_NONE) { 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We want to make sure we log discharge cycle outliers 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if the battery is about to die. 246105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project dischargeDuration = SystemClock.elapsedRealtime() - mDischargeStartTime; 247105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project logOutlier = true; 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastBatteryStatus = mBatteryStatus; 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastBatteryHealth = mBatteryHealth; 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastBatteryPresent = mBatteryPresent; 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastBatteryLevel = mBatteryLevel; 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastPlugType = mPlugType; 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastBatteryVoltage = mBatteryVoltage; 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastBatteryTemperature = mBatteryTemperature; 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastBatteryLevelCritical = mBatteryLevelCritical; 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendIntent(); 260105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 261105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project // This needs to be done after sendIntent() so that we get the lastest battery stats. 262105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (logOutlier && dischargeDuration != 0) { 263105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project logOutlier(dischargeDuration); 264105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final void sendIntent() { 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Pack up the values and broadcast them to everyone 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED); 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 273105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project mBatteryStats.setOnBattery(mPlugType == BATTERY_PLUGGED_NONE, mBatteryLevel); 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Should never happen. 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int icon = getIcon(mBatteryLevel); 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra("status", mBatteryStatus); 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra("health", mBatteryHealth); 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra("present", mBatteryPresent); 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra("level", mBatteryLevel); 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra("scale", BATTERY_SCALE); 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra("icon-small", icon); 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra("plugged", mPlugType); 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra("voltage", mBatteryVoltage); 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra("temperature", mBatteryTemperature); 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra("technology", mBatteryTechnology); 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (false) { 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "updateBattery level:" + mBatteryLevel + 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " scale:" + BATTERY_SCALE + " status:" + mBatteryStatus + 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " health:" + mBatteryHealth + " present:" + mBatteryPresent + 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " voltage: " + mBatteryVoltage + 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " temperature: " + mBatteryTemperature + 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " technology: " + mBatteryTechnology + 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " AC powered:" + mAcOnline + " USB powered:" + mUsbOnline + 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " icon:" + icon ); 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ActivityManagerNative.broadcastStickyIntent(intent, null); 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final void logBatteryStats() { 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IBinder batteryInfoService = ServiceManager.getService(BATTERY_STATS_SERVICE_NAME); 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (batteryInfoService != null) { 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project byte[] buffer = new byte[DUMP_MAX_LENGTH]; 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project File dumpFile = null; 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FileOutputStream dumpStream = null; 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // dump the service to a file 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dumpFile = new File(DUMPSYS_DATA_PATH + BATTERY_STATS_SERVICE_NAME + ".dump"); 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dumpStream = new FileOutputStream(dumpFile); 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project batteryInfoService.dump(dumpStream.getFD(), DUMPSYS_ARGS); 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dumpStream.getFD().sync(); 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // read dumped file above into buffer truncated to DUMP_MAX_LENGTH 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // and insert into events table. 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int length = (int) Math.min(dumpFile.length(), DUMP_MAX_LENGTH); 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FileInputStream fileInputStream = new FileInputStream(dumpFile); 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int nread = fileInputStream.read(buffer, 0, length); 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (nread > 0) { 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Checkin.logEvent(mContext.getContentResolver(), 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Checkin.Events.Tag.BATTERY_DISCHARGE_INFO, 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new String(buffer, 0, nread)); 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (LOCAL_LOGV) Log.v(TAG, "dumped " + nread + "b from " + 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project batteryInfoService + "to log"); 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (LOCAL_LOGV) Log.v(TAG, "actual dump:" + new String(buffer, 0, nread)); 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "failed to dump service '" + BATTERY_STATS_SERVICE_NAME + 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "':" + e); 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "failed to write dumpsys file: " + e); 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // make sure we clean up 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dumpStream != null) { 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dumpStream.close(); 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "failed to close dumpsys output stream"); 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dumpFile != null && !dumpFile.delete()) { 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "failed to delete temporary dumpsys file: " 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + dumpFile.getAbsolutePath()); 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final void logOutlier(long duration) { 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver cr = mContext.getContentResolver(); 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String dischargeThresholdString = Settings.Gservices.getString(cr, 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Settings.Gservices.BATTERY_DISCHARGE_THRESHOLD); 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String durationThresholdString = Settings.Gservices.getString(cr, 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Settings.Gservices.BATTERY_DISCHARGE_DURATION_THRESHOLD); 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dischargeThresholdString != null && durationThresholdString != null) { 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long durationThreshold = Long.parseLong(durationThresholdString); 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int dischargeThreshold = Integer.parseInt(dischargeThresholdString); 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (duration <= durationThreshold && 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDischargeStartLevel - mBatteryLevel >= dischargeThreshold) { 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the discharge cycle is bad enough we want to know about it. 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project logBatteryStats(); 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (LOCAL_LOGV) Log.v(TAG, "duration threshold: " + durationThreshold + 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " discharge threshold: " + dischargeThreshold); 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (LOCAL_LOGV) Log.v(TAG, "duration: " + duration + " discharge: " + 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (mDischargeStartLevel - mBatteryLevel)); 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (NumberFormatException e) { 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "Invalid DischargeThresholds GService string: " + 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project durationThresholdString + " or " + dischargeThresholdString); 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final int getIcon(int level) { 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBatteryStatus == BatteryManager.BATTERY_STATUS_CHARGING) { 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return com.android.internal.R.drawable.stat_sys_battery_charge; 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (mBatteryStatus == BatteryManager.BATTERY_STATUS_DISCHARGING || 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBatteryStatus == BatteryManager.BATTERY_STATUS_NOT_CHARGING || 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBatteryStatus == BatteryManager.BATTERY_STATUS_FULL) { 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return com.android.internal.R.drawable.stat_sys_battery; 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return com.android.internal.R.drawable.stat_sys_battery_unknown; 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED) { 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println("Permission Denial: can't dump Battery service from from pid=" 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Binder.getCallingPid() 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ", uid=" + Binder.getCallingUid()); 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println("Current Battery Service state:"); 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" AC powered: " + mAcOnline); 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" USB powered: " + mUsbOnline); 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" status: " + mBatteryStatus); 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" health: " + mBatteryHealth); 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" present: " + mBatteryPresent); 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" level: " + mBatteryLevel); 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" scale: " + BATTERY_SCALE); 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" voltage:" + mBatteryVoltage); 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" temperature: " + mBatteryTemperature); 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" technology: " + mBatteryTechnology); 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 420