1a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn/* 2a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn * Copyright (C) 2009 The Android Open Source Project 3a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn * 4a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 5a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn * you may not use this file except in compliance with the License. 6a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn * You may obtain a copy of the License at 7a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn * 8a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 9a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn * 10a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn * Unless required by applicable law or agreed to in writing, software 11a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 12a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn * See the License for the specific language governing permissions and 14a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn * limitations under the License. 15a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn */ 16a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 17a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackbornpackage com.android.internal.os; 18a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 19a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackbornimport static android.os.BatteryStats.NETWORK_MOBILE_RX_DATA; 20a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackbornimport static android.os.BatteryStats.NETWORK_MOBILE_TX_DATA; 21a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackbornimport static android.os.BatteryStats.NETWORK_WIFI_RX_DATA; 22a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackbornimport static android.os.BatteryStats.NETWORK_WIFI_TX_DATA; 23a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 24a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackbornimport android.content.Context; 252ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackbornimport android.content.Intent; 262ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackbornimport android.content.IntentFilter; 27a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackbornimport android.hardware.Sensor; 28a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackbornimport android.hardware.SensorManager; 29a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackbornimport android.net.ConnectivityManager; 30a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackbornimport android.os.BatteryStats; 31a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackbornimport android.os.BatteryStats.Uid; 32a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackbornimport android.os.Bundle; 330068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackbornimport android.os.MemoryFile; 34a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackbornimport android.os.Parcel; 350068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackbornimport android.os.ParcelFileDescriptor; 36a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackbornimport android.os.Process; 37a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackbornimport android.os.RemoteException; 38a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackbornimport android.os.ServiceManager; 39a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackbornimport android.os.SystemClock; 40a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackbornimport android.os.UserHandle; 41a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackbornimport android.telephony.SignalStrength; 420068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackbornimport android.util.ArrayMap; 43a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackbornimport android.util.Log; 44a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackbornimport android.util.SparseArray; 45a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 46a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackbornimport com.android.internal.app.IBatteryStats; 47a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackbornimport com.android.internal.os.BatterySipper.DrainType; 48a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 490068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackbornimport java.io.File; 500068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackbornimport java.io.FileInputStream; 510068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackbornimport java.io.FileOutputStream; 520068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackbornimport java.io.IOException; 53a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackbornimport java.util.ArrayList; 54a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackbornimport java.util.Collections; 55d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackbornimport java.util.Comparator; 56a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackbornimport java.util.List; 57a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackbornimport java.util.Map; 58a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 59a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn/** 60a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn * A helper class for retrieving the power usage information for all applications and services. 61a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn * 62a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn * The caller must initialize this class as soon as activity object is ready to use (for example, in 63a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn * onAttach() for Fragment), call create() in onCreate() and call destroy() in onDestroy(). 64a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn */ 650068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackbornpublic final class BatteryStatsHelper { 66a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 67eaf2ac464b1cd741d7d0fe700771b1b7c00ddb29Dianne Hackborn private static final boolean DEBUG = false; 68a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 69a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn private static final String TAG = BatteryStatsHelper.class.getSimpleName(); 70a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 71a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn private static BatteryStats sStatsXfer; 722ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn private static Intent sBatteryBroadcastXfer; 730068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn private static ArrayMap<File, BatteryStats> sFileXfer = new ArrayMap<>(); 74a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 75a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn final private Context mContext; 762ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn final private boolean mCollectBatteryBroadcast; 77d953c53d3b04d772bb1b62ede1c2011641ca82b5Dianne Hackborn final private boolean mWifiOnly; 78a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 79a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn private IBatteryStats mBatteryInfo; 80a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn private BatteryStats mStats; 812ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn private Intent mBatteryBroadcast; 82a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn private PowerProfile mPowerProfile; 83a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 84a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn private final List<BatterySipper> mUsageList = new ArrayList<BatterySipper>(); 85a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn private final List<BatterySipper> mWifiSippers = new ArrayList<BatterySipper>(); 86a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn private final List<BatterySipper> mBluetoothSippers = new ArrayList<BatterySipper>(); 87a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn private final SparseArray<List<BatterySipper>> mUserSippers 88a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn = new SparseArray<List<BatterySipper>>(); 89a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn private final SparseArray<Double> mUserPower = new SparseArray<Double>(); 90a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 91d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn private final List<BatterySipper> mMobilemsppList = new ArrayList<BatterySipper>(); 92d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn 93a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn private int mStatsType = BatteryStats.STATS_SINCE_CHARGED; 94a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 9597ae538554e5d894774ddd55c266434ce1d67492Dianne Hackborn long mRawRealtime; 9697ae538554e5d894774ddd55c266434ce1d67492Dianne Hackborn long mRawUptime; 97a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn long mBatteryRealtime; 98a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn long mBatteryUptime; 99a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn long mTypeBatteryRealtime; 100a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn long mTypeBatteryUptime; 1012ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn long mBatteryTimeRemaining; 1022ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn long mChargeTimeRemaining; 103a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 104a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn private long mStatsPeriod = 0; 105a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn private double mMaxPower = 1; 106fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn private double mMaxRealPower = 1; 107099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn private double mComputedPower; 108a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn private double mTotalPower; 109a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn private double mWifiPower; 110a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn private double mBluetoothPower; 111a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn private double mMinDrainedPower; 112a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn private double mMaxDrainedPower; 113a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 114d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn // How much the apps together have kept the mobile radio active. 115d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn private long mAppMobileActive; 116d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn 117a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn // How much the apps together have left WIFI running. 118a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn private long mAppWifiRunning; 119a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 120a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn public BatteryStatsHelper(Context context) { 1212ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn this(context, true); 1222ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn } 1232ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn 1242ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn public BatteryStatsHelper(Context context, boolean collectBatteryBroadcast) { 125a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn mContext = context; 1262ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn mCollectBatteryBroadcast = collectBatteryBroadcast; 127d953c53d3b04d772bb1b62ede1c2011641ca82b5Dianne Hackborn mWifiOnly = checkWifiOnly(context); 128d953c53d3b04d772bb1b62ede1c2011641ca82b5Dianne Hackborn } 129d953c53d3b04d772bb1b62ede1c2011641ca82b5Dianne Hackborn 130d953c53d3b04d772bb1b62ede1c2011641ca82b5Dianne Hackborn public BatteryStatsHelper(Context context, boolean collectBatteryBroadcast, boolean wifiOnly) { 131d953c53d3b04d772bb1b62ede1c2011641ca82b5Dianne Hackborn mContext = context; 132d953c53d3b04d772bb1b62ede1c2011641ca82b5Dianne Hackborn mCollectBatteryBroadcast = collectBatteryBroadcast; 133d953c53d3b04d772bb1b62ede1c2011641ca82b5Dianne Hackborn mWifiOnly = wifiOnly; 134d953c53d3b04d772bb1b62ede1c2011641ca82b5Dianne Hackborn } 135d953c53d3b04d772bb1b62ede1c2011641ca82b5Dianne Hackborn 136d953c53d3b04d772bb1b62ede1c2011641ca82b5Dianne Hackborn public static boolean checkWifiOnly(Context context) { 137d953c53d3b04d772bb1b62ede1c2011641ca82b5Dianne Hackborn ConnectivityManager cm = (ConnectivityManager)context.getSystemService( 138d953c53d3b04d772bb1b62ede1c2011641ca82b5Dianne Hackborn Context.CONNECTIVITY_SERVICE); 139d953c53d3b04d772bb1b62ede1c2011641ca82b5Dianne Hackborn return !cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE); 140a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 141a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 1420068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn public void storeStatsHistoryInFile(String fname) { 1430068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn synchronized (sFileXfer) { 1440068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn File path = makeFilePath(mContext, fname); 1450068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn sFileXfer.put(path, this.getStats()); 1460068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn FileOutputStream fout = null; 1470068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn try { 1480068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn fout = new FileOutputStream(path); 1490068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn Parcel hist = Parcel.obtain(); 1500068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn getStats().writeToParcelWithoutUids(hist, 0); 1510068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn byte[] histData = hist.marshall(); 1520068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn fout.write(histData); 1530068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn } catch (IOException e) { 1540068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn Log.w(TAG, "Unable to write history to file", e); 1550068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn } finally { 1560068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn if (fout != null) { 1570068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn try { 1580068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn fout.close(); 1590068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn } catch (IOException e) { 1600068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn } 1610068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn } 1620068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn } 1630068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn } 1640068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn } 1650068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn 1660068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn public static BatteryStats statsFromFile(Context context, String fname) { 1670068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn synchronized (sFileXfer) { 1680068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn File path = makeFilePath(context, fname); 1690068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn BatteryStats stats = sFileXfer.get(path); 1700068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn if (stats != null) { 1710068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn return stats; 1720068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn } 1730068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn FileInputStream fin = null; 1740068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn try { 1750068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn fin = new FileInputStream(path); 1760068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn byte[] data = readFully(fin); 1770068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn Parcel parcel = Parcel.obtain(); 1780068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn parcel.unmarshall(data, 0, data.length); 1790068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn parcel.setDataPosition(0); 1800068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn return com.android.internal.os.BatteryStatsImpl.CREATOR.createFromParcel(parcel); 1810068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn } catch (IOException e) { 1820068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn Log.w(TAG, "Unable to read history to file", e); 1830068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn } finally { 1840068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn if (fin != null) { 1850068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn try { 1860068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn fin.close(); 1870068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn } catch (IOException e) { 1880068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn } 1890068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn } 1900068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn } 1910068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn } 1920068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn return getStats(IBatteryStats.Stub.asInterface( 1930068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn ServiceManager.getService(BatteryStats.SERVICE_NAME))); 1940068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn } 1950068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn 1960068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn public static void dropFile(Context context, String fname) { 1970068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn makeFilePath(context, fname).delete(); 1980068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn } 1990068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn 2000068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn private static File makeFilePath(Context context, String fname) { 2010068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn return new File(context.getFilesDir(), fname); 2020068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn } 2030068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn 204a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn /** Clears the current stats and forces recreating for future use. */ 205a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn public void clearStats() { 206a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn mStats = null; 207a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 208a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 209a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn public BatteryStats getStats() { 210a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (mStats == null) { 211a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn load(); 212a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 213a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn return mStats; 214a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 215a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 2162ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn public Intent getBatteryBroadcast() { 2172ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn if (mBatteryBroadcast == null && mCollectBatteryBroadcast) { 2182ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn load(); 2192ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn } 2202ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn return mBatteryBroadcast; 2212ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn } 2222ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn 223a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn public PowerProfile getPowerProfile() { 224a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn return mPowerProfile; 225a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 226a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 227a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn public void create(BatteryStats stats) { 228a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn mPowerProfile = new PowerProfile(mContext); 229a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn mStats = stats; 230a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 231a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 232a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn public void create(Bundle icicle) { 233a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (icicle != null) { 234a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn mStats = sStatsXfer; 2352ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn mBatteryBroadcast = sBatteryBroadcastXfer; 236a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 237a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn mBatteryInfo = IBatteryStats.Stub.asInterface( 238a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn ServiceManager.getService(BatteryStats.SERVICE_NAME)); 239a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn mPowerProfile = new PowerProfile(mContext); 240a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 241a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 242a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn public void storeState() { 243a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn sStatsXfer = mStats; 2442ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn sBatteryBroadcastXfer = mBatteryBroadcast; 245a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 246a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 247a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn public static String makemAh(double power) { 248d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn if (power < .00001) return String.format("%.8f", power); 249a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn else if (power < .0001) return String.format("%.7f", power); 250a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn else if (power < .001) return String.format("%.6f", power); 251a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn else if (power < .01) return String.format("%.5f", power); 252a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn else if (power < .1) return String.format("%.4f", power); 253a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn else if (power < 1) return String.format("%.3f", power); 254a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn else if (power < 10) return String.format("%.2f", power); 255a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn else if (power < 100) return String.format("%.1f", power); 256a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn else return String.format("%.0f", power); 257a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 258a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 259a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn /** 260a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn * Refreshes the power usage list. 261a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn */ 262a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn public void refreshStats(int statsType, int asUser) { 263c3b07a0c9ce9b1a2af644112e678f3963226fad2Zoltan Szatmary-Ban SparseArray<UserHandle> users = new SparseArray<UserHandle>(1); 264c3b07a0c9ce9b1a2af644112e678f3963226fad2Zoltan Szatmary-Ban users.put(asUser, new UserHandle(asUser)); 265c3b07a0c9ce9b1a2af644112e678f3963226fad2Zoltan Szatmary-Ban refreshStats(statsType, users); 266c3b07a0c9ce9b1a2af644112e678f3963226fad2Zoltan Szatmary-Ban } 267c3b07a0c9ce9b1a2af644112e678f3963226fad2Zoltan Szatmary-Ban 268c3b07a0c9ce9b1a2af644112e678f3963226fad2Zoltan Szatmary-Ban /** 269c3b07a0c9ce9b1a2af644112e678f3963226fad2Zoltan Szatmary-Ban * Refreshes the power usage list. 270c3b07a0c9ce9b1a2af644112e678f3963226fad2Zoltan Szatmary-Ban */ 271c3b07a0c9ce9b1a2af644112e678f3963226fad2Zoltan Szatmary-Ban public void refreshStats(int statsType, List<UserHandle> asUsers) { 272c3b07a0c9ce9b1a2af644112e678f3963226fad2Zoltan Szatmary-Ban final int n = asUsers.size(); 273c3b07a0c9ce9b1a2af644112e678f3963226fad2Zoltan Szatmary-Ban SparseArray<UserHandle> users = new SparseArray<UserHandle>(n); 274c3b07a0c9ce9b1a2af644112e678f3963226fad2Zoltan Szatmary-Ban for (int i = 0; i < n; ++i) { 275c3b07a0c9ce9b1a2af644112e678f3963226fad2Zoltan Szatmary-Ban UserHandle userHandle = asUsers.get(i); 276c3b07a0c9ce9b1a2af644112e678f3963226fad2Zoltan Szatmary-Ban users.put(userHandle.getIdentifier(), userHandle); 277c3b07a0c9ce9b1a2af644112e678f3963226fad2Zoltan Szatmary-Ban } 278c3b07a0c9ce9b1a2af644112e678f3963226fad2Zoltan Szatmary-Ban refreshStats(statsType, users); 279c3b07a0c9ce9b1a2af644112e678f3963226fad2Zoltan Szatmary-Ban } 280c3b07a0c9ce9b1a2af644112e678f3963226fad2Zoltan Szatmary-Ban 281c3b07a0c9ce9b1a2af644112e678f3963226fad2Zoltan Szatmary-Ban /** 282c3b07a0c9ce9b1a2af644112e678f3963226fad2Zoltan Szatmary-Ban * Refreshes the power usage list. 283c3b07a0c9ce9b1a2af644112e678f3963226fad2Zoltan Szatmary-Ban */ 284c3b07a0c9ce9b1a2af644112e678f3963226fad2Zoltan Szatmary-Ban public void refreshStats(int statsType, SparseArray<UserHandle> asUsers) { 285c3b07a0c9ce9b1a2af644112e678f3963226fad2Zoltan Szatmary-Ban refreshStats(statsType, asUsers, SystemClock.elapsedRealtime() * 1000, 286a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn SystemClock.uptimeMillis() * 1000); 287a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 288a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 289c3b07a0c9ce9b1a2af644112e678f3963226fad2Zoltan Szatmary-Ban public void refreshStats(int statsType, SparseArray<UserHandle> asUsers, long rawRealtimeUs, 290c3b07a0c9ce9b1a2af644112e678f3963226fad2Zoltan Szatmary-Ban long rawUptimeUs) { 291a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn // Initialize mStats if necessary. 292a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn getStats(); 293a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 294a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn mMaxPower = 0; 295fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn mMaxRealPower = 0; 296099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn mComputedPower = 0; 297a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn mTotalPower = 0; 298a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn mWifiPower = 0; 299a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn mBluetoothPower = 0; 300d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn mAppMobileActive = 0; 301a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn mAppWifiRunning = 0; 302a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 303a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn mUsageList.clear(); 304a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn mWifiSippers.clear(); 305a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn mBluetoothSippers.clear(); 306a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn mUserSippers.clear(); 307a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn mUserPower.clear(); 308d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn mMobilemsppList.clear(); 309a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 310a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (mStats == null) { 311a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn return; 312a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 313a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 314a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn mStatsType = statsType; 31597ae538554e5d894774ddd55c266434ce1d67492Dianne Hackborn mRawUptime = rawUptimeUs; 31697ae538554e5d894774ddd55c266434ce1d67492Dianne Hackborn mRawRealtime = rawRealtimeUs; 31797ae538554e5d894774ddd55c266434ce1d67492Dianne Hackborn mBatteryUptime = mStats.getBatteryUptime(rawUptimeUs); 31897ae538554e5d894774ddd55c266434ce1d67492Dianne Hackborn mBatteryRealtime = mStats.getBatteryRealtime(rawRealtimeUs); 31997ae538554e5d894774ddd55c266434ce1d67492Dianne Hackborn mTypeBatteryUptime = mStats.computeBatteryUptime(rawUptimeUs, mStatsType); 32097ae538554e5d894774ddd55c266434ce1d67492Dianne Hackborn mTypeBatteryRealtime = mStats.computeBatteryRealtime(rawRealtimeUs, mStatsType); 3212ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn mBatteryTimeRemaining = mStats.computeBatteryTimeRemaining(rawRealtimeUs); 3222ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn mChargeTimeRemaining = mStats.computeChargeTimeRemaining(rawRealtimeUs); 323a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 324a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (DEBUG) { 32597ae538554e5d894774ddd55c266434ce1d67492Dianne Hackborn Log.d(TAG, "Raw time: realtime=" + (rawRealtimeUs/1000) + " uptime=" 32697ae538554e5d894774ddd55c266434ce1d67492Dianne Hackborn + (rawUptimeUs/1000)); 327a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn Log.d(TAG, "Battery time: realtime=" + (mBatteryRealtime/1000) + " uptime=" 328a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn + (mBatteryUptime/1000)); 329a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn Log.d(TAG, "Battery type time: realtime=" + (mTypeBatteryRealtime/1000) + " uptime=" 330a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn + (mTypeBatteryUptime/1000)); 331a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 332a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn mMinDrainedPower = (mStats.getLowDischargeAmountSinceCharge() 333a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn * mPowerProfile.getBatteryCapacity()) / 100; 334a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn mMaxDrainedPower = (mStats.getHighDischargeAmountSinceCharge() 335a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn * mPowerProfile.getBatteryCapacity()) / 100; 336a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 337c3b07a0c9ce9b1a2af644112e678f3963226fad2Zoltan Szatmary-Ban processAppUsage(asUsers); 338d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn 339d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn // Before aggregating apps in to users, collect all apps to sort by their ms per packet. 340d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn for (int i=0; i<mUsageList.size(); i++) { 341d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn BatterySipper bs = mUsageList.get(i); 342d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn bs.computeMobilemspp(); 343d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn if (bs.mobilemspp != 0) { 344d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn mMobilemsppList.add(bs); 345d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn } 346d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn } 347d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn for (int i=0; i<mUserSippers.size(); i++) { 348d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn List<BatterySipper> user = mUserSippers.valueAt(i); 349d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn for (int j=0; j<user.size(); j++) { 350d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn BatterySipper bs = user.get(j); 351d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn bs.computeMobilemspp(); 352d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn if (bs.mobilemspp != 0) { 353d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn mMobilemsppList.add(bs); 354d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn } 355d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn } 356d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn } 357d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn Collections.sort(mMobilemsppList, new Comparator<BatterySipper>() { 358d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn @Override 359d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn public int compare(BatterySipper lhs, BatterySipper rhs) { 360d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn if (lhs.mobilemspp < rhs.mobilemspp) { 361d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn return 1; 362d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn } else if (lhs.mobilemspp > rhs.mobilemspp) { 363d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn return -1; 364d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn } 365d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn return 0; 366d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn } 367d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn }); 368d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn 369a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn processMiscUsage(); 370a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 371a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (DEBUG) { 372099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn Log.d(TAG, "Accuracy: total computed=" + makemAh(mComputedPower) + ", min discharge=" 373a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn + makemAh(mMinDrainedPower) + ", max discharge=" + makemAh(mMaxDrainedPower)); 374a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 375099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn mTotalPower = mComputedPower; 376099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn if (mStats.getLowDischargeAmountSinceCharge() > 1) { 377099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn if (mMinDrainedPower > mComputedPower) { 378099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn double amount = mMinDrainedPower - mComputedPower; 379099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn mTotalPower = mMinDrainedPower; 380a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn addEntryNoTotal(BatterySipper.DrainType.UNACCOUNTED, 0, amount); 381099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn } else if (mMaxDrainedPower < mComputedPower) { 382099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn double amount = mComputedPower - mMaxDrainedPower; 383a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn addEntryNoTotal(BatterySipper.DrainType.OVERCOUNTED, 0, amount); 384a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 385a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 386a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 387a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn Collections.sort(mUsageList); 388a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 389a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 390c3b07a0c9ce9b1a2af644112e678f3963226fad2Zoltan Szatmary-Ban private void processAppUsage(SparseArray<UserHandle> asUsers) { 391c3b07a0c9ce9b1a2af644112e678f3963226fad2Zoltan Szatmary-Ban final boolean forAllUsers = (asUsers.get(UserHandle.USER_ALL) != null); 392a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn SensorManager sensorManager = (SensorManager) mContext.getSystemService( 393a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn Context.SENSOR_SERVICE); 394a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn final int which = mStatsType; 395a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn final int speedSteps = mPowerProfile.getNumSpeedSteps(); 396a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn final double[] powerCpuNormal = new double[speedSteps]; 397a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn final long[] cpuSpeedStepTimes = new long[speedSteps]; 398a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn for (int p = 0; p < speedSteps; p++) { 399a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn powerCpuNormal[p] = mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_ACTIVE, p); 400a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 401a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn final double mobilePowerPerPacket = getMobilePowerPerPacket(); 402d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn final double mobilePowerPerMs = getMobilePowerPerMs(); 403a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn final double wifiPowerPerPacket = getWifiPowerPerPacket(); 40497ae538554e5d894774ddd55c266434ce1d67492Dianne Hackborn long appWakelockTimeUs = 0; 405a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn BatterySipper osApp = null; 406a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn mStatsPeriod = mTypeBatteryRealtime; 407a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn SparseArray<? extends Uid> uidStats = mStats.getUidStats(); 408a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn final int NU = uidStats.size(); 409a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn for (int iu = 0; iu < NU; iu++) { 410a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn Uid u = uidStats.valueAt(iu); 411a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn double p; // in mAs 412a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn double power = 0; // in mAs 413a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn double highestDrain = 0; 414a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn String packageWithHighestDrain = null; 415a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats(); 416a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn long cpuTime = 0; 417a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn long cpuFgTime = 0; 418a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn long wakelockTime = 0; 419a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn long gpsTime = 0; 420a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (processStats.size() > 0) { 421a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn // Process CPU time 422a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent 423a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn : processStats.entrySet()) { 424a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn Uid.Proc ps = ent.getValue(); 425a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn final long userTime = ps.getUserTime(which); 426a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn final long systemTime = ps.getSystemTime(which); 427a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn final long foregroundTime = ps.getForegroundTime(which); 428a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn cpuFgTime += foregroundTime * 10; // convert to millis 429a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn final long tmpCpuTime = (userTime + systemTime) * 10; // convert to millis 430a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn int totalTimeAtSpeeds = 0; 431a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn // Get the total first 432a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn for (int step = 0; step < speedSteps; step++) { 433a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn cpuSpeedStepTimes[step] = ps.getTimeAtCpuSpeedStep(step, which); 434a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn totalTimeAtSpeeds += cpuSpeedStepTimes[step]; 435a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 436a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (totalTimeAtSpeeds == 0) totalTimeAtSpeeds = 1; 437a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn // Then compute the ratio of time spent at each speed 438a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn double processPower = 0; 439a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn for (int step = 0; step < speedSteps; step++) { 440a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn double ratio = (double) cpuSpeedStepTimes[step] / totalTimeAtSpeeds; 441a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (DEBUG && ratio != 0) Log.d(TAG, "UID " + u.getUid() + ": CPU step #" 442a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn + step + " ratio=" + makemAh(ratio) + " power=" 443a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn + makemAh(ratio*tmpCpuTime*powerCpuNormal[step] / (60*60*1000))); 444a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn processPower += ratio * tmpCpuTime * powerCpuNormal[step]; 445a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 446a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn cpuTime += tmpCpuTime; 447a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (DEBUG && processPower != 0) { 448a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn Log.d(TAG, String.format("process %s, cpu power=%s", 449a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn ent.getKey(), makemAh(processPower / (60*60*1000)))); 450a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 451a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn power += processPower; 452a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (packageWithHighestDrain == null 453a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn || packageWithHighestDrain.startsWith("*")) { 454a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn highestDrain = processPower; 455a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn packageWithHighestDrain = ent.getKey(); 456a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } else if (highestDrain < processPower 457a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn && !ent.getKey().startsWith("*")) { 458a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn highestDrain = processPower; 459a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn packageWithHighestDrain = ent.getKey(); 460a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 461a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 462a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 463a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (cpuFgTime > cpuTime) { 464a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (DEBUG && cpuFgTime > cpuTime + 10000) { 465a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn Log.d(TAG, "WARNING! Cputime is more than 10 seconds behind Foreground time"); 466a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 467a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn cpuTime = cpuFgTime; // Statistics may not have been gathered yet. 468a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 469a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn power /= (60*60*1000); 470a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 471a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn // Process wake lock usage 472a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn Map<String, ? extends BatteryStats.Uid.Wakelock> wakelockStats = u.getWakelockStats(); 473a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> wakelockEntry 474a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn : wakelockStats.entrySet()) { 475a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn Uid.Wakelock wakelock = wakelockEntry.getValue(); 476a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn // Only care about partial wake locks since full wake locks 477a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn // are canceled when the user turns the screen off. 478a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn BatteryStats.Timer timer = wakelock.getWakeTime(BatteryStats.WAKE_TYPE_PARTIAL); 479a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (timer != null) { 48097ae538554e5d894774ddd55c266434ce1d67492Dianne Hackborn wakelockTime += timer.getTotalTimeLocked(mRawRealtime, which); 481a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 482a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 48397ae538554e5d894774ddd55c266434ce1d67492Dianne Hackborn appWakelockTimeUs += wakelockTime; 484a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn wakelockTime /= 1000; // convert to millis 485a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 486a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn // Add cost of holding a wake lock 487a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn p = (wakelockTime 488a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn * mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_AWAKE)) / (60*60*1000); 489a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (DEBUG && p != 0) Log.d(TAG, "UID " + u.getUid() + ": wake " 490a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn + wakelockTime + " power=" + makemAh(p)); 491a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn power += p; 492a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 493a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn // Add cost of mobile traffic 494a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn final long mobileRx = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, mStatsType); 495a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn final long mobileTx = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, mStatsType); 496a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn final long mobileRxB = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, mStatsType); 497a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn final long mobileTxB = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, mStatsType); 498d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn final long mobileActive = u.getMobileRadioActiveTime(mStatsType); 499d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn if (mobileActive > 0) { 500d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn // We are tracking when the radio is up, so can use the active time to 501d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn // determine power use. 502d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn mAppMobileActive += mobileActive; 503d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn p = (mobilePowerPerMs * mobileActive) / 1000; 504d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn } else { 505d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn // We are not tracking when the radio is up, so must approximate power use 506d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn // based on the number of packets. 507d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn p = (mobileRx + mobileTx) * mobilePowerPerPacket; 508d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn } 509a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (DEBUG && p != 0) Log.d(TAG, "UID " + u.getUid() + ": mobile packets " 510d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn + (mobileRx+mobileTx) + " active time " + mobileActive 511d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn + " power=" + makemAh(p)); 512a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn power += p; 513a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 514a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn // Add cost of wifi traffic 515a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn final long wifiRx = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, mStatsType); 516a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn final long wifiTx = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, mStatsType); 517a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn final long wifiRxB = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, mStatsType); 518a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn final long wifiTxB = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, mStatsType); 519a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn p = (wifiRx + wifiTx) * wifiPowerPerPacket; 520a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (DEBUG && p != 0) Log.d(TAG, "UID " + u.getUid() + ": wifi packets " 521a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn + (mobileRx+mobileTx) + " power=" + makemAh(p)); 522a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn power += p; 523a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 524a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn // Add cost of keeping WIFI running. 52597ae538554e5d894774ddd55c266434ce1d67492Dianne Hackborn long wifiRunningTimeMs = u.getWifiRunningTime(mRawRealtime, which) / 1000; 526a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn mAppWifiRunning += wifiRunningTimeMs; 527a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn p = (wifiRunningTimeMs 528a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn * mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_ON)) / (60*60*1000); 529a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (DEBUG && p != 0) Log.d(TAG, "UID " + u.getUid() + ": wifi running " 530a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn + wifiRunningTimeMs + " power=" + makemAh(p)); 531a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn power += p; 532a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 533a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn // Add cost of WIFI scans 53497ae538554e5d894774ddd55c266434ce1d67492Dianne Hackborn long wifiScanTimeMs = u.getWifiScanTime(mRawRealtime, which) / 1000; 535a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn p = (wifiScanTimeMs 536a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn * mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_SCAN)) / (60*60*1000); 537a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (DEBUG) Log.d(TAG, "UID " + u.getUid() + ": wifi scan " + wifiScanTimeMs 538a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn + " power=" + makemAh(p)); 539a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn power += p; 540a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn for (int bin = 0; bin < BatteryStats.Uid.NUM_WIFI_BATCHED_SCAN_BINS; bin++) { 54197ae538554e5d894774ddd55c266434ce1d67492Dianne Hackborn long batchScanTimeMs = u.getWifiBatchedScanTime(bin, mRawRealtime, which) / 1000; 542a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn p = ((batchScanTimeMs 543a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn * mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_BATCHED_SCAN, bin)) 544a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn ) / (60*60*1000); 545a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (DEBUG && p != 0) Log.d(TAG, "UID " + u.getUid() + ": wifi batched scan # " + bin 546a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn + " time=" + batchScanTimeMs + " power=" + makemAh(p)); 547a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn power += p; 548a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 549a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 550a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn // Process Sensor usage 55161659e5daaea80104d4d0fd567e78b5f757b5df4Dianne Hackborn SparseArray<? extends BatteryStats.Uid.Sensor> sensorStats = u.getSensorStats(); 55261659e5daaea80104d4d0fd567e78b5f757b5df4Dianne Hackborn int NSE = sensorStats.size(); 55361659e5daaea80104d4d0fd567e78b5f757b5df4Dianne Hackborn for (int ise=0; ise<NSE; ise++) { 55461659e5daaea80104d4d0fd567e78b5f757b5df4Dianne Hackborn Uid.Sensor sensor = sensorStats.valueAt(ise); 55561659e5daaea80104d4d0fd567e78b5f757b5df4Dianne Hackborn int sensorHandle = sensorStats.keyAt(ise); 556a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn BatteryStats.Timer timer = sensor.getSensorTime(); 55797ae538554e5d894774ddd55c266434ce1d67492Dianne Hackborn long sensorTime = timer.getTotalTimeLocked(mRawRealtime, which) / 1000; 558a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn double multiplier = 0; 559a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn switch (sensorHandle) { 560a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn case Uid.Sensor.GPS: 561a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn multiplier = mPowerProfile.getAveragePower(PowerProfile.POWER_GPS_ON); 562a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn gpsTime = sensorTime; 563a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn break; 564a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn default: 565a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn List<Sensor> sensorList = sensorManager.getSensorList( 566a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn android.hardware.Sensor.TYPE_ALL); 567a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn for (android.hardware.Sensor s : sensorList) { 568a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (s.getHandle() == sensorHandle) { 569a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn multiplier = s.getPower(); 570a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn break; 571a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 572a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 573a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 574a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn p = (multiplier * sensorTime) / (60*60*1000); 575a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (DEBUG && p != 0) Log.d(TAG, "UID " + u.getUid() + ": sensor #" + sensorHandle 576a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn + " time=" + sensorTime + " power=" + makemAh(p)); 577a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn power += p; 578a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 579a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 580a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (DEBUG && power != 0) Log.d(TAG, String.format("UID %d: total power=%s", 581a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn u.getUid(), makemAh(power))); 582a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 583a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn // Add the app to the list if it is consuming power 584a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn final int userId = UserHandle.getUserId(u.getUid()); 585a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (power != 0 || u.getUid() == 0) { 586a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn BatterySipper app = new BatterySipper(BatterySipper.DrainType.APP, u, 587a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn new double[] {power}); 588a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn app.cpuTime = cpuTime; 589a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn app.gpsTime = gpsTime; 590a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn app.wifiRunningTime = wifiRunningTimeMs; 591a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn app.cpuFgTime = cpuFgTime; 592a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn app.wakeLockTime = wakelockTime; 593a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn app.mobileRxPackets = mobileRx; 594a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn app.mobileTxPackets = mobileTx; 595d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn app.mobileActive = mobileActive / 1000; 59677b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn app.mobileActiveCount = u.getMobileRadioActiveCount(mStatsType); 597a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn app.wifiRxPackets = wifiRx; 598a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn app.wifiTxPackets = wifiTx; 599a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn app.mobileRxBytes = mobileRxB; 600a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn app.mobileTxBytes = mobileTxB; 601a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn app.wifiRxBytes = wifiRxB; 602a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn app.wifiTxBytes = wifiTxB; 603a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn app.packageWithHighestDrain = packageWithHighestDrain; 604a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (u.getUid() == Process.WIFI_UID) { 605a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn mWifiSippers.add(app); 606ae19a06e030e55b4db3cb20f1e564d49a78a395eDianne Hackborn mWifiPower += power; 607a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } else if (u.getUid() == Process.BLUETOOTH_UID) { 608a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn mBluetoothSippers.add(app); 609ae19a06e030e55b4db3cb20f1e564d49a78a395eDianne Hackborn mBluetoothPower += power; 610c3b07a0c9ce9b1a2af644112e678f3963226fad2Zoltan Szatmary-Ban } else if (!forAllUsers && asUsers.get(userId) == null 611a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn && UserHandle.getAppId(u.getUid()) >= Process.FIRST_APPLICATION_UID) { 612a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn List<BatterySipper> list = mUserSippers.get(userId); 613a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (list == null) { 614a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn list = new ArrayList<BatterySipper>(); 615a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn mUserSippers.put(userId, list); 616a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 617a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn list.add(app); 618ae19a06e030e55b4db3cb20f1e564d49a78a395eDianne Hackborn if (power != 0) { 619ae19a06e030e55b4db3cb20f1e564d49a78a395eDianne Hackborn Double userPower = mUserPower.get(userId); 620ae19a06e030e55b4db3cb20f1e564d49a78a395eDianne Hackborn if (userPower == null) { 621ae19a06e030e55b4db3cb20f1e564d49a78a395eDianne Hackborn userPower = power; 622ae19a06e030e55b4db3cb20f1e564d49a78a395eDianne Hackborn } else { 623ae19a06e030e55b4db3cb20f1e564d49a78a395eDianne Hackborn userPower += power; 624ae19a06e030e55b4db3cb20f1e564d49a78a395eDianne Hackborn } 625ae19a06e030e55b4db3cb20f1e564d49a78a395eDianne Hackborn mUserPower.put(userId, userPower); 626ae19a06e030e55b4db3cb20f1e564d49a78a395eDianne Hackborn } 627a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } else { 628a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn mUsageList.add(app); 629ae19a06e030e55b4db3cb20f1e564d49a78a395eDianne Hackborn if (power > mMaxPower) mMaxPower = power; 630fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn if (power > mMaxRealPower) mMaxRealPower = power; 631099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn mComputedPower += power; 632a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 633a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (u.getUid() == 0) { 634a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn osApp = app; 635a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 636a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 637a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 638a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 639a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn // The device has probably been awake for longer than the screen on 640a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn // time and application wake lock time would account for. Assign 641a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn // this remainder to the OS, if possible. 642a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (osApp != null) { 643a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn long wakeTimeMillis = mBatteryUptime / 1000; 64497ae538554e5d894774ddd55c266434ce1d67492Dianne Hackborn wakeTimeMillis -= (appWakelockTimeUs / 1000) 64597ae538554e5d894774ddd55c266434ce1d67492Dianne Hackborn + (mStats.getScreenOnTime(mRawRealtime, which) / 1000); 646a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (wakeTimeMillis > 0) { 647a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn double power = (wakeTimeMillis 648a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn * mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_AWAKE)) 649a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn / (60*60*1000); 650a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (DEBUG) Log.d(TAG, "OS wakeLockTime " + wakeTimeMillis + " power " 651a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn + makemAh(power)); 652a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn osApp.wakeLockTime += wakeTimeMillis; 653a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn osApp.value += power; 654a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn osApp.values[0] += power; 655a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (osApp.value > mMaxPower) mMaxPower = osApp.value; 656fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn if (osApp.value > mMaxRealPower) mMaxRealPower = osApp.value; 657099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn mComputedPower += power; 658a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 659a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 660a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 661a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 662a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn private void addPhoneUsage() { 66397ae538554e5d894774ddd55c266434ce1d67492Dianne Hackborn long phoneOnTimeMs = mStats.getPhoneOnTime(mRawRealtime, mStatsType) / 1000; 664a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn double phoneOnPower = mPowerProfile.getAveragePower(PowerProfile.POWER_RADIO_ACTIVE) 665a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn * phoneOnTimeMs / (60*60*1000); 666099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn if (phoneOnPower != 0) { 667d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn BatterySipper bs = addEntry(BatterySipper.DrainType.PHONE, phoneOnTimeMs, phoneOnPower); 668099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn } 669a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 670a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 671a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn private void addScreenUsage() { 672a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn double power = 0; 67397ae538554e5d894774ddd55c266434ce1d67492Dianne Hackborn long screenOnTimeMs = mStats.getScreenOnTime(mRawRealtime, mStatsType) / 1000; 674a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn power += screenOnTimeMs * mPowerProfile.getAveragePower(PowerProfile.POWER_SCREEN_ON); 675a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn final double screenFullPower = 676a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn mPowerProfile.getAveragePower(PowerProfile.POWER_SCREEN_FULL); 677a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn for (int i = 0; i < BatteryStats.NUM_SCREEN_BRIGHTNESS_BINS; i++) { 678a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn double screenBinPower = screenFullPower * (i + 0.5f) 679a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn / BatteryStats.NUM_SCREEN_BRIGHTNESS_BINS; 68097ae538554e5d894774ddd55c266434ce1d67492Dianne Hackborn long brightnessTime = mStats.getScreenBrightnessTime(i, mRawRealtime, mStatsType) 681a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn / 1000; 682a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn double p = screenBinPower*brightnessTime; 683a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (DEBUG && p != 0) { 684a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn Log.d(TAG, "Screen bin #" + i + ": time=" + brightnessTime 685099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn + " power=" + makemAh(p / (60 * 60 * 1000))); 686a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 687a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn power += p; 688a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 689a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn power /= (60*60*1000); // To hours 690099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn if (power != 0) { 691099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn addEntry(BatterySipper.DrainType.SCREEN, screenOnTimeMs, power); 692099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn } 693a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 694a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 695a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn private void addRadioUsage() { 696a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn double power = 0; 697a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn final int BINS = SignalStrength.NUM_SIGNAL_STRENGTH_BINS; 698a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn long signalTimeMs = 0; 699a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn long noCoverageTimeMs = 0; 700a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn for (int i = 0; i < BINS; i++) { 70197ae538554e5d894774ddd55c266434ce1d67492Dianne Hackborn long strengthTimeMs = mStats.getPhoneSignalStrengthTime(i, mRawRealtime, mStatsType) 702a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn / 1000; 703a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn double p = (strengthTimeMs * mPowerProfile.getAveragePower(PowerProfile.POWER_RADIO_ON, i)) 704a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn / (60*60*1000); 705a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (DEBUG && p != 0) { 706a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn Log.d(TAG, "Cell strength #" + i + ": time=" + strengthTimeMs + " power=" 707a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn + makemAh(p)); 708a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 709a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn power += p; 710a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn signalTimeMs += strengthTimeMs; 711a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (i == 0) { 712a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn noCoverageTimeMs = strengthTimeMs; 713a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 714a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 71597ae538554e5d894774ddd55c266434ce1d67492Dianne Hackborn long scanningTimeMs = mStats.getPhoneSignalScanningTime(mRawRealtime, mStatsType) 716a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn / 1000; 717a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn double p = (scanningTimeMs * mPowerProfile.getAveragePower( 718a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn PowerProfile.POWER_RADIO_SCANNING)) 719a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn / (60*60*1000); 720a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (DEBUG && p != 0) { 721a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn Log.d(TAG, "Cell radio scanning: time=" + scanningTimeMs + " power=" + makemAh(p)); 722a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 723a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn power += p; 72497ae538554e5d894774ddd55c266434ce1d67492Dianne Hackborn long radioActiveTimeUs = mStats.getMobileRadioActiveTime(mRawRealtime, mStatsType); 725d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn long remainingActiveTime = (radioActiveTimeUs - mAppMobileActive) / 1000; 726d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn if (remainingActiveTime > 0) { 727d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn power += getMobilePowerPerMs() * remainingActiveTime; 728d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn } 729099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn if (power != 0) { 730099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn BatterySipper bs = 731099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn addEntry(BatterySipper.DrainType.CELL, signalTimeMs, power); 732099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn if (signalTimeMs != 0) { 733099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn bs.noCoveragePercent = noCoverageTimeMs * 100.0 / signalTimeMs; 734099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn } 735d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn bs.mobileActive = remainingActiveTime; 73677b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn bs.mobileActiveCount = mStats.getMobileRadioActiveUnknownCount(mStatsType); 737a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 738a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 739a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 740a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn private void aggregateSippers(BatterySipper bs, List<BatterySipper> from, String tag) { 741a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn for (int i=0; i<from.size(); i++) { 742a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn BatterySipper wbs = from.get(i); 743a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (DEBUG) Log.d(TAG, tag + " adding sipper " + wbs + ": cpu=" + wbs.cpuTime); 744a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn bs.cpuTime += wbs.cpuTime; 745a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn bs.gpsTime += wbs.gpsTime; 746a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn bs.wifiRunningTime += wbs.wifiRunningTime; 747a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn bs.cpuFgTime += wbs.cpuFgTime; 748a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn bs.wakeLockTime += wbs.wakeLockTime; 749a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn bs.mobileRxPackets += wbs.mobileRxPackets; 750a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn bs.mobileTxPackets += wbs.mobileTxPackets; 751d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn bs.mobileActive += wbs.mobileActive; 75277b987f1a1bb6028a871de01065b94c4cfff0b5cDianne Hackborn bs.mobileActiveCount += wbs.mobileActiveCount; 753a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn bs.wifiRxPackets += wbs.wifiRxPackets; 754a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn bs.wifiTxPackets += wbs.wifiTxPackets; 755a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn bs.mobileRxBytes += wbs.mobileRxBytes; 756a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn bs.mobileTxBytes += wbs.mobileTxBytes; 757a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn bs.wifiRxBytes += wbs.wifiRxBytes; 758a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn bs.wifiTxBytes += wbs.wifiTxBytes; 759a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 760d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn bs.computeMobilemspp(); 761a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 762a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 763a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn private void addWiFiUsage() { 76497ae538554e5d894774ddd55c266434ce1d67492Dianne Hackborn long onTimeMs = mStats.getWifiOnTime(mRawRealtime, mStatsType) / 1000; 76597ae538554e5d894774ddd55c266434ce1d67492Dianne Hackborn long runningTimeMs = mStats.getGlobalWifiRunningTime(mRawRealtime, mStatsType) / 1000; 766a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (DEBUG) Log.d(TAG, "WIFI runningTime=" + runningTimeMs 767a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn + " app runningTime=" + mAppWifiRunning); 768a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn runningTimeMs -= mAppWifiRunning; 769a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (runningTimeMs < 0) runningTimeMs = 0; 770a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn double wifiPower = (onTimeMs * 0 /* TODO */ 771a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn * mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_ON) 772a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn + runningTimeMs * mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_ON)) 773a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn / (60*60*1000); 774a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (DEBUG && wifiPower != 0) { 775a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn Log.d(TAG, "Wifi: time=" + runningTimeMs + " power=" + makemAh(wifiPower)); 776a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 777099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn if ((wifiPower+mWifiPower) != 0) { 778099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn BatterySipper bs = addEntry(BatterySipper.DrainType.WIFI, runningTimeMs, 779099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn wifiPower + mWifiPower); 780099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn aggregateSippers(bs, mWifiSippers, "WIFI"); 781099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn } 782a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 783a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 784a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn private void addIdleUsage() { 785a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn long idleTimeMs = (mTypeBatteryRealtime 78697ae538554e5d894774ddd55c266434ce1d67492Dianne Hackborn - mStats.getScreenOnTime(mRawRealtime, mStatsType)) / 1000; 787a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn double idlePower = (idleTimeMs * mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_IDLE)) 788a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn / (60*60*1000); 789a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (DEBUG && idlePower != 0) { 790a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn Log.d(TAG, "Idle: time=" + idleTimeMs + " power=" + makemAh(idlePower)); 791a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 792099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn if (idlePower != 0) { 793099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn addEntry(BatterySipper.DrainType.IDLE, idleTimeMs, idlePower); 794099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn } 795a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 796a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 797a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn private void addBluetoothUsage() { 79897ae538554e5d894774ddd55c266434ce1d67492Dianne Hackborn long btOnTimeMs = mStats.getBluetoothOnTime(mRawRealtime, mStatsType) / 1000; 799a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn double btPower = btOnTimeMs * mPowerProfile.getAveragePower(PowerProfile.POWER_BLUETOOTH_ON) 800a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn / (60*60*1000); 801a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (DEBUG && btPower != 0) { 802a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn Log.d(TAG, "Bluetooth: time=" + btOnTimeMs + " power=" + makemAh(btPower)); 803a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 804a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn int btPingCount = mStats.getBluetoothPingCount(); 805a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn double pingPower = (btPingCount 806a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn * mPowerProfile.getAveragePower(PowerProfile.POWER_BLUETOOTH_AT_CMD)) 807a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn / (60*60*1000); 808a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (DEBUG && pingPower != 0) { 809a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn Log.d(TAG, "Bluetooth ping: count=" + btPingCount + " power=" + makemAh(pingPower)); 810a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 811a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn btPower += pingPower; 812099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn if ((btPower+mBluetoothPower) != 0) { 813099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn BatterySipper bs = addEntry(BatterySipper.DrainType.BLUETOOTH, btOnTimeMs, 814099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn btPower + mBluetoothPower); 815099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn aggregateSippers(bs, mBluetoothSippers, "Bluetooth"); 816099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn } 817a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 818a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 819abc7c499133fe640d6ece2b28d43b52e66cdaa9aDianne Hackborn private void addFlashlightUsage() { 820abc7c499133fe640d6ece2b28d43b52e66cdaa9aDianne Hackborn long flashlightOnTimeMs = mStats.getFlashlightOnTime(mRawRealtime, mStatsType) / 1000; 821abc7c499133fe640d6ece2b28d43b52e66cdaa9aDianne Hackborn double flashlightPower = flashlightOnTimeMs 822abc7c499133fe640d6ece2b28d43b52e66cdaa9aDianne Hackborn * mPowerProfile.getAveragePower(PowerProfile.POWER_FLASHLIGHT) / (60*60*1000); 823abc7c499133fe640d6ece2b28d43b52e66cdaa9aDianne Hackborn if (flashlightPower != 0) { 824abc7c499133fe640d6ece2b28d43b52e66cdaa9aDianne Hackborn addEntry(BatterySipper.DrainType.FLASHLIGHT, flashlightOnTimeMs, flashlightPower); 825abc7c499133fe640d6ece2b28d43b52e66cdaa9aDianne Hackborn } 826abc7c499133fe640d6ece2b28d43b52e66cdaa9aDianne Hackborn } 827abc7c499133fe640d6ece2b28d43b52e66cdaa9aDianne Hackborn 828a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn private void addUserUsage() { 829a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn for (int i=0; i<mUserSippers.size(); i++) { 830a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn final int userId = mUserSippers.keyAt(i); 831a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn final List<BatterySipper> sippers = mUserSippers.valueAt(i); 832a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn Double userPower = mUserPower.get(userId); 833a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn double power = (userPower != null) ? userPower : 0.0; 834a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn BatterySipper bs = addEntry(BatterySipper.DrainType.USER, 0, power); 835a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn bs.userId = userId; 836a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn aggregateSippers(bs, sippers, "User"); 837a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 838a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 839a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 840a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn /** 841a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn * Return estimated power (in mAs) of sending or receiving a packet with the mobile radio. 842a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn */ 843a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn private double getMobilePowerPerPacket() { 844a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn final long MOBILE_BPS = 200000; // TODO: Extract average bit rates from system 845a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn final double MOBILE_POWER = mPowerProfile.getAveragePower(PowerProfile.POWER_RADIO_ACTIVE) 846a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn / 3600; 847a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 848a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn final long mobileRx = mStats.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, mStatsType); 849a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn final long mobileTx = mStats.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, mStatsType); 850a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn final long mobileData = mobileRx + mobileTx; 851a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 852e13c4c0b664dabdc069ca8f9601d96a337eb02f9Dianne Hackborn final long radioDataUptimeMs 85397ae538554e5d894774ddd55c266434ce1d67492Dianne Hackborn = mStats.getMobileRadioActiveTime(mRawRealtime, mStatsType) / 1000; 854fb7b50a0263e500a6a8d2bbd7366b06d1fc91fe3Dianne Hackborn final double mobilePps = (mobileData != 0 && radioDataUptimeMs != 0) 855fb7b50a0263e500a6a8d2bbd7366b06d1fc91fe3Dianne Hackborn ? (mobileData / (double)radioDataUptimeMs) 856a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn : (((double)MOBILE_BPS) / 8 / 2048); 857a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 858a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn return (MOBILE_POWER / mobilePps) / (60*60); 859a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 860a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 861a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn /** 862d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn * Return estimated power (in mAs) of keeping the radio up 863d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn */ 864d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn private double getMobilePowerPerMs() { 865d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn return mPowerProfile.getAveragePower(PowerProfile.POWER_RADIO_ACTIVE) / (60*60*1000); 866d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn } 867d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn 868d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn /** 869a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn * Return estimated power (in mAs) of sending a byte with the Wi-Fi radio. 870a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn */ 871a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn private double getWifiPowerPerPacket() { 872a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn final long WIFI_BPS = 1000000; // TODO: Extract average bit rates from system 873a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn final double WIFI_POWER = mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_ACTIVE) 874a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn / 3600; 875a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn return (WIFI_POWER / (((double)WIFI_BPS) / 8 / 2048)) / (60*60); 876a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 877a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 878a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn private void processMiscUsage() { 879a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn addUserUsage(); 880a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn addPhoneUsage(); 881a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn addScreenUsage(); 882abc7c499133fe640d6ece2b28d43b52e66cdaa9aDianne Hackborn addFlashlightUsage(); 883a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn addWiFiUsage(); 884a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn addBluetoothUsage(); 885a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn addIdleUsage(); // Not including cellular idle power 886a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn // Don't compute radio usage if it's a wifi-only device 887d953c53d3b04d772bb1b62ede1c2011641ca82b5Dianne Hackborn if (!mWifiOnly) { 888a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn addRadioUsage(); 889a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 890a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 891a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 892a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn private BatterySipper addEntry(DrainType drainType, long time, double power) { 893099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn mComputedPower += power; 894fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn if (power > mMaxRealPower) mMaxRealPower = power; 895a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn return addEntryNoTotal(drainType, time, power); 896a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 897a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 898a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn private BatterySipper addEntryNoTotal(DrainType drainType, long time, double power) { 899a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (power > mMaxPower) mMaxPower = power; 900a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn BatterySipper bs = new BatterySipper(drainType, null, new double[] {power}); 901a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn bs.usageTime = time; 902a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn mUsageList.add(bs); 903a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn return bs; 904a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 905a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 906a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn public List<BatterySipper> getUsageList() { 907a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn return mUsageList; 908a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 909a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 910d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn public List<BatterySipper> getMobilemsppList() { 911d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn return mMobilemsppList; 912d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn } 913d45665bf0b26fddf5716a0fd43036848d9301960Dianne Hackborn 914a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn public long getStatsPeriod() { return mStatsPeriod; } 915a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 916a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn public int getStatsType() { return mStatsType; }; 917a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 918a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn public double getMaxPower() { return mMaxPower; } 919a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 920fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn public double getMaxRealPower() { return mMaxRealPower; } 921fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn 922a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn public double getTotalPower() { return mTotalPower; } 923a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 924099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn public double getComputedPower() { return mComputedPower; } 925099bc627c463d9941e23e480f25a78a154429c55Dianne Hackborn 926a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn public double getMinDrainedPower() { 927a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn return mMinDrainedPower; 928a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 929a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 930a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn public double getMaxDrainedPower() { 931a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn return mMaxDrainedPower; 932a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 933a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn 9342ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn public long getBatteryTimeRemaining() { return mBatteryTimeRemaining; } 9352ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn 9362ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn public long getChargeTimeRemaining() { return mChargeTimeRemaining; } 9372ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn 9380068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn public static byte[] readFully(FileInputStream stream) throws java.io.IOException { 9390068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn return readFully(stream, stream.available()); 9400068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn } 9410068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn 9420068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn public static byte[] readFully(FileInputStream stream, int avail) throws java.io.IOException { 9430068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn int pos = 0; 9440068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn byte[] data = new byte[avail]; 9450068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn while (true) { 9460068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn int amt = stream.read(data, pos, data.length-pos); 9470068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn //Log.i("foo", "Read " + amt + " bytes at " + pos 9480068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn // + " of avail " + data.length); 9490068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn if (amt <= 0) { 9500068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn //Log.i("foo", "**** FINISHED READING: pos=" + pos 9510068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn // + " len=" + data.length); 9520068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn return data; 9530068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn } 9540068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn pos += amt; 9550068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn avail = stream.available(); 9560068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn if (avail > data.length-pos) { 9570068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn byte[] newData = new byte[pos+avail]; 9580068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn System.arraycopy(data, 0, newData, 0, pos); 9590068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn data = newData; 9600068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn } 9610068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn } 9620068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn } 9630068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn 964a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn private void load() { 965a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn if (mBatteryInfo == null) { 966a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn return; 967a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 9680068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn mStats = getStats(mBatteryInfo); 9692ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn if (mCollectBatteryBroadcast) { 9702ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn mBatteryBroadcast = mContext.registerReceiver(null, 9712ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); 9722ffa11e4b71c545e34533ef827bdc1a07fbe8246Dianne Hackborn } 973a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn } 9740068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn 9750068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn private static BatteryStatsImpl getStats(IBatteryStats service) { 9760068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn try { 9770068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn ParcelFileDescriptor pfd = service.getStatisticsStream(); 9780068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn if (pfd != null) { 9790068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(pfd); 9800068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn try { 9810068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn byte[] data = readFully(fis, MemoryFile.getSize(pfd.getFileDescriptor())); 9820068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn Parcel parcel = Parcel.obtain(); 9830068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn parcel.unmarshall(data, 0, data.length); 9840068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn parcel.setDataPosition(0); 9850068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn BatteryStatsImpl stats = com.android.internal.os.BatteryStatsImpl.CREATOR 9860068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn .createFromParcel(parcel); 9870068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn stats.distributeWorkLocked(BatteryStats.STATS_SINCE_CHARGED); 9880068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn return stats; 9890068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn } catch (IOException e) { 9900068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn Log.w(TAG, "Unable to read statistics stream", e); 9910068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn } 9920068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn } 9930068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn } catch (RemoteException e) { 9940068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn Log.w(TAG, "RemoteException:", e); 9950068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn } 996d7c9289f935992f4ae2fc032747f9e04bb86a7d0Dianne Hackborn return new BatteryStatsImpl(); 9970068d3dcf1f1a804554a1a09e3b173ac12651786Dianne Hackborn } 998a7c837f043c1ca0bdecd42645ba7da8c5717566dDianne Hackborn} 999