BatteryStatsHelper.java revision c3e9ac937a4ba948d47cbb83f6999af34fd00b65
1c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang/* 2c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * Copyright (C) 2009 The Android Open Source Project 3c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * 4c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * Licensed under the Apache License, Version 2.0 (the "License"); 5c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * you may not use this file except in compliance with the License. 6c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * You may obtain a copy of the License at 7c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * 8c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * http://www.apache.org/licenses/LICENSE-2.0 9c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * 10c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * Unless required by applicable law or agreed to in writing, software 11c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * distributed under the License is distributed on an "AS IS" BASIS, 12c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * See the License for the specific language governing permissions and 14c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * limitations under the License. 15c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang */ 16c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 17c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangpackage com.android.settings.fuelgauge; 18c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 19c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport static android.os.BatteryStats.NETWORK_MOBILE_RX_BYTES; 20c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport static android.os.BatteryStats.NETWORK_MOBILE_TX_BYTES; 21c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport static android.os.BatteryStats.NETWORK_WIFI_RX_BYTES; 22c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport static android.os.BatteryStats.NETWORK_WIFI_TX_BYTES; 23c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 24c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport android.app.Activity; 25c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport android.content.Context; 26c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport android.content.pm.UserInfo; 27c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport android.graphics.drawable.Drawable; 28c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport android.hardware.Sensor; 29c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport android.hardware.SensorManager; 30c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport android.os.BatteryStats; 31c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport android.os.BatteryStats.Uid; 32c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport android.os.Bundle; 33c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport android.os.Handler; 34c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport android.os.Parcel; 35c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport android.os.Process; 36c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport android.os.RemoteException; 37c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport android.os.ServiceManager; 38c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport android.os.SystemClock; 39c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport android.os.UserHandle; 40c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport android.os.UserManager; 41c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport android.preference.PreferenceActivity; 42c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport android.telephony.SignalStrength; 43c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport android.util.Log; 44c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport android.util.SparseArray; 45c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 46c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport com.android.internal.app.IBatteryStats; 47c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport com.android.internal.os.BatteryStatsImpl; 48c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport com.android.internal.os.PowerProfile; 49c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport com.android.internal.util.FastPrintWriter; 50c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport com.android.settings.R; 51c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport com.android.settings.fuelgauge.PowerUsageDetail.DrainType; 52c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport com.android.settings.users.UserUtils; 53c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 54c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport java.io.PrintWriter; 55c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport java.io.StringWriter; 56c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport java.io.Writer; 57c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport java.util.ArrayList; 58c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport java.util.Collections; 59c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport java.util.List; 60c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangimport java.util.Map; 61c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 62c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang/** 63c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * A helper class for retrieving the power usage information for all applications and services. 64c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * 65c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * The caller must initialize this class as soon as activity object is ready to use (for example, in 66c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * onAttach() for Fragment), call create() in onCreate() and call destroy() in onDestroy(). 67c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang */ 68c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tangpublic class BatteryStatsHelper { 69c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 70c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private static final boolean DEBUG = false; 71c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 72c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private static final String TAG = BatteryStatsHelper.class.getSimpleName(); 73c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 74c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private static BatteryStatsImpl sStatsXfer; 75c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private IBatteryStats mBatteryInfo; 76c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private UserManager mUm; 77c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private BatteryStatsImpl mStats; 78c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private PowerProfile mPowerProfile; 79c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 80c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private final List<BatterySipper> mUsageList = new ArrayList<BatterySipper>(); 81c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private final List<BatterySipper> mWifiSippers = new ArrayList<BatterySipper>(); 82c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private final List<BatterySipper> mBluetoothSippers = new ArrayList<BatterySipper>(); 83c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private final SparseArray<List<BatterySipper>> mUserSippers 84c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang = new SparseArray<List<BatterySipper>>(); 85c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private final SparseArray<Double> mUserPower = new SparseArray<Double>(); 86c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 87c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private int mStatsType = BatteryStats.STATS_SINCE_CHARGED; 88c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 89c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private long mStatsPeriod = 0; 90c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private double mMaxPower = 1; 91c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private double mTotalPower; 92c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private double mWifiPower; 93c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private double mBluetoothPower; 94c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 95c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // How much the apps together have left WIFI running. 96c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private long mAppWifiRunning; 97c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 98c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang /** Queue for fetching name and icon for an application */ 99c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private ArrayList<BatterySipper> mRequestQueue = new ArrayList<BatterySipper>(); 100c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 101c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private Activity mActivity; 102c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private Handler mHandler; 103c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 104c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private class NameAndIconLoader extends Thread { 105c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private boolean mAbort = false; 106c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 107c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang public NameAndIconLoader() { 108c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang super("BatteryUsage Icon Loader"); 109c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 110c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 111c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang public void abort() { 112c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mAbort = true; 113c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 114c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 115c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang @Override 116c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang public void run() { 117c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang while (true) { 118c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang BatterySipper bs; 119c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang synchronized (mRequestQueue) { 120c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (mRequestQueue.isEmpty() || mAbort) { 121c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mHandler.sendEmptyMessage(MSG_REPORT_FULLY_DRAWN); 122c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang return; 123c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 124c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang bs = mRequestQueue.remove(0); 125c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 126c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang bs.loadNameAndIcon(); 127c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 128c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 129c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 130c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 131c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private NameAndIconLoader mRequestThread; 132c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 133c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang public BatteryStatsHelper(Activity activity, Handler handler) { 134c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mActivity = activity; 135c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mHandler = handler; 136c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 137c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 138c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang /** Clears the current stats and forces recreating for future use. */ 139c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang public void clearStats() { 140c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mStats = null; 141c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 142c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 143c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang public BatteryStatsImpl getStats() { 144c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (mStats == null) { 145c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang load(); 146c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 147c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang return mStats; 148c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 149c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 150c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang public PowerProfile getPowerProfile() { 151c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang return mPowerProfile; 152c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 153c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 154c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang public void create(Bundle icicle) { 155c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (icicle != null) { 156c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mStats = sStatsXfer; 157c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 158c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mBatteryInfo = IBatteryStats.Stub.asInterface( 159c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang ServiceManager.getService(BatteryStats.SERVICE_NAME)); 160c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mUm = (UserManager) mActivity.getSystemService(Context.USER_SERVICE); 161c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mPowerProfile = new PowerProfile(mActivity); 162c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 163c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 164c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang public void pause() { 165c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (mRequestThread != null) { 166c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mRequestThread.abort(); 167c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 168c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 169c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 170c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang public void destroy() { 171c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (mActivity.isChangingConfigurations()) { 172c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sStatsXfer = mStats; 173c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } else { 174c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang BatterySipper.sUidCache.clear(); 175c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 176c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 177c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 178c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang public void startBatteryDetailPage(PreferenceActivity caller, BatterySipper sipper) { 179c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // Initialize mStats if necessary. 180c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang getStats(); 181c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 182c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Bundle args = new Bundle(); 183c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang args.putString(PowerUsageDetail.EXTRA_TITLE, sipper.name); 184c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang args.putInt(PowerUsageDetail.EXTRA_PERCENT, (int) 185c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Math.ceil(sipper.getSortValue() * 100 / mTotalPower)); 186c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang args.putInt(PowerUsageDetail.EXTRA_GAUGE, (int) 187c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Math.ceil(sipper.getSortValue() * 100 / mMaxPower)); 188c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang args.putLong(PowerUsageDetail.EXTRA_USAGE_DURATION, mStatsPeriod); 189c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang args.putString(PowerUsageDetail.EXTRA_ICON_PACKAGE, sipper.defaultPackageName); 190c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang args.putInt(PowerUsageDetail.EXTRA_ICON_ID, sipper.iconId); 191c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang args.putDouble(PowerUsageDetail.EXTRA_NO_COVERAGE, sipper.noCoveragePercent); 192c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (sipper.uidObj != null) { 193c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang args.putInt(PowerUsageDetail.EXTRA_UID, sipper.uidObj.getUid()); 194c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 195c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang args.putSerializable(PowerUsageDetail.EXTRA_DRAIN_TYPE, sipper.drainType); 196c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 197c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang int[] types; 198c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang double[] values; 199c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang switch (sipper.drainType) { 200c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang case APP: 201c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang case USER: 202c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang { 203c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Uid uid = sipper.uidObj; 204c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang types = new int[] { 205c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_cpu, 206c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_cpu_foreground, 207c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_wake_lock, 208c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_gps, 209c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_wifi_running, 210c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_data_recv, 211c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_data_send, 212c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_data_wifi_recv, 213c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_data_wifi_send, 214c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_audio, 215c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_video, 216c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang }; 217c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang values = new double[] { 218c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.cpuTime, 219c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.cpuFgTime, 220c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.wakeLockTime, 221c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.gpsTime, 222c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.wifiRunningTime, 223c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.mobileRxBytes, 224c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.mobileTxBytes, 225c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.wifiRxBytes, 226c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.wifiTxBytes, 227c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 0, 228c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 0 229c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang }; 230c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 231c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (sipper.drainType == DrainType.APP) { 232c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Writer result = new StringWriter(); 233c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang PrintWriter printWriter = new FastPrintWriter(result, false, 1024); 234c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mStats.dumpLocked(printWriter, "", mStatsType, uid.getUid()); 235c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang printWriter.flush(); 236c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang args.putString(PowerUsageDetail.EXTRA_REPORT_DETAILS, result.toString()); 237c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 238c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang result = new StringWriter(); 239c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang printWriter = new FastPrintWriter(result, false, 1024); 240c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mStats.dumpCheckinLocked(printWriter, mStatsType, uid.getUid()); 241c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang printWriter.flush(); 242c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang args.putString(PowerUsageDetail.EXTRA_REPORT_CHECKIN_DETAILS, 243c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang result.toString()); 244c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 245c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 246c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang break; 247c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang case CELL: 248c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang { 249c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang types = new int[] { 250c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_on_time, 251c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_no_coverage 252c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang }; 253c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang values = new double[] { 254c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.usageTime, 255c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.noCoveragePercent 256c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang }; 257c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 258c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang break; 259c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang case WIFI: 260c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang { 261c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang types = new int[] { 262c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_wifi_running, 263c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_cpu, 264c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_cpu_foreground, 265c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_wake_lock, 266c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_data_recv, 267c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_data_send, 268c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_data_wifi_recv, 269c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_data_wifi_send, 270c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang }; 271c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang values = new double[] { 272c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.usageTime, 273c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.cpuTime, 274c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.cpuFgTime, 275c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.wakeLockTime, 276c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.mobileRxBytes, 277c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.mobileTxBytes, 278c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.wifiRxBytes, 279c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.wifiTxBytes, 280c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang }; 281c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } break; 282c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang case BLUETOOTH: 283c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang { 284c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang types = new int[] { 285c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_on_time, 286c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_cpu, 287c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_cpu_foreground, 288c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_wake_lock, 289c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_data_recv, 290c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_data_send, 291c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_data_wifi_recv, 292c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_data_wifi_send, 293c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang }; 294c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang values = new double[] { 295c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.usageTime, 296c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.cpuTime, 297c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.cpuFgTime, 298c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.wakeLockTime, 299c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.mobileRxBytes, 300c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.mobileTxBytes, 301c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.wifiRxBytes, 302c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.wifiTxBytes, 303c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang }; 304c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } break; 305c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang default: 306c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang { 307c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang types = new int[] { 308c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_on_time 309c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang }; 310c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang values = new double[] { 311c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.usageTime 312c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang }; 313c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 314c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 315c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang args.putIntArray(PowerUsageDetail.EXTRA_DETAIL_TYPES, types); 316c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang args.putDoubleArray(PowerUsageDetail.EXTRA_DETAIL_VALUES, values); 317c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang caller.startPreferencePanel(PowerUsageDetail.class.getName(), args, 318c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.details_title, null, null, 0); 319c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 320c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 321c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang public void refreshStats() { 322c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // Initialize mStats if necessary. 323c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang getStats(); 324c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 325c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mMaxPower = 0; 326c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mTotalPower = 0; 327c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mWifiPower = 0; 328c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mBluetoothPower = 0; 329c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mAppWifiRunning = 0; 330c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 331c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mUsageList.clear(); 332c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mWifiSippers.clear(); 333c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mBluetoothSippers.clear(); 334c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mUserSippers.clear(); 335c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mUserPower.clear(); 336c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 337c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang processAppUsage(); 338c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang processMiscUsage(); 339c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 340c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Collections.sort(mUsageList); 341c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 342c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (mHandler != null) { 343c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang synchronized (mRequestQueue) { 344c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (!mRequestQueue.isEmpty()) { 345c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (mRequestThread != null) { 346c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mRequestThread.abort(); 347c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 348c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mRequestThread = new NameAndIconLoader(); 349c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mRequestThread.setPriority(Thread.MIN_PRIORITY); 350c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mRequestThread.start(); 351c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mRequestQueue.notify(); 352c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 353c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 354c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 355c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 356c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 357c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private void processAppUsage() { 358c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang SensorManager sensorManager = (SensorManager) mActivity.getSystemService( 359c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Context.SENSOR_SERVICE); 360c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final int which = mStatsType; 361c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final int speedSteps = mPowerProfile.getNumSpeedSteps(); 362c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final double[] powerCpuNormal = new double[speedSteps]; 363c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long[] cpuSpeedStepTimes = new long[speedSteps]; 364c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang for (int p = 0; p < speedSteps; p++) { 365c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang powerCpuNormal[p] = mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_ACTIVE, p); 366c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 367c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final double mobilePowerPerByte = getMobilePowerPerByte(); 368c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final double wifiPowerPerByte = getWifiPowerPerByte(); 369c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long uSecTime = mStats.computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which); 370c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long appWakelockTime = 0; 371c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang BatterySipper osApp = null; 372c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mStatsPeriod = uSecTime; 373c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang SparseArray<? extends Uid> uidStats = mStats.getUidStats(); 374c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final int NU = uidStats.size(); 375c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang for (int iu = 0; iu < NU; iu++) { 376c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Uid u = uidStats.valueAt(iu); 377c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang double p; // in mAs 378c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang double power = 0; // in mAs 379c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang double highestDrain = 0; 380c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang String packageWithHighestDrain = null; 381c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang //mUsageList.add(new AppUsage(u.getUid(), new double[] {power})); 382c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats(); 383c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long cpuTime = 0; 384c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long cpuFgTime = 0; 385c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long wakelockTime = 0; 386c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long gpsTime = 0; 387c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG) Log.i(TAG, "UID " + u.getUid()); 388c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (processStats.size() > 0) { 389c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // Process CPU time 390c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent 391c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang : processStats.entrySet()) { 392c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Uid.Proc ps = ent.getValue(); 393c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long userTime = ps.getUserTime(which); 394c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long systemTime = ps.getSystemTime(which); 395c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long foregroundTime = ps.getForegroundTime(which); 396c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang cpuFgTime += foregroundTime * 10; // convert to millis 397c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long tmpCpuTime = (userTime + systemTime) * 10; // convert to millis 398c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang int totalTimeAtSpeeds = 0; 399c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // Get the total first 400c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang for (int step = 0; step < speedSteps; step++) { 401c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang cpuSpeedStepTimes[step] = ps.getTimeAtCpuSpeedStep(step, which); 402c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang totalTimeAtSpeeds += cpuSpeedStepTimes[step]; 403c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 404c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (totalTimeAtSpeeds == 0) totalTimeAtSpeeds = 1; 405c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // Then compute the ratio of time spent at each speed 406c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang double processPower = 0; 407c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang for (int step = 0; step < speedSteps; step++) { 408c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang double ratio = (double) cpuSpeedStepTimes[step] / totalTimeAtSpeeds; 409c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang processPower += ratio * tmpCpuTime * powerCpuNormal[step]; 410c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 411c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang cpuTime += tmpCpuTime; 412c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG && processPower != 0) { 413c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Log.i(TAG, String.format("process %s, cpu power=%.2f", 414c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang ent.getKey(), processPower / 1000)); 415c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 416c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang power += processPower; 417c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (packageWithHighestDrain == null 418c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang || packageWithHighestDrain.startsWith("*")) { 419c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang highestDrain = processPower; 420c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang packageWithHighestDrain = ent.getKey(); 421c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } else if (highestDrain < processPower 422c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang && !ent.getKey().startsWith("*")) { 423c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang highestDrain = processPower; 424c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang packageWithHighestDrain = ent.getKey(); 425c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 426c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 427c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 428c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (cpuFgTime > cpuTime) { 429c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG && cpuFgTime > cpuTime + 10000) { 430c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Log.i(TAG, "WARNING! Cputime is more than 10 seconds behind Foreground time"); 431c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 432c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang cpuTime = cpuFgTime; // Statistics may not have been gathered yet. 433c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 434c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang power /= 1000; 435c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG && power != 0) Log.i(TAG, String.format("total cpu power=%.2f", power)); 436c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 437c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // Process wake lock usage 438c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Map<String, ? extends BatteryStats.Uid.Wakelock> wakelockStats = u.getWakelockStats(); 439c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> wakelockEntry 440c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang : wakelockStats.entrySet()) { 441c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Uid.Wakelock wakelock = wakelockEntry.getValue(); 442c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // Only care about partial wake locks since full wake locks 443c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // are canceled when the user turns the screen off. 444c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang BatteryStats.Timer timer = wakelock.getWakeTime(BatteryStats.WAKE_TYPE_PARTIAL); 445c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (timer != null) { 446c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang wakelockTime += timer.getTotalTimeLocked(uSecTime, which); 447c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 448c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 449c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang wakelockTime /= 1000; // convert to millis 450c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang appWakelockTime += wakelockTime; 451c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 452c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // Add cost of holding a wake lock 453c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang p = (wakelockTime 454c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_AWAKE)) / 1000; 455c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang power += p; 456c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG && p != 0) Log.i(TAG, String.format("wakelock power=%.2f", p)); 457c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 458c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // Add cost of mobile traffic 459c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long mobileRx = u.getNetworkActivityCount(NETWORK_MOBILE_RX_BYTES, mStatsType); 460c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long mobileTx = u.getNetworkActivityCount(NETWORK_MOBILE_TX_BYTES, mStatsType); 461c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang p = (mobileRx + mobileTx) * mobilePowerPerByte; 462c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang power += p; 463c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG && p != 0) Log.i(TAG, String.format("mobile power=%.2f", p)); 464c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 465c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // Add cost of wifi traffic 466c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long wifiRx = u.getNetworkActivityCount(NETWORK_WIFI_RX_BYTES, mStatsType); 467c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long wifiTx = u.getNetworkActivityCount(NETWORK_WIFI_TX_BYTES, mStatsType); 468c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang p = (wifiRx + wifiTx) * wifiPowerPerByte; 469c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang power += p; 470c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG && p != 0) Log.i(TAG, String.format("wifi power=%.2f", p)); 471c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 472c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // Add cost of keeping WIFI running. 473c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long wifiRunningTimeMs = u.getWifiRunningTime(uSecTime, which) / 1000; 474c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mAppWifiRunning += wifiRunningTimeMs; 475c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang p = (wifiRunningTimeMs 476c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_ON)) / 1000; 477c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang power += p; 478c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG && p != 0) Log.i(TAG, String.format("wifi running power=%.2f", p)); 479c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 480c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // Add cost of WIFI scans 481c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long wifiScanTimeMs = u.getWifiScanTime(uSecTime, which) / 1000; 482c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang p = (wifiScanTimeMs 483c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_SCAN)) / 1000; 484c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang power += p; 485c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG && p != 0) Log.i(TAG, String.format("wifi scanning power=%.2f", p)); 486c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 487c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // Process Sensor usage 488c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Map<Integer, ? extends BatteryStats.Uid.Sensor> sensorStats = u.getSensorStats(); 489c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> sensorEntry 490c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang : sensorStats.entrySet()) { 491c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Uid.Sensor sensor = sensorEntry.getValue(); 492c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang int sensorHandle = sensor.getHandle(); 493c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang BatteryStats.Timer timer = sensor.getSensorTime(); 494c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long sensorTime = timer.getTotalTimeLocked(uSecTime, which) / 1000; 495c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang double multiplier = 0; 496c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang switch (sensorHandle) { 497c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang case Uid.Sensor.GPS: 498c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang multiplier = mPowerProfile.getAveragePower(PowerProfile.POWER_GPS_ON); 499c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang gpsTime = sensorTime; 500c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang break; 501c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang default: 502c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang List<Sensor> sensorList = sensorManager.getSensorList( 503c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang android.hardware.Sensor.TYPE_ALL); 504c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang for (android.hardware.Sensor s : sensorList) { 505c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (s.getHandle() == sensorHandle) { 506c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang multiplier = s.getPower(); 507c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang break; 508c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 509c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 510c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 511c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang p = (multiplier * sensorTime) / 1000; 512c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang power += p; 513c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG && p != 0) { 514c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Log.i(TAG, String.format("sensor %s power=%.2f", sensor.toString(), p)); 515c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 516c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 517c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 518c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG) Log.i(TAG, String.format("UID %d total power=%.2f", u.getUid(), power)); 519c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 520c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // Add the app to the list if it is consuming power 521c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang boolean isOtherUser = false; 522c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final int userId = UserHandle.getUserId(u.getUid()); 523c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (power != 0 || u.getUid() == 0) { 524c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang BatterySipper app = new BatterySipper(mActivity, mRequestQueue, mHandler, 525c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang packageWithHighestDrain, DrainType.APP, 0, u, 526c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang new double[] {power}); 527c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang app.cpuTime = cpuTime; 528c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang app.gpsTime = gpsTime; 529c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang app.wifiRunningTime = wifiRunningTimeMs; 530c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang app.cpuFgTime = cpuFgTime; 531c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang app.wakeLockTime = wakelockTime; 532c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang app.mobileRxBytes = mobileRx; 533c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang app.mobileTxBytes = mobileTx; 534c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang app.wifiRxBytes = wifiRx; 535c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang app.wifiTxBytes = wifiTx; 536c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (u.getUid() == Process.WIFI_UID) { 537c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mWifiSippers.add(app); 538c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } else if (u.getUid() == Process.BLUETOOTH_UID) { 539c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mBluetoothSippers.add(app); 540c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } else if (userId != UserHandle.myUserId() 541c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang && UserHandle.getAppId(u.getUid()) >= Process.FIRST_APPLICATION_UID) { 542c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang isOtherUser = true; 543c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang List<BatterySipper> list = mUserSippers.get(userId); 544c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (list == null) { 545c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang list = new ArrayList<BatterySipper>(); 546c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mUserSippers.put(userId, list); 547c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 548c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang list.add(app); 549c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } else { 550c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mUsageList.add(app); 551c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 552c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (u.getUid() == 0) { 553c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang osApp = app; 554c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 555c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 556c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (power != 0) { 557c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (u.getUid() == Process.WIFI_UID) { 558c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mWifiPower += power; 559c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } else if (u.getUid() == Process.BLUETOOTH_UID) { 560c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mBluetoothPower += power; 561c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } else if (isOtherUser) { 562c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Double userPower = mUserPower.get(userId); 563c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (userPower == null) { 564c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang userPower = power; 565c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } else { 566c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang userPower += power; 567c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 568c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mUserPower.put(userId, userPower); 569c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } else { 570c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (power > mMaxPower) mMaxPower = power; 571c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mTotalPower += power; 572c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 573c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 574c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 575c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 576c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // The device has probably been awake for longer than the screen on 577c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // time and application wake lock time would account for. Assign 578c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // this remainder to the OS, if possible. 579c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (osApp != null) { 580c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long wakeTimeMillis = mStats.computeBatteryUptime( 581c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang SystemClock.uptimeMillis() * 1000, which) / 1000; 582c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang wakeTimeMillis -= appWakelockTime + (mStats.getScreenOnTime( 583c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang SystemClock.elapsedRealtime(), which) / 1000); 584c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (wakeTimeMillis > 0) { 585c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang double power = (wakeTimeMillis 586c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_AWAKE)) / 1000; 587c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG) Log.i(TAG, "OS wakeLockTime " + wakeTimeMillis + " power " + power); 588c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang osApp.wakeLockTime += wakeTimeMillis; 589c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang osApp.value += power; 590c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang osApp.values[0] += power; 591c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (osApp.value > mMaxPower) mMaxPower = osApp.value; 592c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mTotalPower += power; 593c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 594c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 595c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 596c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 597c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private void addPhoneUsage(long uSecNow) { 598c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long phoneOnTimeMs = mStats.getPhoneOnTime(uSecNow, mStatsType) / 1000; 599c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang double phoneOnPower = mPowerProfile.getAveragePower(PowerProfile.POWER_RADIO_ACTIVE) 600c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * phoneOnTimeMs / 1000; 601c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang addEntry(mActivity.getString(R.string.power_phone), DrainType.PHONE, phoneOnTimeMs, 602c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.drawable.ic_settings_voice_calls, phoneOnPower); 603c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 604c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 605c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private void addScreenUsage(long uSecNow) { 606c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang double power = 0; 607c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long screenOnTimeMs = mStats.getScreenOnTime(uSecNow, mStatsType) / 1000; 608c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang power += screenOnTimeMs * mPowerProfile.getAveragePower(PowerProfile.POWER_SCREEN_ON); 609c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final double screenFullPower = 610c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mPowerProfile.getAveragePower(PowerProfile.POWER_SCREEN_FULL); 611c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang for (int i = 0; i < BatteryStats.NUM_SCREEN_BRIGHTNESS_BINS; i++) { 612c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang double screenBinPower = screenFullPower * (i + 0.5f) 613c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang / BatteryStats.NUM_SCREEN_BRIGHTNESS_BINS; 614c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long brightnessTime = mStats.getScreenBrightnessTime(i, uSecNow, mStatsType) / 1000; 615c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang power += screenBinPower * brightnessTime; 616c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG) { 617c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Log.i(TAG, "Screen bin power = " + (int) screenBinPower + ", time = " 618c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang + brightnessTime); 619c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 620c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 621c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang power /= 1000; // To seconds 622c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang addEntry(mActivity.getString(R.string.power_screen), DrainType.SCREEN, screenOnTimeMs, 623c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.drawable.ic_settings_display, power); 624c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 625c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 626c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private void addRadioUsage(long uSecNow) { 627c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang double power = 0; 628c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final int BINS = SignalStrength.NUM_SIGNAL_STRENGTH_BINS; 629c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long signalTimeMs = 0; 630c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang for (int i = 0; i < BINS; i++) { 631c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long strengthTimeMs = mStats.getPhoneSignalStrengthTime(i, uSecNow, mStatsType) / 1000; 632c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang power += strengthTimeMs / 1000 633c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * mPowerProfile.getAveragePower(PowerProfile.POWER_RADIO_ON, i); 634c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang signalTimeMs += strengthTimeMs; 635c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 636c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long scanningTimeMs = mStats.getPhoneSignalScanningTime(uSecNow, mStatsType) / 1000; 637c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang power += scanningTimeMs / 1000 * mPowerProfile.getAveragePower( 638c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang PowerProfile.POWER_RADIO_SCANNING); 639c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang BatterySipper bs = 640c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang addEntry(mActivity.getString(R.string.power_cell), DrainType.CELL, 641c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang signalTimeMs, R.drawable.ic_settings_cell_standby, power); 642c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (signalTimeMs != 0) { 643c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang bs.noCoveragePercent = mStats.getPhoneSignalStrengthTime(0, uSecNow, mStatsType) 644c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang / 1000 * 100.0 / signalTimeMs; 645c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 646c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 647c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 648c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private void aggregateSippers(BatterySipper bs, List<BatterySipper> from, String tag) { 649c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang for (int i=0; i<from.size(); i++) { 650c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang BatterySipper wbs = from.get(i); 651c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG) Log.i(TAG, tag + " adding sipper " + wbs + ": cpu=" + wbs.cpuTime); 652c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang bs.cpuTime += wbs.cpuTime; 653c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang bs.gpsTime += wbs.gpsTime; 654c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang bs.wifiRunningTime += wbs.wifiRunningTime; 655c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang bs.cpuFgTime += wbs.cpuFgTime; 656c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang bs.wakeLockTime += wbs.wakeLockTime; 657c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang bs.mobileRxBytes += wbs.mobileRxBytes; 658c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang bs.mobileTxBytes += wbs.mobileTxBytes; 659c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang bs.wifiRxBytes += wbs.wifiRxBytes; 660c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang bs.wifiTxBytes += wbs.wifiTxBytes; 661c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 662c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 663c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 664c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private void addWiFiUsage(long uSecNow) { 665c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long onTimeMs = mStats.getWifiOnTime(uSecNow, mStatsType) / 1000; 666c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long runningTimeMs = mStats.getGlobalWifiRunningTime(uSecNow, mStatsType) / 1000; 667c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG) Log.i(TAG, "WIFI runningTime=" + runningTimeMs 668c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang + " app runningTime=" + mAppWifiRunning); 669c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang runningTimeMs -= mAppWifiRunning; 670c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (runningTimeMs < 0) runningTimeMs = 0; 671c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang double wifiPower = (onTimeMs * 0 /* TODO */ 672c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_ON) 673c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang + runningTimeMs * mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_ON)) / 1000; 674c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG) Log.i(TAG, "WIFI power=" + wifiPower + " from procs=" + mWifiPower); 675c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang BatterySipper bs = addEntry(mActivity.getString(R.string.power_wifi), DrainType.WIFI, 676c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang runningTimeMs, R.drawable.ic_settings_wifi, wifiPower + mWifiPower); 677c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang aggregateSippers(bs, mWifiSippers, "WIFI"); 678c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 679c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 680c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private void addIdleUsage(long uSecNow) { 681c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long idleTimeMs = (uSecNow - mStats.getScreenOnTime(uSecNow, mStatsType)) / 1000; 682c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang double idlePower = (idleTimeMs * mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_IDLE)) 683c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang / 1000; 684c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang addEntry(mActivity.getString(R.string.power_idle), DrainType.IDLE, idleTimeMs, 685c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.drawable.ic_settings_phone_idle, idlePower); 686c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 687c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 688c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private void addBluetoothUsage(long uSecNow) { 689c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long btOnTimeMs = mStats.getBluetoothOnTime(uSecNow, mStatsType) / 1000; 690c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang double btPower = btOnTimeMs * mPowerProfile.getAveragePower(PowerProfile.POWER_BLUETOOTH_ON) 691c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang / 1000; 692c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang int btPingCount = mStats.getBluetoothPingCount(); 693c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang btPower += (btPingCount 694c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * mPowerProfile.getAveragePower(PowerProfile.POWER_BLUETOOTH_AT_CMD)) / 1000; 695c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang BatterySipper bs = addEntry(mActivity.getString(R.string.power_bluetooth), 696c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang DrainType.BLUETOOTH, btOnTimeMs, R.drawable.ic_settings_bluetooth, 697c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang btPower + mBluetoothPower); 698c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang aggregateSippers(bs, mBluetoothSippers, "Bluetooth"); 699c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 700c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 701c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private void addUserUsage() { 702c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang for (int i=0; i<mUserSippers.size(); i++) { 703c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final int userId = mUserSippers.keyAt(i); 704c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final List<BatterySipper> sippers = mUserSippers.valueAt(i); 705c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang UserInfo info = mUm.getUserInfo(userId); 706c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Drawable icon; 707c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang String name; 708c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (info != null) { 709c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang icon = UserUtils.getUserIcon(mActivity, mUm, info, mActivity.getResources()); 710c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang name = info != null ? info.name : null; 711c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (name == null) { 712c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang name = Integer.toString(info.id); 713c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 714c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang name = mActivity.getResources().getString( 715c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.running_process_item_user_label, name); 716c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } else { 717c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang icon = null; 718c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang name = mActivity.getResources().getString( 719c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.running_process_item_removed_user_label); 720c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 721c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang double power = mUserPower.get(userId); 722c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang BatterySipper bs = addEntry(name, DrainType.USER, 0, 0, power); 723c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang bs.icon = icon; 724c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang aggregateSippers(bs, sippers, "User"); 725c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 726c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 727c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 728c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang /** 729c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * Return estimated power (in mAs) of sending a byte with the mobile radio. 730c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang */ 731c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private double getMobilePowerPerByte() { 732c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long MOBILE_BPS = 200000; // TODO: Extract average bit rates from system 733c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final double MOBILE_POWER = mPowerProfile.getAveragePower(PowerProfile.POWER_RADIO_ACTIVE) 734c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang / 3600; 735c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 736c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long mobileRx = mStats.getNetworkActivityCount(NETWORK_MOBILE_RX_BYTES, mStatsType); 737c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long mobileTx = mStats.getNetworkActivityCount(NETWORK_MOBILE_TX_BYTES, mStatsType); 738c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long mobileData = mobileRx + mobileTx; 739c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 740c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long radioDataUptimeMs = mStats.getRadioDataUptime() / 1000; 741c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long mobileBps = radioDataUptimeMs != 0 742c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang ? mobileData * 8 * 1000 / radioDataUptimeMs 743c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang : MOBILE_BPS; 744c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 745c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang return MOBILE_POWER / (mobileBps / 8); 746c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 747c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 748c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang /** 749c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * Return estimated power (in mAs) of sending a byte with the Wi-Fi radio. 750c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang */ 751c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private double getWifiPowerPerByte() { 752c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long WIFI_BPS = 1000000; // TODO: Extract average bit rates from system 753c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final double WIFI_POWER = mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_ACTIVE) 754c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang / 3600; 755c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang return WIFI_POWER / (WIFI_BPS / 8); 756c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 757c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 758c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private void processMiscUsage() { 759c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final int which = mStatsType; 760c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long uSecTime = SystemClock.elapsedRealtime() * 1000; 761c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long uSecNow = mStats.computeBatteryRealtime(uSecTime, which); 762c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long timeSinceUnplugged = uSecNow; 763c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG) { 764c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Log.i(TAG, "Uptime since last unplugged = " + (timeSinceUnplugged / 1000)); 765c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 766c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 767c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang addUserUsage(); 768c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang addPhoneUsage(uSecNow); 769c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang addScreenUsage(uSecNow); 770c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang addWiFiUsage(uSecNow); 771c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang addBluetoothUsage(uSecNow); 772c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang addIdleUsage(uSecNow); // Not including cellular idle power 773c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // Don't compute radio usage if it's a wifi-only device 774c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (!com.android.settings.Utils.isWifiOnly(mActivity)) { 775c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang addRadioUsage(uSecNow); 776c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 777c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 778c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 779c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private BatterySipper addEntry(String label, DrainType drainType, long time, int iconId, 780c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang double power) { 781c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (power > mMaxPower) mMaxPower = power; 782c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mTotalPower += power; 783c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang BatterySipper bs = new BatterySipper(mActivity, mRequestQueue, mHandler, 784c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang label, drainType, iconId, null, new double[] {power}); 785c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang bs.usageTime = time; 786c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang bs.iconId = iconId; 787c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mUsageList.add(bs); 788c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang return bs; 789c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 790c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 791c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang public List<BatterySipper> getUsageList() { 792c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang return mUsageList; 793c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 794c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 795c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang static final int MSG_UPDATE_NAME_ICON = 1; 796c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang static final int MSG_REPORT_FULLY_DRAWN = 2; 797c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 798c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang public double getMaxPower() { 799c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang return mMaxPower; 800c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 801c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 802c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang public double getTotalPower() { 803c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang return mTotalPower; 804c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 805c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 806c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private void load() { 807c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang try { 808c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang byte[] data = mBatteryInfo.getStatistics(); 809c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Parcel parcel = Parcel.obtain(); 810c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang parcel.unmarshall(data, 0, data.length); 811c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang parcel.setDataPosition(0); 812c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mStats = com.android.internal.os.BatteryStatsImpl.CREATOR 813c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang .createFromParcel(parcel); 814c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mStats.distributeWorkLocked(BatteryStats.STATS_SINCE_CHARGED); 815c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } catch (RemoteException e) { 816c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Log.e(TAG, "RemoteException:", e); 817c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 818c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 819c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang} 820