BatteryService.java revision 07a500f0de2243b832e258ed477652a10cbd2d08
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 * <p>BatteryService monitors the charging status, and charge level of the device 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * battery. When these values change this service broadcasts the new values 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to all {@link android.content.BroadcastReceiver IntentReceivers} that are 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * watching the {@link android.content.Intent#ACTION_BATTERY_CHANGED 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * BATTERY_CHANGED} action.</p> 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The new values are stored in the Intent data and can be retrieved by 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * calling {@link android.content.Intent#getExtra Intent.getExtra} with the 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * following keys:</p> 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>"scale" - int, the maximum value for the charge level</p> 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>"level" - int, charge level, from 0 through "scale" inclusive</p> 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>"status" - String, the current charging status.<br /> 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>"health" - String, the current battery health.<br /> 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>"present" - boolean, true if the battery is present<br /> 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>"icon-small" - int, suggested small icon to use for this state</p> 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>"plugged" - int, 0 if the device is not plugged in; 1 if plugged 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * into an AC power adapter; 2 if plugged in via USB.</p> 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>"voltage" - int, current battery voltage in millivolts</p> 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>"temperature" - int, current battery temperature in tenths of 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a degree Centigrade</p> 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>"technology" - String, the type of battery installed, e.g. "Li-ion"</p> 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass BatteryService extends Binder { 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = BatteryService.class.getSimpleName(); 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final boolean LOCAL_LOGV = false; 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final int LOG_BATTERY_LEVEL = 2722; 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final int LOG_BATTERY_STATUS = 2723; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final int LOG_BATTERY_DISCHARGE_STATUS = 2730; 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final int BATTERY_SCALE = 100; // battery capacity is a percentage 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Used locally for determining when to make a last ditch effort to log 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // discharge stats before the device dies. 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int CRITICAL_BATTERY_LEVEL = 4; 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int DUMP_MAX_LENGTH = 24 * 1024; 866447ca30b8e41c22c7214f201120327057e356dcDianne Hackborn private static final String[] DUMPSYS_ARGS = new String[] { "--checkin", "-u" }; 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String BATTERY_STATS_SERVICE_NAME = "batteryinfo"; 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String DUMPSYS_DATA_PATH = "/data/system/"; 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This should probably be exposed in the API, though it's not critical 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int BATTERY_PLUGGED_NONE = 0; 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 948ec5b83fc8f8aa68805c4d5987f8f75bb28250caDianne Hackborn private static final int BATTERY_LEVEL_CLOSE_WARNING = 20; 95a82842f98d64897e92e1012404863f940bd03d26Mihai Preda private static final int BATTERY_LEVEL_WARNING = 15; 96a82842f98d64897e92e1012404863f940bd03d26Mihai Preda 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Context mContext; 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final IBatteryStats mBatteryStats; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mAcOnline; 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mUsbOnline; 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mBatteryStatus; 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mBatteryHealth; 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mBatteryPresent; 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mBatteryLevel; 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mBatteryVoltage; 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mBatteryTemperature; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private String mBatteryTechnology; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mBatteryLevelCritical; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mLastBatteryStatus; 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mLastBatteryHealth; 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mLastBatteryPresent; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mLastBatteryLevel; 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mLastBatteryVoltage; 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mLastBatteryTemperature; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mLastBatteryLevelCritical; 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mPlugType; 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mLastPlugType = -1; // Extra state so we can detect first run 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mDischargeStartTime; 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mDischargeStartLevel; 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1258ec5b83fc8f8aa68805c4d5987f8f75bb28250caDianne Hackborn private boolean mSentLowBatteryBroadcast = false; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public BatteryService(Context context) { 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBatteryStats = BatteryStatsService.getService(); 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUEventObserver.startObserving("SUBSYSTEM=power_supply"); 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // set initial status 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update(); 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean isPowered() { 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // assume we are powered if battery state is unknown so the "stay on while plugged in" option will work. 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (mAcOnline || mUsbOnline || mBatteryStatus == BatteryManager.BATTERY_STATUS_UNKNOWN); 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean isPowered(int plugTypeSet) { 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // assume we are powered if battery state is unknown so 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the "stay on while plugged in" option will work. 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBatteryStatus == BatteryManager.BATTERY_STATUS_UNKNOWN) { 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (plugTypeSet == 0) { 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int plugTypeBit = 0; 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAcOnline) { 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project plugTypeBit |= BatteryManager.BATTERY_PLUGGED_AC; 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mUsbOnline) { 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project plugTypeBit |= BatteryManager.BATTERY_PLUGGED_USB; 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (plugTypeSet & plugTypeBit) != 0; 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int getPlugType() { 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mPlugType; 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private UEventObserver mUEventObserver = new UEventObserver() { 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onUEvent(UEventObserver.UEvent event) { 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project update(); 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // returns battery level as a percentage 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int getBatteryLevel() { 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBatteryLevel; 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17707a500f0de2243b832e258ed477652a10cbd2d08Mike Lockwood void systemReady() { 17807a500f0de2243b832e258ed477652a10cbd2d08Mike Lockwood // check our power situation now that it is safe to display the shutdown dialog. 17907a500f0de2243b832e258ed477652a10cbd2d08Mike Lockwood shutdownIfNoPower(); 18007a500f0de2243b832e258ed477652a10cbd2d08Mike Lockwood } 18107a500f0de2243b832e258ed477652a10cbd2d08Mike Lockwood 18207a500f0de2243b832e258ed477652a10cbd2d08Mike Lockwood private final void shutdownIfNoPower() { 18307a500f0de2243b832e258ed477652a10cbd2d08Mike Lockwood // shut down gracefully if our battery is critically low and we are not powered. 18407a500f0de2243b832e258ed477652a10cbd2d08Mike Lockwood // wait until the system has booted before attempting to display the shutdown dialog. 18507a500f0de2243b832e258ed477652a10cbd2d08Mike Lockwood if (mBatteryLevel == 0 && !isPowered() && ActivityManagerNative.isSystemReady()) { 18607a500f0de2243b832e258ed477652a10cbd2d08Mike Lockwood Intent intent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN); 18707a500f0de2243b832e258ed477652a10cbd2d08Mike Lockwood intent.putExtra(Intent.EXTRA_KEY_CONFIRM, false); 18807a500f0de2243b832e258ed477652a10cbd2d08Mike Lockwood intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 18907a500f0de2243b832e258ed477652a10cbd2d08Mike Lockwood mContext.startActivity(intent); 19007a500f0de2243b832e258ed477652a10cbd2d08Mike Lockwood } 19107a500f0de2243b832e258ed477652a10cbd2d08Mike Lockwood } 19207a500f0de2243b832e258ed477652a10cbd2d08Mike Lockwood 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_update(); 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private synchronized final void update() { 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_update(); 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 198105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project boolean logOutlier = false; 199105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project long dischargeDuration = 0; 200a7e4cf9b5c9dd7d733e1ee7109ecb0e58996fe06Joe Onorato 20107a500f0de2243b832e258ed477652a10cbd2d08Mike Lockwood shutdownIfNoPower(); 20207a500f0de2243b832e258ed477652a10cbd2d08Mike Lockwood 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBatteryLevelCritical = mBatteryLevel <= CRITICAL_BATTERY_LEVEL; 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAcOnline) { 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlugType = BatteryManager.BATTERY_PLUGGED_AC; 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (mUsbOnline) { 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlugType = BatteryManager.BATTERY_PLUGGED_USB; 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlugType = BATTERY_PLUGGED_NONE; 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBatteryStatus != mLastBatteryStatus || 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBatteryHealth != mLastBatteryHealth || 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBatteryPresent != mLastBatteryPresent || 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBatteryLevel != mLastBatteryLevel || 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlugType != mLastPlugType || 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBatteryVoltage != mLastBatteryVoltage || 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBatteryTemperature != mLastBatteryTemperature) { 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPlugType != mLastPlugType) { 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mLastPlugType == BATTERY_PLUGGED_NONE) { 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // discharging -> charging 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // There's no value in this data unless we've discharged at least once and the 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // battery level has changed; so don't log until it does. 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDischargeStartTime != 0 && mDischargeStartLevel != mBatteryLevel) { 226105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project dischargeDuration = SystemClock.elapsedRealtime() - mDischargeStartTime; 227105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project logOutlier = true; 228105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project EventLog.writeEvent(LOG_BATTERY_DISCHARGE_STATUS, dischargeDuration, 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDischargeStartLevel, mBatteryLevel); 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // make sure we see a discharge event before logging again 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDischargeStartTime = 0; 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (mPlugType == BATTERY_PLUGGED_NONE) { 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // charging -> discharging or we just powered up 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDischargeStartTime = SystemClock.elapsedRealtime(); 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDischargeStartLevel = mBatteryLevel; 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBatteryStatus != mLastBatteryStatus || 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBatteryHealth != mLastBatteryHealth || 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBatteryPresent != mLastBatteryPresent || 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlugType != mLastPlugType) { 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EventLog.writeEvent(LOG_BATTERY_STATUS, 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBatteryStatus, mBatteryHealth, mBatteryPresent ? 1 : 0, 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlugType, mBatteryTechnology); 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBatteryLevel != mLastBatteryLevel || 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBatteryVoltage != mLastBatteryVoltage || 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBatteryTemperature != mLastBatteryTemperature) { 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EventLog.writeEvent(LOG_BATTERY_LEVEL, 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBatteryLevel, mBatteryVoltage, mBatteryTemperature); 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 253633a1740ce5951ccb5d478ba2795f6f4fada1646Evan Millar if (mBatteryLevel != mLastBatteryLevel && mPlugType == BATTERY_PLUGGED_NONE) { 254633a1740ce5951ccb5d478ba2795f6f4fada1646Evan Millar // If the battery level has changed and we are on battery, update the current level. 255633a1740ce5951ccb5d478ba2795f6f4fada1646Evan Millar // This is used for discharge cycle tracking so this shouldn't be updated while the 256633a1740ce5951ccb5d478ba2795f6f4fada1646Evan Millar // battery is charging. 257633a1740ce5951ccb5d478ba2795f6f4fada1646Evan Millar try { 258633a1740ce5951ccb5d478ba2795f6f4fada1646Evan Millar mBatteryStats.recordCurrentLevel(mBatteryLevel); 259633a1740ce5951ccb5d478ba2795f6f4fada1646Evan Millar } catch (RemoteException e) { 260633a1740ce5951ccb5d478ba2795f6f4fada1646Evan Millar // Should never happen. 261633a1740ce5951ccb5d478ba2795f6f4fada1646Evan Millar } 262633a1740ce5951ccb5d478ba2795f6f4fada1646Evan Millar } 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBatteryLevelCritical && !mLastBatteryLevelCritical && 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlugType == BATTERY_PLUGGED_NONE) { 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We want to make sure we log discharge cycle outliers 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if the battery is about to die. 267105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project dischargeDuration = SystemClock.elapsedRealtime() - mDischargeStartTime; 268105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project logOutlier = true; 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27106ba55476ee9703c876d223cd41bd73c5f85f42dChristopher Tate // Separate broadcast is sent for power connected / not connected 27206ba55476ee9703c876d223cd41bd73c5f85f42dChristopher Tate // since the standard intent will not wake any applications and some 27306ba55476ee9703c876d223cd41bd73c5f85f42dChristopher Tate // applications may want to have smart behavior based on this. 27493dc9fe96192dbe6f974ca5d1c7c1102eb4b325aChristopher Tate Intent statusIntent = new Intent(); 27593dc9fe96192dbe6f974ca5d1c7c1102eb4b325aChristopher Tate statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 27606ba55476ee9703c876d223cd41bd73c5f85f42dChristopher Tate if (mPlugType != 0 && mLastPlugType == 0) { 27793dc9fe96192dbe6f974ca5d1c7c1102eb4b325aChristopher Tate statusIntent.setAction(Intent.ACTION_POWER_CONNECTED); 27893dc9fe96192dbe6f974ca5d1c7c1102eb4b325aChristopher Tate mContext.sendBroadcast(statusIntent); 27906ba55476ee9703c876d223cd41bd73c5f85f42dChristopher Tate } 28006ba55476ee9703c876d223cd41bd73c5f85f42dChristopher Tate else if (mPlugType == 0 && mLastPlugType != 0) { 28193dc9fe96192dbe6f974ca5d1c7c1102eb4b325aChristopher Tate statusIntent.setAction(Intent.ACTION_POWER_DISCONNECTED); 28293dc9fe96192dbe6f974ca5d1c7c1102eb4b325aChristopher Tate mContext.sendBroadcast(statusIntent); 28306ba55476ee9703c876d223cd41bd73c5f85f42dChristopher Tate } 284a82842f98d64897e92e1012404863f940bd03d26Mihai Preda 285a82842f98d64897e92e1012404863f940bd03d26Mihai Preda final boolean plugged = mPlugType != BATTERY_PLUGGED_NONE; 286a82842f98d64897e92e1012404863f940bd03d26Mihai Preda final boolean oldPlugged = mLastPlugType != BATTERY_PLUGGED_NONE; 287a82842f98d64897e92e1012404863f940bd03d26Mihai Preda 288a82842f98d64897e92e1012404863f940bd03d26Mihai Preda /* The ACTION_BATTERY_LOW broadcast is sent in these situations: 289a82842f98d64897e92e1012404863f940bd03d26Mihai Preda * - is just un-plugged (previously was plugged) and battery level is under WARNING, or 290a82842f98d64897e92e1012404863f940bd03d26Mihai Preda * - is not plugged and battery level crosses the WARNING boundary (becomes < 15). 291a82842f98d64897e92e1012404863f940bd03d26Mihai Preda */ 292a82842f98d64897e92e1012404863f940bd03d26Mihai Preda final boolean sendBatteryLow = !plugged 29347ee3bc78e6e44230f36ea1e850c3d55d4a07b57Rebecca Schultz Zavin && mBatteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN 294a82842f98d64897e92e1012404863f940bd03d26Mihai Preda && mBatteryLevel < BATTERY_LEVEL_WARNING 295a82842f98d64897e92e1012404863f940bd03d26Mihai Preda && (oldPlugged || mLastBatteryLevel >= BATTERY_LEVEL_WARNING); 29606ba55476ee9703c876d223cd41bd73c5f85f42dChristopher Tate 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastBatteryStatus = mBatteryStatus; 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastBatteryHealth = mBatteryHealth; 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastBatteryPresent = mBatteryPresent; 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastBatteryLevel = mBatteryLevel; 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastPlugType = mPlugType; 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastBatteryVoltage = mBatteryVoltage; 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastBatteryTemperature = mBatteryTemperature; 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastBatteryLevelCritical = mBatteryLevelCritical; 305a82842f98d64897e92e1012404863f940bd03d26Mihai Preda 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sendIntent(); 307a82842f98d64897e92e1012404863f940bd03d26Mihai Preda if (sendBatteryLow) { 3088ec5b83fc8f8aa68805c4d5987f8f75bb28250caDianne Hackborn mSentLowBatteryBroadcast = true; 30993dc9fe96192dbe6f974ca5d1c7c1102eb4b325aChristopher Tate statusIntent.setAction(Intent.ACTION_BATTERY_LOW); 31093dc9fe96192dbe6f974ca5d1c7c1102eb4b325aChristopher Tate mContext.sendBroadcast(statusIntent); 3118ec5b83fc8f8aa68805c4d5987f8f75bb28250caDianne Hackborn } else if (mSentLowBatteryBroadcast && mLastBatteryLevel >= BATTERY_LEVEL_CLOSE_WARNING) { 3128ec5b83fc8f8aa68805c4d5987f8f75bb28250caDianne Hackborn mSentLowBatteryBroadcast = false; 31393dc9fe96192dbe6f974ca5d1c7c1102eb4b325aChristopher Tate statusIntent.setAction(Intent.ACTION_BATTERY_OKAY); 31493dc9fe96192dbe6f974ca5d1c7c1102eb4b325aChristopher Tate mContext.sendBroadcast(statusIntent); 315a82842f98d64897e92e1012404863f940bd03d26Mihai Preda } 316105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 317105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project // This needs to be done after sendIntent() so that we get the lastest battery stats. 318105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (logOutlier && dischargeDuration != 0) { 319105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project logOutlier(dischargeDuration); 320105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final void sendIntent() { 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Pack up the values and broadcast them to everyone 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED); 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 329105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project mBatteryStats.setOnBattery(mPlugType == BATTERY_PLUGGED_NONE, mBatteryLevel); 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Should never happen. 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int icon = getIcon(mBatteryLevel); 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra("status", mBatteryStatus); 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra("health", mBatteryHealth); 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra("present", mBatteryPresent); 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra("level", mBatteryLevel); 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra("scale", BATTERY_SCALE); 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra("icon-small", icon); 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra("plugged", mPlugType); 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra("voltage", mBatteryVoltage); 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra("temperature", mBatteryTemperature); 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra("technology", mBatteryTechnology); 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (false) { 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "updateBattery level:" + mBatteryLevel + 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " scale:" + BATTERY_SCALE + " status:" + mBatteryStatus + 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " health:" + mBatteryHealth + " present:" + mBatteryPresent + 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " voltage: " + mBatteryVoltage + 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " temperature: " + mBatteryTemperature + 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " technology: " + mBatteryTechnology + 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " AC powered:" + mAcOnline + " USB powered:" + mUsbOnline + 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " icon:" + icon ); 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ActivityManagerNative.broadcastStickyIntent(intent, null); 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final void logBatteryStats() { 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IBinder batteryInfoService = ServiceManager.getService(BATTERY_STATS_SERVICE_NAME); 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (batteryInfoService != null) { 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project byte[] buffer = new byte[DUMP_MAX_LENGTH]; 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project File dumpFile = null; 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FileOutputStream dumpStream = null; 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // dump the service to a file 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dumpFile = new File(DUMPSYS_DATA_PATH + BATTERY_STATS_SERVICE_NAME + ".dump"); 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dumpStream = new FileOutputStream(dumpFile); 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project batteryInfoService.dump(dumpStream.getFD(), DUMPSYS_ARGS); 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dumpStream.getFD().sync(); 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // read dumped file above into buffer truncated to DUMP_MAX_LENGTH 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // and insert into events table. 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int length = (int) Math.min(dumpFile.length(), DUMP_MAX_LENGTH); 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FileInputStream fileInputStream = new FileInputStream(dumpFile); 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int nread = fileInputStream.read(buffer, 0, length); 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (nread > 0) { 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Checkin.logEvent(mContext.getContentResolver(), 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Checkin.Events.Tag.BATTERY_DISCHARGE_INFO, 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new String(buffer, 0, nread)); 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (LOCAL_LOGV) Log.v(TAG, "dumped " + nread + "b from " + 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project batteryInfoService + "to log"); 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (LOCAL_LOGV) Log.v(TAG, "actual dump:" + new String(buffer, 0, nread)); 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "failed to dump service '" + BATTERY_STATS_SERVICE_NAME + 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "':" + e); 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "failed to write dumpsys file: " + e); 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // make sure we clean up 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dumpStream != null) { 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dumpStream.close(); 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "failed to close dumpsys output stream"); 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dumpFile != null && !dumpFile.delete()) { 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "failed to delete temporary dumpsys file: " 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + dumpFile.getAbsolutePath()); 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final void logOutlier(long duration) { 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver cr = mContext.getContentResolver(); 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String dischargeThresholdString = Settings.Gservices.getString(cr, 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Settings.Gservices.BATTERY_DISCHARGE_THRESHOLD); 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String durationThresholdString = Settings.Gservices.getString(cr, 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Settings.Gservices.BATTERY_DISCHARGE_DURATION_THRESHOLD); 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dischargeThresholdString != null && durationThresholdString != null) { 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long durationThreshold = Long.parseLong(durationThresholdString); 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int dischargeThreshold = Integer.parseInt(dischargeThresholdString); 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (duration <= durationThreshold && 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDischargeStartLevel - mBatteryLevel >= dischargeThreshold) { 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the discharge cycle is bad enough we want to know about it. 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project logBatteryStats(); 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (LOCAL_LOGV) Log.v(TAG, "duration threshold: " + durationThreshold + 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " discharge threshold: " + dischargeThreshold); 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (LOCAL_LOGV) Log.v(TAG, "duration: " + duration + " discharge: " + 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (mDischargeStartLevel - mBatteryLevel)); 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (NumberFormatException e) { 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "Invalid DischargeThresholds GService string: " + 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project durationThresholdString + " or " + dischargeThresholdString); 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final int getIcon(int level) { 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBatteryStatus == BatteryManager.BATTERY_STATUS_CHARGING) { 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return com.android.internal.R.drawable.stat_sys_battery_charge; 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (mBatteryStatus == BatteryManager.BATTERY_STATUS_DISCHARGING || 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBatteryStatus == BatteryManager.BATTERY_STATUS_NOT_CHARGING || 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBatteryStatus == BatteryManager.BATTERY_STATUS_FULL) { 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return com.android.internal.R.drawable.stat_sys_battery; 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return com.android.internal.R.drawable.stat_sys_battery_unknown; 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED) { 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println("Permission Denial: can't dump Battery service from from pid=" 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Binder.getCallingPid() 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ", uid=" + Binder.getCallingUid()); 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println("Current Battery Service state:"); 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" AC powered: " + mAcOnline); 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" USB powered: " + mUsbOnline); 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" status: " + mBatteryStatus); 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" health: " + mBatteryHealth); 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" present: " + mBatteryPresent); 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" level: " + mBatteryLevel); 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" scale: " + BATTERY_SCALE); 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" voltage:" + mBatteryVoltage); 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" temperature: " + mBatteryTemperature); 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" technology: " + mBatteryTechnology); 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 476