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 178bfa96c3b10f53a969406755eed36ba98fc1de549Lifu Tang public void startBatteryDetailPage( 179bfa96c3b10f53a969406755eed36ba98fc1de549Lifu Tang PreferenceActivity caller, BatterySipper sipper, boolean showLocationButton) { 180c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // Initialize mStats if necessary. 181c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang getStats(); 182c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 183c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Bundle args = new Bundle(); 184c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang args.putString(PowerUsageDetail.EXTRA_TITLE, sipper.name); 185c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang args.putInt(PowerUsageDetail.EXTRA_PERCENT, (int) 186c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Math.ceil(sipper.getSortValue() * 100 / mTotalPower)); 187c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang args.putInt(PowerUsageDetail.EXTRA_GAUGE, (int) 188c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Math.ceil(sipper.getSortValue() * 100 / mMaxPower)); 189c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang args.putLong(PowerUsageDetail.EXTRA_USAGE_DURATION, mStatsPeriod); 190c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang args.putString(PowerUsageDetail.EXTRA_ICON_PACKAGE, sipper.defaultPackageName); 191c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang args.putInt(PowerUsageDetail.EXTRA_ICON_ID, sipper.iconId); 192c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang args.putDouble(PowerUsageDetail.EXTRA_NO_COVERAGE, sipper.noCoveragePercent); 193c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (sipper.uidObj != null) { 194c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang args.putInt(PowerUsageDetail.EXTRA_UID, sipper.uidObj.getUid()); 195c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 196c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang args.putSerializable(PowerUsageDetail.EXTRA_DRAIN_TYPE, sipper.drainType); 197bfa96c3b10f53a969406755eed36ba98fc1de549Lifu Tang args.putBoolean(PowerUsageDetail.EXTRA_SHOW_LOCATION_BUTTON, showLocationButton); 198c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 199c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang int[] types; 200c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang double[] values; 201c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang switch (sipper.drainType) { 202c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang case APP: 203c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang case USER: 204c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang { 205c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Uid uid = sipper.uidObj; 206c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang types = new int[] { 207c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_cpu, 208c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_cpu_foreground, 209c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_wake_lock, 210c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_gps, 211c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_wifi_running, 212c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_data_recv, 213c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_data_send, 214c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_data_wifi_recv, 215c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_data_wifi_send, 216c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_audio, 217c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_video, 218c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang }; 219c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang values = new double[] { 220c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.cpuTime, 221c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.cpuFgTime, 222c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.wakeLockTime, 223c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.gpsTime, 224c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.wifiRunningTime, 225c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.mobileRxBytes, 226c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.mobileTxBytes, 227c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.wifiRxBytes, 228c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.wifiTxBytes, 229c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 0, 230c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 0 231c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang }; 232c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 233c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (sipper.drainType == DrainType.APP) { 234c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Writer result = new StringWriter(); 235c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang PrintWriter printWriter = new FastPrintWriter(result, false, 1024); 236c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mStats.dumpLocked(printWriter, "", mStatsType, uid.getUid()); 237c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang printWriter.flush(); 238c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang args.putString(PowerUsageDetail.EXTRA_REPORT_DETAILS, result.toString()); 239c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 240c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang result = new StringWriter(); 241c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang printWriter = new FastPrintWriter(result, false, 1024); 242c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mStats.dumpCheckinLocked(printWriter, mStatsType, uid.getUid()); 243c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang printWriter.flush(); 244c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang args.putString(PowerUsageDetail.EXTRA_REPORT_CHECKIN_DETAILS, 245c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang result.toString()); 246c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 247c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 248c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang break; 249c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang case CELL: 250c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang { 251c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang types = new int[] { 252c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_on_time, 253c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_no_coverage 254c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang }; 255c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang values = new double[] { 256c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.usageTime, 257c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.noCoveragePercent 258c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang }; 259c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 260c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang break; 261c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang case WIFI: 262c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang { 263c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang types = new int[] { 264c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_wifi_running, 265c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_cpu, 266c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_cpu_foreground, 267c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_wake_lock, 268c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_data_recv, 269c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_data_send, 270c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_data_wifi_recv, 271c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_data_wifi_send, 272c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang }; 273c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang values = new double[] { 274c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.usageTime, 275c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.cpuTime, 276c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.cpuFgTime, 277c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.wakeLockTime, 278c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.mobileRxBytes, 279c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.mobileTxBytes, 280c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.wifiRxBytes, 281c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.wifiTxBytes, 282c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang }; 283c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } break; 284c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang case BLUETOOTH: 285c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang { 286c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang types = new int[] { 287c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_on_time, 288c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_cpu, 289c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_cpu_foreground, 290c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_wake_lock, 291c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_data_recv, 292c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_data_send, 293c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_data_wifi_recv, 294c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_data_wifi_send, 295c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang }; 296c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang values = new double[] { 297c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.usageTime, 298c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.cpuTime, 299c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.cpuFgTime, 300c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.wakeLockTime, 301c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.mobileRxBytes, 302c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.mobileTxBytes, 303c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.wifiRxBytes, 304c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.wifiTxBytes, 305c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang }; 306c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } break; 307c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang default: 308c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang { 309c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang types = new int[] { 310c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.usage_type_on_time 311c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang }; 312c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang values = new double[] { 313c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang sipper.usageTime 314c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang }; 315c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 316c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 317c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang args.putIntArray(PowerUsageDetail.EXTRA_DETAIL_TYPES, types); 318c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang args.putDoubleArray(PowerUsageDetail.EXTRA_DETAIL_VALUES, values); 319c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang caller.startPreferencePanel(PowerUsageDetail.class.getName(), args, 320c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.details_title, null, null, 0); 321c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 322c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 323ad7bfbd3469b0dfd42c6bc9d25b22c29d52fbdadLifu Tang /** 324ad7bfbd3469b0dfd42c6bc9d25b22c29d52fbdadLifu Tang * Refreshes the power usage list. 325ad7bfbd3469b0dfd42c6bc9d25b22c29d52fbdadLifu Tang * @param includeZeroConsumption whether includes those applications which have consumed very 326ad7bfbd3469b0dfd42c6bc9d25b22c29d52fbdadLifu Tang * little power up till now. 327ad7bfbd3469b0dfd42c6bc9d25b22c29d52fbdadLifu Tang */ 328ad7bfbd3469b0dfd42c6bc9d25b22c29d52fbdadLifu Tang public void refreshStats(boolean includeZeroConsumption) { 329c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // Initialize mStats if necessary. 330c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang getStats(); 331c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 332c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mMaxPower = 0; 333c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mTotalPower = 0; 334c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mWifiPower = 0; 335c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mBluetoothPower = 0; 336c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mAppWifiRunning = 0; 337c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 338c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mUsageList.clear(); 339c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mWifiSippers.clear(); 340c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mBluetoothSippers.clear(); 341c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mUserSippers.clear(); 342c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mUserPower.clear(); 343c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 344ad7bfbd3469b0dfd42c6bc9d25b22c29d52fbdadLifu Tang processAppUsage(includeZeroConsumption); 345c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang processMiscUsage(); 346c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 347c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Collections.sort(mUsageList); 348c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 349c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (mHandler != null) { 350c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang synchronized (mRequestQueue) { 351c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (!mRequestQueue.isEmpty()) { 352c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (mRequestThread != null) { 353c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mRequestThread.abort(); 354c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 355c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mRequestThread = new NameAndIconLoader(); 356c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mRequestThread.setPriority(Thread.MIN_PRIORITY); 357c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mRequestThread.start(); 358c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mRequestQueue.notify(); 359c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 360c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 361c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 362c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 363c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 364ad7bfbd3469b0dfd42c6bc9d25b22c29d52fbdadLifu Tang private void processAppUsage(boolean includeZeroConsumption) { 365c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang SensorManager sensorManager = (SensorManager) mActivity.getSystemService( 366c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Context.SENSOR_SERVICE); 367c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final int which = mStatsType; 368c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final int speedSteps = mPowerProfile.getNumSpeedSteps(); 369c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final double[] powerCpuNormal = new double[speedSteps]; 370c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long[] cpuSpeedStepTimes = new long[speedSteps]; 371c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang for (int p = 0; p < speedSteps; p++) { 372c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang powerCpuNormal[p] = mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_ACTIVE, p); 373c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 374c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final double mobilePowerPerByte = getMobilePowerPerByte(); 375c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final double wifiPowerPerByte = getWifiPowerPerByte(); 376c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long uSecTime = mStats.computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which); 377c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long appWakelockTime = 0; 378c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang BatterySipper osApp = null; 379c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mStatsPeriod = uSecTime; 380c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang SparseArray<? extends Uid> uidStats = mStats.getUidStats(); 381c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final int NU = uidStats.size(); 382c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang for (int iu = 0; iu < NU; iu++) { 383c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Uid u = uidStats.valueAt(iu); 384c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang double p; // in mAs 385c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang double power = 0; // in mAs 386c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang double highestDrain = 0; 387c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang String packageWithHighestDrain = null; 388c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang //mUsageList.add(new AppUsage(u.getUid(), new double[] {power})); 389c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats(); 390c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long cpuTime = 0; 391c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long cpuFgTime = 0; 392c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long wakelockTime = 0; 393c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long gpsTime = 0; 394c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG) Log.i(TAG, "UID " + u.getUid()); 395c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (processStats.size() > 0) { 396c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // Process CPU time 397c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent 398c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang : processStats.entrySet()) { 399c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Uid.Proc ps = ent.getValue(); 400c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long userTime = ps.getUserTime(which); 401c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long systemTime = ps.getSystemTime(which); 402c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long foregroundTime = ps.getForegroundTime(which); 403c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang cpuFgTime += foregroundTime * 10; // convert to millis 404c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long tmpCpuTime = (userTime + systemTime) * 10; // convert to millis 405c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang int totalTimeAtSpeeds = 0; 406c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // Get the total first 407c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang for (int step = 0; step < speedSteps; step++) { 408c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang cpuSpeedStepTimes[step] = ps.getTimeAtCpuSpeedStep(step, which); 409c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang totalTimeAtSpeeds += cpuSpeedStepTimes[step]; 410c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 411c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (totalTimeAtSpeeds == 0) totalTimeAtSpeeds = 1; 412c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // Then compute the ratio of time spent at each speed 413c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang double processPower = 0; 414c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang for (int step = 0; step < speedSteps; step++) { 415c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang double ratio = (double) cpuSpeedStepTimes[step] / totalTimeAtSpeeds; 416c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang processPower += ratio * tmpCpuTime * powerCpuNormal[step]; 417c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 418c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang cpuTime += tmpCpuTime; 419c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG && processPower != 0) { 420c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Log.i(TAG, String.format("process %s, cpu power=%.2f", 421c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang ent.getKey(), processPower / 1000)); 422c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 423c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang power += processPower; 424c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (packageWithHighestDrain == null 425c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang || packageWithHighestDrain.startsWith("*")) { 426c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang highestDrain = processPower; 427c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang packageWithHighestDrain = ent.getKey(); 428c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } else if (highestDrain < processPower 429c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang && !ent.getKey().startsWith("*")) { 430c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang highestDrain = processPower; 431c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang packageWithHighestDrain = ent.getKey(); 432c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 433c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 434c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 435c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (cpuFgTime > cpuTime) { 436c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG && cpuFgTime > cpuTime + 10000) { 437c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Log.i(TAG, "WARNING! Cputime is more than 10 seconds behind Foreground time"); 438c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 439c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang cpuTime = cpuFgTime; // Statistics may not have been gathered yet. 440c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 441c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang power /= 1000; 442c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG && power != 0) Log.i(TAG, String.format("total cpu power=%.2f", power)); 443c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 444c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // Process wake lock usage 445c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Map<String, ? extends BatteryStats.Uid.Wakelock> wakelockStats = u.getWakelockStats(); 446c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> wakelockEntry 447c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang : wakelockStats.entrySet()) { 448c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Uid.Wakelock wakelock = wakelockEntry.getValue(); 449c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // Only care about partial wake locks since full wake locks 450c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // are canceled when the user turns the screen off. 451c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang BatteryStats.Timer timer = wakelock.getWakeTime(BatteryStats.WAKE_TYPE_PARTIAL); 452c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (timer != null) { 453c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang wakelockTime += timer.getTotalTimeLocked(uSecTime, which); 454c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 455c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 456c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang wakelockTime /= 1000; // convert to millis 457c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang appWakelockTime += wakelockTime; 458c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 459c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // Add cost of holding a wake lock 460c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang p = (wakelockTime 461c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_AWAKE)) / 1000; 462c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang power += p; 463c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG && p != 0) Log.i(TAG, String.format("wakelock power=%.2f", p)); 464c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 465c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // Add cost of mobile traffic 466c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long mobileRx = u.getNetworkActivityCount(NETWORK_MOBILE_RX_BYTES, mStatsType); 467c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long mobileTx = u.getNetworkActivityCount(NETWORK_MOBILE_TX_BYTES, mStatsType); 468c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang p = (mobileRx + mobileTx) * mobilePowerPerByte; 469c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang power += p; 470c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG && p != 0) Log.i(TAG, String.format("mobile power=%.2f", p)); 471c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 472c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // Add cost of wifi traffic 473c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long wifiRx = u.getNetworkActivityCount(NETWORK_WIFI_RX_BYTES, mStatsType); 474c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long wifiTx = u.getNetworkActivityCount(NETWORK_WIFI_TX_BYTES, mStatsType); 475c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang p = (wifiRx + wifiTx) * wifiPowerPerByte; 476c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang power += p; 477c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG && p != 0) Log.i(TAG, String.format("wifi power=%.2f", p)); 478c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 479c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // Add cost of keeping WIFI running. 480c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long wifiRunningTimeMs = u.getWifiRunningTime(uSecTime, which) / 1000; 481c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mAppWifiRunning += wifiRunningTimeMs; 482c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang p = (wifiRunningTimeMs 483c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_ON)) / 1000; 484c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang power += p; 485c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG && p != 0) Log.i(TAG, String.format("wifi running power=%.2f", p)); 486c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 487c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // Add cost of WIFI scans 488c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long wifiScanTimeMs = u.getWifiScanTime(uSecTime, which) / 1000; 489c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang p = (wifiScanTimeMs 490c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_SCAN)) / 1000; 491c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang power += p; 492c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG && p != 0) Log.i(TAG, String.format("wifi scanning power=%.2f", p)); 49321a2eb5aeae57985356f60db476234fa4cf1a6fbRobert Greenwalt for (int bin = 0; bin < BatteryStats.Uid.NUM_WIFI_BATCHED_SCAN_BINS; bin++) { 49421a2eb5aeae57985356f60db476234fa4cf1a6fbRobert Greenwalt long batchScanTimeMs = u.getWifiBatchedScanTime(bin, uSecTime, which) / 1000; 49521a2eb5aeae57985356f60db476234fa4cf1a6fbRobert Greenwalt p = (batchScanTimeMs 49621a2eb5aeae57985356f60db476234fa4cf1a6fbRobert Greenwalt * mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_BATCHED_SCAN, bin)); 49721a2eb5aeae57985356f60db476234fa4cf1a6fbRobert Greenwalt power += p; 49821a2eb5aeae57985356f60db476234fa4cf1a6fbRobert Greenwalt if (DEBUG && p != 0) { 49921a2eb5aeae57985356f60db476234fa4cf1a6fbRobert Greenwalt Log.i(TAG, String.format("wifi batched scanning lvl %d = %.2f", bin, p)); 50021a2eb5aeae57985356f60db476234fa4cf1a6fbRobert Greenwalt } 50121a2eb5aeae57985356f60db476234fa4cf1a6fbRobert Greenwalt } 502c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 503c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // Process Sensor usage 504c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Map<Integer, ? extends BatteryStats.Uid.Sensor> sensorStats = u.getSensorStats(); 505c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> sensorEntry 506c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang : sensorStats.entrySet()) { 507c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Uid.Sensor sensor = sensorEntry.getValue(); 508c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang int sensorHandle = sensor.getHandle(); 509c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang BatteryStats.Timer timer = sensor.getSensorTime(); 510c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long sensorTime = timer.getTotalTimeLocked(uSecTime, which) / 1000; 511c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang double multiplier = 0; 512c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang switch (sensorHandle) { 513c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang case Uid.Sensor.GPS: 514c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang multiplier = mPowerProfile.getAveragePower(PowerProfile.POWER_GPS_ON); 515c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang gpsTime = sensorTime; 516c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang break; 517c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang default: 518c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang List<Sensor> sensorList = sensorManager.getSensorList( 519c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang android.hardware.Sensor.TYPE_ALL); 520c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang for (android.hardware.Sensor s : sensorList) { 521c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (s.getHandle() == sensorHandle) { 522c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang multiplier = s.getPower(); 523c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang break; 524c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 525c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 526c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 527c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang p = (multiplier * sensorTime) / 1000; 528c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang power += p; 529c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG && p != 0) { 530c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Log.i(TAG, String.format("sensor %s power=%.2f", sensor.toString(), p)); 531c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 532c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 533c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 534c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG) Log.i(TAG, String.format("UID %d total power=%.2f", u.getUid(), power)); 535c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 536c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // Add the app to the list if it is consuming power 537c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang boolean isOtherUser = false; 538c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final int userId = UserHandle.getUserId(u.getUid()); 539ad7bfbd3469b0dfd42c6bc9d25b22c29d52fbdadLifu Tang if (power != 0 || includeZeroConsumption || u.getUid() == 0) { 540c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang BatterySipper app = new BatterySipper(mActivity, mRequestQueue, mHandler, 541c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang packageWithHighestDrain, DrainType.APP, 0, u, 542c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang new double[] {power}); 543c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang app.cpuTime = cpuTime; 544c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang app.gpsTime = gpsTime; 545c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang app.wifiRunningTime = wifiRunningTimeMs; 546c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang app.cpuFgTime = cpuFgTime; 547c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang app.wakeLockTime = wakelockTime; 548c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang app.mobileRxBytes = mobileRx; 549c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang app.mobileTxBytes = mobileTx; 550c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang app.wifiRxBytes = wifiRx; 551c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang app.wifiTxBytes = wifiTx; 552c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (u.getUid() == Process.WIFI_UID) { 553c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mWifiSippers.add(app); 554c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } else if (u.getUid() == Process.BLUETOOTH_UID) { 555c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mBluetoothSippers.add(app); 556c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } else if (userId != UserHandle.myUserId() 557c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang && UserHandle.getAppId(u.getUid()) >= Process.FIRST_APPLICATION_UID) { 558c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang isOtherUser = true; 559c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang List<BatterySipper> list = mUserSippers.get(userId); 560c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (list == null) { 561c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang list = new ArrayList<BatterySipper>(); 562c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mUserSippers.put(userId, list); 563c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 564c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang list.add(app); 565c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } else { 566c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mUsageList.add(app); 567c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 568c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (u.getUid() == 0) { 569c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang osApp = app; 570c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 571c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 5726cc61f17a1b239217225347d52fbef43fc72066cLifu Tang if (power != 0 || includeZeroConsumption) { 573c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (u.getUid() == Process.WIFI_UID) { 574c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mWifiPower += power; 575c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } else if (u.getUid() == Process.BLUETOOTH_UID) { 576c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mBluetoothPower += power; 577c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } else if (isOtherUser) { 578c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Double userPower = mUserPower.get(userId); 579c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (userPower == null) { 580c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang userPower = power; 581c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } else { 582c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang userPower += power; 583c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 584c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mUserPower.put(userId, userPower); 585c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } else { 586c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (power > mMaxPower) mMaxPower = power; 587c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mTotalPower += power; 588c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 589c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 590c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 591c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 592c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // The device has probably been awake for longer than the screen on 593c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // time and application wake lock time would account for. Assign 594c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // this remainder to the OS, if possible. 595c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (osApp != null) { 596c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long wakeTimeMillis = mStats.computeBatteryUptime( 597c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang SystemClock.uptimeMillis() * 1000, which) / 1000; 598c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang wakeTimeMillis -= appWakelockTime + (mStats.getScreenOnTime( 599c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang SystemClock.elapsedRealtime(), which) / 1000); 600c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (wakeTimeMillis > 0) { 601c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang double power = (wakeTimeMillis 602c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_AWAKE)) / 1000; 603c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG) Log.i(TAG, "OS wakeLockTime " + wakeTimeMillis + " power " + power); 604c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang osApp.wakeLockTime += wakeTimeMillis; 605c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang osApp.value += power; 606c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang osApp.values[0] += power; 607c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (osApp.value > mMaxPower) mMaxPower = osApp.value; 608c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mTotalPower += power; 609c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 610c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 611c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 612c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 613c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private void addPhoneUsage(long uSecNow) { 614c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long phoneOnTimeMs = mStats.getPhoneOnTime(uSecNow, mStatsType) / 1000; 615c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang double phoneOnPower = mPowerProfile.getAveragePower(PowerProfile.POWER_RADIO_ACTIVE) 616c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * phoneOnTimeMs / 1000; 617c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang addEntry(mActivity.getString(R.string.power_phone), DrainType.PHONE, phoneOnTimeMs, 618c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.drawable.ic_settings_voice_calls, phoneOnPower); 619c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 620c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 621c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private void addScreenUsage(long uSecNow) { 622c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang double power = 0; 623c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long screenOnTimeMs = mStats.getScreenOnTime(uSecNow, mStatsType) / 1000; 624c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang power += screenOnTimeMs * mPowerProfile.getAveragePower(PowerProfile.POWER_SCREEN_ON); 625c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final double screenFullPower = 626c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mPowerProfile.getAveragePower(PowerProfile.POWER_SCREEN_FULL); 627c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang for (int i = 0; i < BatteryStats.NUM_SCREEN_BRIGHTNESS_BINS; i++) { 628c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang double screenBinPower = screenFullPower * (i + 0.5f) 629c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang / BatteryStats.NUM_SCREEN_BRIGHTNESS_BINS; 630c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long brightnessTime = mStats.getScreenBrightnessTime(i, uSecNow, mStatsType) / 1000; 631c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang power += screenBinPower * brightnessTime; 632c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG) { 633c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Log.i(TAG, "Screen bin power = " + (int) screenBinPower + ", time = " 634c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang + brightnessTime); 635c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 636c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 637c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang power /= 1000; // To seconds 638c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang addEntry(mActivity.getString(R.string.power_screen), DrainType.SCREEN, screenOnTimeMs, 639c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.drawable.ic_settings_display, power); 640c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 641c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 642c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private void addRadioUsage(long uSecNow) { 643c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang double power = 0; 644c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final int BINS = SignalStrength.NUM_SIGNAL_STRENGTH_BINS; 645c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long signalTimeMs = 0; 646c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang for (int i = 0; i < BINS; i++) { 647c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long strengthTimeMs = mStats.getPhoneSignalStrengthTime(i, uSecNow, mStatsType) / 1000; 648c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang power += strengthTimeMs / 1000 649c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * mPowerProfile.getAveragePower(PowerProfile.POWER_RADIO_ON, i); 650c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang signalTimeMs += strengthTimeMs; 651c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 652c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long scanningTimeMs = mStats.getPhoneSignalScanningTime(uSecNow, mStatsType) / 1000; 653c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang power += scanningTimeMs / 1000 * mPowerProfile.getAveragePower( 654c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang PowerProfile.POWER_RADIO_SCANNING); 655c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang BatterySipper bs = 656c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang addEntry(mActivity.getString(R.string.power_cell), DrainType.CELL, 657c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang signalTimeMs, R.drawable.ic_settings_cell_standby, power); 658c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (signalTimeMs != 0) { 659c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang bs.noCoveragePercent = mStats.getPhoneSignalStrengthTime(0, uSecNow, mStatsType) 660c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang / 1000 * 100.0 / signalTimeMs; 661c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 662c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 663c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 664c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private void aggregateSippers(BatterySipper bs, List<BatterySipper> from, String tag) { 665c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang for (int i=0; i<from.size(); i++) { 666c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang BatterySipper wbs = from.get(i); 667c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG) Log.i(TAG, tag + " adding sipper " + wbs + ": cpu=" + wbs.cpuTime); 668c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang bs.cpuTime += wbs.cpuTime; 669c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang bs.gpsTime += wbs.gpsTime; 670c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang bs.wifiRunningTime += wbs.wifiRunningTime; 671c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang bs.cpuFgTime += wbs.cpuFgTime; 672c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang bs.wakeLockTime += wbs.wakeLockTime; 673c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang bs.mobileRxBytes += wbs.mobileRxBytes; 674c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang bs.mobileTxBytes += wbs.mobileTxBytes; 675c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang bs.wifiRxBytes += wbs.wifiRxBytes; 676c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang bs.wifiTxBytes += wbs.wifiTxBytes; 677c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 678c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 679c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 680c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private void addWiFiUsage(long uSecNow) { 681c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long onTimeMs = mStats.getWifiOnTime(uSecNow, mStatsType) / 1000; 682c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long runningTimeMs = mStats.getGlobalWifiRunningTime(uSecNow, mStatsType) / 1000; 683c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG) Log.i(TAG, "WIFI runningTime=" + runningTimeMs 684c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang + " app runningTime=" + mAppWifiRunning); 685c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang runningTimeMs -= mAppWifiRunning; 686c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (runningTimeMs < 0) runningTimeMs = 0; 687c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang double wifiPower = (onTimeMs * 0 /* TODO */ 688c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_ON) 689c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang + runningTimeMs * mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_ON)) / 1000; 690c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG) Log.i(TAG, "WIFI power=" + wifiPower + " from procs=" + mWifiPower); 691c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang BatterySipper bs = addEntry(mActivity.getString(R.string.power_wifi), DrainType.WIFI, 692c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang runningTimeMs, R.drawable.ic_settings_wifi, wifiPower + mWifiPower); 693c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang aggregateSippers(bs, mWifiSippers, "WIFI"); 694c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 695c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 696c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private void addIdleUsage(long uSecNow) { 697c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long idleTimeMs = (uSecNow - mStats.getScreenOnTime(uSecNow, mStatsType)) / 1000; 698c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang double idlePower = (idleTimeMs * mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_IDLE)) 699c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang / 1000; 700c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang addEntry(mActivity.getString(R.string.power_idle), DrainType.IDLE, idleTimeMs, 701c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.drawable.ic_settings_phone_idle, idlePower); 702c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 703c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 704c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private void addBluetoothUsage(long uSecNow) { 705c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long btOnTimeMs = mStats.getBluetoothOnTime(uSecNow, mStatsType) / 1000; 706c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang double btPower = btOnTimeMs * mPowerProfile.getAveragePower(PowerProfile.POWER_BLUETOOTH_ON) 707c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang / 1000; 708c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang int btPingCount = mStats.getBluetoothPingCount(); 709c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang btPower += (btPingCount 710c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * mPowerProfile.getAveragePower(PowerProfile.POWER_BLUETOOTH_AT_CMD)) / 1000; 711c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang BatterySipper bs = addEntry(mActivity.getString(R.string.power_bluetooth), 712c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang DrainType.BLUETOOTH, btOnTimeMs, R.drawable.ic_settings_bluetooth, 713c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang btPower + mBluetoothPower); 714c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang aggregateSippers(bs, mBluetoothSippers, "Bluetooth"); 715c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 716c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 717c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private void addUserUsage() { 718c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang for (int i=0; i<mUserSippers.size(); i++) { 719c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final int userId = mUserSippers.keyAt(i); 720c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final List<BatterySipper> sippers = mUserSippers.valueAt(i); 721c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang UserInfo info = mUm.getUserInfo(userId); 722c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Drawable icon; 723c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang String name; 724c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (info != null) { 725c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang icon = UserUtils.getUserIcon(mActivity, mUm, info, mActivity.getResources()); 726c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang name = info != null ? info.name : null; 727c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (name == null) { 728c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang name = Integer.toString(info.id); 729c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 730c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang name = mActivity.getResources().getString( 731c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.running_process_item_user_label, name); 732c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } else { 733c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang icon = null; 734c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang name = mActivity.getResources().getString( 735c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang R.string.running_process_item_removed_user_label); 736c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 7376cc61f17a1b239217225347d52fbef43fc72066cLifu Tang Double userPower = mUserPower.get(userId); 7386cc61f17a1b239217225347d52fbef43fc72066cLifu Tang double power = (userPower != null) ? userPower : 0.0; 739c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang BatterySipper bs = addEntry(name, DrainType.USER, 0, 0, power); 740c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang bs.icon = icon; 741c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang aggregateSippers(bs, sippers, "User"); 742c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 743c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 744c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 745c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang /** 746c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * Return estimated power (in mAs) of sending a byte with the mobile radio. 747c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang */ 748c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private double getMobilePowerPerByte() { 749c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long MOBILE_BPS = 200000; // TODO: Extract average bit rates from system 750c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final double MOBILE_POWER = mPowerProfile.getAveragePower(PowerProfile.POWER_RADIO_ACTIVE) 751c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang / 3600; 752c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 753c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long mobileRx = mStats.getNetworkActivityCount(NETWORK_MOBILE_RX_BYTES, mStatsType); 754c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long mobileTx = mStats.getNetworkActivityCount(NETWORK_MOBILE_TX_BYTES, mStatsType); 755c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long mobileData = mobileRx + mobileTx; 756c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 757c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long radioDataUptimeMs = mStats.getRadioDataUptime() / 1000; 758c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long mobileBps = radioDataUptimeMs != 0 759c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang ? mobileData * 8 * 1000 / radioDataUptimeMs 760c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang : MOBILE_BPS; 761c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 762c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang return MOBILE_POWER / (mobileBps / 8); 763c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 764c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 765c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang /** 766c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang * Return estimated power (in mAs) of sending a byte with the Wi-Fi radio. 767c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang */ 768c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private double getWifiPowerPerByte() { 769c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long WIFI_BPS = 1000000; // TODO: Extract average bit rates from system 770c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final double WIFI_POWER = mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_ACTIVE) 771c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang / 3600; 772c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang return WIFI_POWER / (WIFI_BPS / 8); 773c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 774c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 775c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private void processMiscUsage() { 776c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final int which = mStatsType; 777c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang long uSecTime = SystemClock.elapsedRealtime() * 1000; 778c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long uSecNow = mStats.computeBatteryRealtime(uSecTime, which); 779c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang final long timeSinceUnplugged = uSecNow; 780c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (DEBUG) { 781c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Log.i(TAG, "Uptime since last unplugged = " + (timeSinceUnplugged / 1000)); 782c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 783c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 784c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang addUserUsage(); 785c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang addPhoneUsage(uSecNow); 786c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang addScreenUsage(uSecNow); 787c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang addWiFiUsage(uSecNow); 788c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang addBluetoothUsage(uSecNow); 789c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang addIdleUsage(uSecNow); // Not including cellular idle power 790c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang // Don't compute radio usage if it's a wifi-only device 791c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (!com.android.settings.Utils.isWifiOnly(mActivity)) { 792c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang addRadioUsage(uSecNow); 793c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 794c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 795c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 796c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private BatterySipper addEntry(String label, DrainType drainType, long time, int iconId, 797c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang double power) { 798c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang if (power > mMaxPower) mMaxPower = power; 799c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mTotalPower += power; 800c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang BatterySipper bs = new BatterySipper(mActivity, mRequestQueue, mHandler, 801c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang label, drainType, iconId, null, new double[] {power}); 802c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang bs.usageTime = time; 803c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang bs.iconId = iconId; 804c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mUsageList.add(bs); 805c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang return bs; 806c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 807c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 808c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang public List<BatterySipper> getUsageList() { 809c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang return mUsageList; 810c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 811c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 812c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang static final int MSG_UPDATE_NAME_ICON = 1; 813c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang static final int MSG_REPORT_FULLY_DRAWN = 2; 814c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 815c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang public double getMaxPower() { 816c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang return mMaxPower; 817c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 818c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 819c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang public double getTotalPower() { 820c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang return mTotalPower; 821c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 822c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang 823c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang private void load() { 824c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang try { 825c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang byte[] data = mBatteryInfo.getStatistics(); 826c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Parcel parcel = Parcel.obtain(); 827c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang parcel.unmarshall(data, 0, data.length); 828c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang parcel.setDataPosition(0); 829c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mStats = com.android.internal.os.BatteryStatsImpl.CREATOR 830c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang .createFromParcel(parcel); 831c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang mStats.distributeWorkLocked(BatteryStats.STATS_SINCE_CHARGED); 832c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } catch (RemoteException e) { 833c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang Log.e(TAG, "RemoteException:", e); 834c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 835c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang } 836c3e9ac937a4ba948d47cbb83f6999af34fd00b65Lifu Tang} 837