summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2014-01-16 01:39:21 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-01-16 01:39:22 +0000
commitc1405900609f9cc42280a6eee0cf2f44dd6ca9f7 (patch)
treefdaa757fd3348a1635384bff0aa286e11b3b4f67
parentdf062746f9aae9df9494072ba7197acbafdb141b (diff)
parent7c80af410b09fa14b6fdb5ecec14b6b96562de4c (diff)
downloadpackages_apps_Settings-c1405900609f9cc42280a6eee0cf2f44dd6ca9f7.zip
packages_apps_Settings-c1405900609f9cc42280a6eee0cf2f44dd6ca9f7.tar.gz
packages_apps_Settings-c1405900609f9cc42280a6eee0cf2f44dd6ca9f7.tar.bz2
Merge "Switch to BatteryStatsHelper implementation in the framework."
-rw-r--r--src/com/android/settings/fuelgauge/BatteryEntry.java305
-rw-r--r--src/com/android/settings/fuelgauge/BatterySipper.java246
-rw-r--r--src/com/android/settings/fuelgauge/BatteryStatsHelper.java907
-rw-r--r--src/com/android/settings/fuelgauge/PowerGaugePreference.java7
-rw-r--r--src/com/android/settings/fuelgauge/PowerUsageDetail.java190
-rw-r--r--src/com/android/settings/fuelgauge/PowerUsageSummary.java55
6 files changed, 518 insertions, 1192 deletions
diff --git a/src/com/android/settings/fuelgauge/BatteryEntry.java b/src/com/android/settings/fuelgauge/BatteryEntry.java
new file mode 100644
index 0000000..4d1fb2f
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/BatteryEntry.java
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.fuelgauge;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
+import android.graphics.drawable.Drawable;
+import android.os.BatteryStats;
+import android.os.Handler;
+import android.os.UserManager;
+import com.android.internal.os.BatterySipper;
+import com.android.settings.R;
+import com.android.settings.users.UserUtils;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * Wraps the power usage data of a BatterySipper with information about package name
+ * and icon image.
+ */
+public class BatteryEntry {
+ public static final int MSG_UPDATE_NAME_ICON = 1;
+ public static final int MSG_REPORT_FULLY_DRAWN = 2;
+
+ static final HashMap<String,UidToDetail> sUidCache = new HashMap<String,UidToDetail>();
+
+ static final ArrayList<BatteryEntry> mRequestQueue = new ArrayList<BatteryEntry>();
+ static Handler mHandler;
+
+ static private class NameAndIconLoader extends Thread {
+ private boolean mAbort = false;
+
+ public NameAndIconLoader() {
+ super("BatteryUsage Icon Loader");
+ }
+
+ public void abort() {
+ mAbort = true;
+ }
+
+ @Override
+ public void run() {
+ while (true) {
+ BatteryEntry be;
+ synchronized (mRequestQueue) {
+ if (mRequestQueue.isEmpty() || mAbort) {
+ mHandler.sendEmptyMessage(MSG_REPORT_FULLY_DRAWN);
+ mRequestQueue.clear();
+ return;
+ }
+ be = mRequestQueue.remove(0);
+ }
+ be.loadNameAndIcon();
+ }
+ }
+ }
+
+ private static NameAndIconLoader mRequestThread;
+
+ public static void startRequestQueue() {
+ if (mHandler != null) {
+ synchronized (mRequestQueue) {
+ if (!mRequestQueue.isEmpty()) {
+ if (mRequestThread != null) {
+ mRequestThread.abort();
+ }
+ mRequestThread = new NameAndIconLoader();
+ mRequestThread.setPriority(Thread.MIN_PRIORITY);
+ mRequestThread.start();
+ mRequestQueue.notify();
+ }
+ }
+ }
+ }
+
+ public static void stopRequestQueue() {
+ synchronized (mRequestQueue) {
+ if (mRequestThread != null) {
+ mRequestThread.abort();
+ mRequestThread = null;
+ mHandler = null;
+ }
+ }
+ }
+
+ public static void clearUidCache() {
+ sUidCache.clear();
+ }
+
+ public final Context context;
+ public final BatterySipper sipper;
+
+ public String name;
+ public Drawable icon;
+ public int iconId; // For passing to the detail screen.
+ public String defaultPackageName;
+
+ static class UidToDetail {
+ String name;
+ String packageName;
+ Drawable icon;
+ }
+
+ public BatteryEntry(Context context, Handler handler, UserManager um, BatterySipper sipper) {
+ mHandler = handler;
+ this.context = context;
+ this.sipper = sipper;
+ switch (sipper.drainType) {
+ case IDLE:
+ name = context.getResources().getString(R.string.power_idle);
+ iconId = R.drawable.ic_settings_phone_idle;
+ break;
+ case CELL:
+ name = context.getResources().getString(R.string.power_cell);
+ iconId = R.drawable.ic_settings_cell_standby;
+ break;
+ case PHONE:
+ name = context.getResources().getString(R.string.power_phone);
+ iconId = R.drawable.ic_settings_voice_calls;
+ break;
+ case WIFI:
+ name = context.getResources().getString(R.string.power_wifi);
+ iconId = R.drawable.ic_settings_wifi;
+ break;
+ case BLUETOOTH:
+ name = context.getResources().getString(R.string.power_bluetooth);
+ iconId = R.drawable.ic_settings_bluetooth;
+ break;
+ case SCREEN:
+ name = context.getResources().getString(R.string.power_screen);
+ iconId = R.drawable.ic_settings_display;
+ break;
+ case APP:
+ name = sipper.packageWithHighestDrain;
+ break;
+ case USER: {
+ UserInfo info = um.getUserInfo(sipper.userId);
+ if (info != null) {
+ icon = UserUtils.getUserIcon(context, um, info, context.getResources());
+ name = info != null ? info.name : null;
+ if (name == null) {
+ name = Integer.toString(info.id);
+ }
+ name = context.getResources().getString(
+ R.string.running_process_item_user_label, name);
+ } else {
+ icon = null;
+ name = context.getResources().getString(
+ R.string.running_process_item_removed_user_label);
+ }
+ } break;
+ case UNACCOUNTED:
+ name = context.getResources().getString(R.string.power_unaccounted);
+ iconId = R.drawable.ic_power_system;
+ break;
+ case OVERCOUNTED:
+ name = context.getResources().getString(R.string.power_overcounted);
+ iconId = R.drawable.ic_power_system;
+ break;
+ }
+ if (iconId > 0) {
+ icon = context.getResources().getDrawable(iconId);
+ }
+ if ((name == null || iconId == 0) && this.sipper.uidObj != null) {
+ getQuickNameIconForUid(this.sipper.uidObj);
+ }
+ }
+
+ public Drawable getIcon() {
+ return icon;
+ }
+
+ /**
+ * Gets the application name
+ */
+ public String getLabel() {
+ return name;
+ }
+
+ void getQuickNameIconForUid(BatteryStats.Uid uidObj) {
+ final int uid = uidObj.getUid();
+ final String uidString = Integer.toString(uid);
+ if (sUidCache.containsKey(uidString)) {
+ UidToDetail utd = sUidCache.get(uidString);
+ defaultPackageName = utd.packageName;
+ name = utd.name;
+ icon = utd.icon;
+ return;
+ }
+ PackageManager pm = context.getPackageManager();
+ String[] packages = pm.getPackagesForUid(uid);
+ icon = pm.getDefaultActivityIcon();
+ if (packages == null) {
+ //name = Integer.toString(uid);
+ if (uid == 0) {
+ name = context.getResources().getString(R.string.process_kernel_label);
+ } else if ("mediaserver".equals(name)) {
+ name = context.getResources().getString(R.string.process_mediaserver_label);
+ }
+ iconId = R.drawable.ic_power_system;
+ icon = context.getResources().getDrawable(iconId);
+ return;
+ } else {
+ //name = packages[0];
+ }
+ if (mHandler != null) {
+ synchronized (mRequestQueue) {
+ mRequestQueue.add(this);
+ }
+ }
+ }
+
+ /**
+ * Loads the app label and icon image and stores into the cache.
+ */
+ public void loadNameAndIcon() {
+ // Bail out if the current sipper is not an App sipper.
+ if (sipper.uidObj == null) {
+ return;
+ }
+ PackageManager pm = context.getPackageManager();
+ final int uid = sipper.uidObj.getUid();
+ final Drawable defaultActivityIcon = pm.getDefaultActivityIcon();
+ sipper.mPackages = pm.getPackagesForUid(uid);
+ if (sipper.mPackages == null) {
+ name = Integer.toString(uid);
+ return;
+ }
+
+ String[] packageLabels = new String[sipper.mPackages.length];
+ System.arraycopy(sipper.mPackages, 0, packageLabels, 0, sipper.mPackages.length);
+
+ int preferredIndex = -1;
+ // Convert package names to user-facing labels where possible
+ for (int i = 0; i < packageLabels.length; i++) {
+ // Check if package matches preferred package
+ if (packageLabels[i].equals(name)) preferredIndex = i;
+ try {
+ ApplicationInfo ai = pm.getApplicationInfo(packageLabels[i], 0);
+ CharSequence label = ai.loadLabel(pm);
+ if (label != null) {
+ packageLabels[i] = label.toString();
+ }
+ if (ai.icon != 0) {
+ defaultPackageName = sipper.mPackages[i];
+ icon = ai.loadIcon(pm);
+ break;
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+ }
+ if (icon == null) icon = defaultActivityIcon;
+
+ if (packageLabels.length == 1) {
+ name = packageLabels[0];
+ } else {
+ // Look for an official name for this UID.
+ for (String pkgName : sipper.mPackages) {
+ try {
+ final PackageInfo pi = pm.getPackageInfo(pkgName, 0);
+ if (pi.sharedUserLabel != 0) {
+ final CharSequence nm = pm.getText(pkgName,
+ pi.sharedUserLabel, pi.applicationInfo);
+ if (nm != null) {
+ name = nm.toString();
+ if (pi.applicationInfo.icon != 0) {
+ defaultPackageName = pkgName;
+ icon = pi.applicationInfo.loadIcon(pm);
+ }
+ break;
+ }
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+ }
+ }
+ final String uidString = Integer.toString(sipper.uidObj.getUid());
+ UidToDetail utd = new UidToDetail();
+ utd.name = name;
+ utd.icon = icon;
+ utd.packageName = defaultPackageName;
+ sUidCache.put(uidString, utd);
+ if (mHandler != null) {
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_UPDATE_NAME_ICON, this));
+ }
+ }
+}
diff --git a/src/com/android/settings/fuelgauge/BatterySipper.java b/src/com/android/settings/fuelgauge/BatterySipper.java
deleted file mode 100644
index d1f885c..0000000
--- a/src/com/android/settings/fuelgauge/BatterySipper.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.settings.fuelgauge;
-
-import com.android.settings.R;
-import com.android.settings.fuelgauge.PowerUsageDetail.DrainType;
-
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.os.BatteryStats.Uid;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-
-/**
- * Contains information about package name, icon image, power usage about an
- * application or a system service.
- */
-public class BatterySipper implements Comparable<BatterySipper> {
- final Context mContext;
- /* Cache cleared when PowerUsageSummary is destroyed */
- static final HashMap<String,UidToDetail> sUidCache = new HashMap<String,UidToDetail>();
- final ArrayList<BatterySipper> mRequestQueue;
- final Handler mHandler;
- String name;
- Drawable icon;
- int iconId; // For passing to the detail screen.
- Uid uidObj;
- double value;
- double[] values;
- DrainType drainType;
- long usageTime;
- long cpuTime;
- long gpsTime;
- long wifiRunningTime;
- long cpuFgTime;
- long wakeLockTime;
- long mobileRxPackets;
- long mobileTxPackets;
- long wifiRxPackets;
- long wifiTxPackets;
- long mobileRxBytes;
- long mobileTxBytes;
- long wifiRxBytes;
- long wifiTxBytes;
- double percent;
- double noCoveragePercent;
- String defaultPackageName;
- String[] mPackages;
-
- static class UidToDetail {
- String name;
- String packageName;
- Drawable icon;
- }
-
- BatterySipper(Context context, ArrayList<BatterySipper> requestQueue,
- Handler handler, String label, DrainType drainType,
- int iconId, Uid uid, double[] values) {
- mContext = context;
- mRequestQueue = requestQueue;
- mHandler = handler;
- this.values = values;
- name = label;
- this.drainType = drainType;
- if (iconId > 0) {
- icon = mContext.getResources().getDrawable(iconId);
- }
- if (values != null) value = values[0];
- if ((label == null || iconId == 0) && uid != null) {
- getQuickNameIconForUid(uid);
- }
- uidObj = uid;
- }
-
- double getSortValue() {
- return value;
- }
-
- double[] getValues() {
- return values;
- }
-
- public Drawable getIcon() {
- return icon;
- }
-
- /**
- * Gets the application name
- */
- public String getLabel() {
- return name;
- }
-
- @Override
- public int compareTo(BatterySipper other) {
- // Return the flipped value because we want the items in descending order
- return Double.compare(other.getSortValue(), getSortValue());
- }
-
- /**
- * Gets a list of packages associated with the current user
- */
- public String[] getPackages() {
- return mPackages;
- }
-
- public int getUid() {
- // Bail out if the current sipper is not an App sipper.
- if (uidObj == null) {
- return 0;
- }
- return uidObj.getUid();
- }
-
- void getQuickNameIconForUid(Uid uidObj) {
- final int uid = uidObj.getUid();
- final String uidString = Integer.toString(uid);
- if (sUidCache.containsKey(uidString)) {
- UidToDetail utd = sUidCache.get(uidString);
- defaultPackageName = utd.packageName;
- name = utd.name;
- icon = utd.icon;
- return;
- }
- PackageManager pm = mContext.getPackageManager();
- String[] packages = pm.getPackagesForUid(uid);
- icon = pm.getDefaultActivityIcon();
- if (packages == null) {
- //name = Integer.toString(uid);
- if (uid == 0) {
- name = mContext.getResources().getString(R.string.process_kernel_label);
- } else if ("mediaserver".equals(name)) {
- name = mContext.getResources().getString(R.string.process_mediaserver_label);
- }
- iconId = R.drawable.ic_power_system;
- icon = mContext.getResources().getDrawable(iconId);
- return;
- } else {
- //name = packages[0];
- }
- if (mHandler != null) {
- synchronized (mRequestQueue) {
- mRequestQueue.add(this);
- }
- }
- }
-
- public static void clearUidCache() {
- sUidCache.clear();
- }
-
- /**
- * Loads the app label and icon image and stores into the cache.
- */
- public void loadNameAndIcon() {
- // Bail out if the current sipper is not an App sipper.
- if (uidObj == null) {
- return;
- }
- PackageManager pm = mContext.getPackageManager();
- final int uid = uidObj.getUid();
- final Drawable defaultActivityIcon = pm.getDefaultActivityIcon();
- mPackages = pm.getPackagesForUid(uid);
- if (mPackages == null) {
- name = Integer.toString(uid);
- return;
- }
-
- String[] packageLabels = new String[mPackages.length];
- System.arraycopy(mPackages, 0, packageLabels, 0, mPackages.length);
-
- int preferredIndex = -1;
- // Convert package names to user-facing labels where possible
- for (int i = 0; i < packageLabels.length; i++) {
- // Check if package matches preferred package
- if (packageLabels[i].equals(name)) preferredIndex = i;
- try {
- ApplicationInfo ai = pm.getApplicationInfo(packageLabels[i], 0);
- CharSequence label = ai.loadLabel(pm);
- if (label != null) {
- packageLabels[i] = label.toString();
- }
- if (ai.icon != 0) {
- defaultPackageName = mPackages[i];
- icon = ai.loadIcon(pm);
- break;
- }
- } catch (NameNotFoundException e) {
- }
- }
- if (icon == null) icon = defaultActivityIcon;
-
- if (packageLabels.length == 1) {
- name = packageLabels[0];
- } else {
- // Look for an official name for this UID.
- for (String pkgName : mPackages) {
- try {
- final PackageInfo pi = pm.getPackageInfo(pkgName, 0);
- if (pi.sharedUserLabel != 0) {
- final CharSequence nm = pm.getText(pkgName,
- pi.sharedUserLabel, pi.applicationInfo);
- if (nm != null) {
- name = nm.toString();
- if (pi.applicationInfo.icon != 0) {
- defaultPackageName = pkgName;
- icon = pi.applicationInfo.loadIcon(pm);
- }
- break;
- }
- }
- } catch (PackageManager.NameNotFoundException e) {
- }
- }
- }
- final String uidString = Integer.toString(uidObj.getUid());
- UidToDetail utd = new UidToDetail();
- utd.name = name;
- utd.icon = icon;
- utd.packageName = defaultPackageName;
- sUidCache.put(uidString, utd);
- if (mHandler != null) {
- mHandler.sendMessage(
- mHandler.obtainMessage(BatteryStatsHelper.MSG_UPDATE_NAME_ICON, this));
- }
- }
-}
diff --git a/src/com/android/settings/fuelgauge/BatteryStatsHelper.java b/src/com/android/settings/fuelgauge/BatteryStatsHelper.java
deleted file mode 100644
index a02917e..0000000
--- a/src/com/android/settings/fuelgauge/BatteryStatsHelper.java
+++ /dev/null
@@ -1,907 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.fuelgauge;
-
-import static android.os.BatteryStats.NETWORK_MOBILE_RX_DATA;
-import static android.os.BatteryStats.NETWORK_MOBILE_TX_DATA;
-import static android.os.BatteryStats.NETWORK_WIFI_RX_DATA;
-import static android.os.BatteryStats.NETWORK_WIFI_TX_DATA;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.pm.UserInfo;
-import android.graphics.drawable.Drawable;
-import android.hardware.Sensor;
-import android.hardware.SensorManager;
-import android.os.BatteryStats;
-import android.os.BatteryStats.Uid;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Parcel;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.preference.PreferenceActivity;
-import android.telephony.SignalStrength;
-import android.util.Log;
-import android.util.SparseArray;
-
-import com.android.internal.app.IBatteryStats;
-import com.android.internal.os.BatteryStatsImpl;
-import com.android.internal.os.PowerProfile;
-import com.android.internal.util.FastPrintWriter;
-import com.android.settings.R;
-import com.android.settings.fuelgauge.PowerUsageDetail.DrainType;
-import com.android.settings.users.UserUtils;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-/**
- * A helper class for retrieving the power usage information for all applications and services.
- *
- * The caller must initialize this class as soon as activity object is ready to use (for example, in
- * onAttach() for Fragment), call create() in onCreate() and call destroy() in onDestroy().
- */
-public class BatteryStatsHelper {
-
- private static final boolean DEBUG = false;
-
- private static final String TAG = BatteryStatsHelper.class.getSimpleName();
-
- private static BatteryStatsImpl sStatsXfer;
- private IBatteryStats mBatteryInfo;
- private UserManager mUm;
- private BatteryStatsImpl mStats;
- private PowerProfile mPowerProfile;
-
- private final List<BatterySipper> mUsageList = new ArrayList<BatterySipper>();
- private final List<BatterySipper> mWifiSippers = new ArrayList<BatterySipper>();
- private final List<BatterySipper> mBluetoothSippers = new ArrayList<BatterySipper>();
- private final SparseArray<List<BatterySipper>> mUserSippers
- = new SparseArray<List<BatterySipper>>();
- private final SparseArray<Double> mUserPower = new SparseArray<Double>();
-
- private int mStatsType = BatteryStats.STATS_SINCE_CHARGED;
-
- private long mStatsPeriod = 0;
- private double mMaxPower = 1;
- private double mTotalPower;
- private double mTotalPowermAh;
- private double mWifiPower;
- private double mBluetoothPower;
- private double mMinDrainedPower;
- private double mMaxDrainedPower;
-
- // How much the apps together have left WIFI running.
- private long mAppWifiRunning;
-
- /** Queue for fetching name and icon for an application */
- private ArrayList<BatterySipper> mRequestQueue = new ArrayList<BatterySipper>();
-
- private Activity mActivity;
- private Handler mHandler;
-
- private class NameAndIconLoader extends Thread {
- private boolean mAbort = false;
-
- public NameAndIconLoader() {
- super("BatteryUsage Icon Loader");
- }
-
- public void abort() {
- mAbort = true;
- }
-
- @Override
- public void run() {
- while (true) {
- BatterySipper bs;
- synchronized (mRequestQueue) {
- if (mRequestQueue.isEmpty() || mAbort) {
- mHandler.sendEmptyMessage(MSG_REPORT_FULLY_DRAWN);
- return;
- }
- bs = mRequestQueue.remove(0);
- }
- bs.loadNameAndIcon();
- }
- }
- }
-
- private NameAndIconLoader mRequestThread;
-
- public BatteryStatsHelper(Activity activity, Handler handler) {
- mActivity = activity;
- mHandler = handler;
- }
-
- /** Clears the current stats and forces recreating for future use. */
- public void clearStats() {
- mStats = null;
- }
-
- public BatteryStatsImpl getStats() {
- if (mStats == null) {
- load();
- }
- return mStats;
- }
-
- public PowerProfile getPowerProfile() {
- return mPowerProfile;
- }
-
- public void create(Bundle icicle) {
- if (icicle != null) {
- mStats = sStatsXfer;
- }
- mBatteryInfo = IBatteryStats.Stub.asInterface(
- ServiceManager.getService(BatteryStats.SERVICE_NAME));
- mUm = (UserManager) mActivity.getSystemService(Context.USER_SERVICE);
- mPowerProfile = new PowerProfile(mActivity);
- }
-
- public void pause() {
- if (mRequestThread != null) {
- mRequestThread.abort();
- }
- }
-
- public void destroy() {
- if (mActivity.isChangingConfigurations()) {
- sStatsXfer = mStats;
- } else {
- BatterySipper.sUidCache.clear();
- }
- }
-
- public void startBatteryDetailPage(
- PreferenceActivity caller, BatterySipper sipper, boolean showLocationButton) {
- // Initialize mStats if necessary.
- getStats();
-
- Bundle args = new Bundle();
- args.putString(PowerUsageDetail.EXTRA_TITLE, sipper.name);
- args.putInt(PowerUsageDetail.EXTRA_PERCENT, (int)
- Math.ceil(sipper.getSortValue() * 100 / mTotalPower));
- args.putInt(PowerUsageDetail.EXTRA_GAUGE, (int)
- Math.ceil(sipper.getSortValue() * 100 / mMaxPower));
- args.putLong(PowerUsageDetail.EXTRA_USAGE_DURATION, mStatsPeriod);
- args.putString(PowerUsageDetail.EXTRA_ICON_PACKAGE, sipper.defaultPackageName);
- args.putInt(PowerUsageDetail.EXTRA_ICON_ID, sipper.iconId);
- args.putDouble(PowerUsageDetail.EXTRA_NO_COVERAGE, sipper.noCoveragePercent);
- if (sipper.uidObj != null) {
- args.putInt(PowerUsageDetail.EXTRA_UID, sipper.uidObj.getUid());
- }
- args.putSerializable(PowerUsageDetail.EXTRA_DRAIN_TYPE, sipper.drainType);
- args.putBoolean(PowerUsageDetail.EXTRA_SHOW_LOCATION_BUTTON, showLocationButton);
-
- int[] types;
- double[] values;
- switch (sipper.drainType) {
- case APP:
- case USER:
- {
- Uid uid = sipper.uidObj;
- types = new int[] {
- R.string.usage_type_cpu,
- R.string.usage_type_cpu_foreground,
- R.string.usage_type_wake_lock,
- R.string.usage_type_gps,
- R.string.usage_type_wifi_running,
- R.string.usage_type_data_recv,
- R.string.usage_type_data_send,
- R.string.usage_type_data_wifi_recv,
- R.string.usage_type_data_wifi_send,
- R.string.usage_type_audio,
- R.string.usage_type_video,
- };
- values = new double[] {
- sipper.cpuTime,
- sipper.cpuFgTime,
- sipper.wakeLockTime,
- sipper.gpsTime,
- sipper.wifiRunningTime,
- sipper.mobileRxPackets,
- sipper.mobileTxPackets,
- sipper.wifiRxPackets,
- sipper.wifiTxPackets,
- 0,
- 0
- };
-
- if (sipper.drainType == DrainType.APP) {
- Writer result = new StringWriter();
- PrintWriter printWriter = new FastPrintWriter(result, false, 1024);
- mStats.dumpLocked(printWriter, "", mStatsType, uid.getUid());
- printWriter.flush();
- args.putString(PowerUsageDetail.EXTRA_REPORT_DETAILS, result.toString());
-
- result = new StringWriter();
- printWriter = new FastPrintWriter(result, false, 1024);
- mStats.dumpCheckinLocked(printWriter, mStatsType, uid.getUid());
- printWriter.flush();
- args.putString(PowerUsageDetail.EXTRA_REPORT_CHECKIN_DETAILS,
- result.toString());
- }
- }
- break;
- case CELL:
- {
- types = new int[] {
- R.string.usage_type_on_time,
- R.string.usage_type_no_coverage
- };
- values = new double[] {
- sipper.usageTime,
- sipper.noCoveragePercent
- };
- }
- break;
- case WIFI:
- {
- types = new int[] {
- R.string.usage_type_wifi_running,
- R.string.usage_type_cpu,
- R.string.usage_type_cpu_foreground,
- R.string.usage_type_wake_lock,
- R.string.usage_type_data_recv,
- R.string.usage_type_data_send,
- R.string.usage_type_data_wifi_recv,
- R.string.usage_type_data_wifi_send,
- };
- values = new double[] {
- sipper.usageTime,
- sipper.cpuTime,
- sipper.cpuFgTime,
- sipper.wakeLockTime,
- sipper.mobileRxPackets,
- sipper.mobileTxPackets,
- sipper.wifiRxPackets,
- sipper.wifiTxPackets,
- };
- } break;
- case BLUETOOTH:
- {
- types = new int[] {
- R.string.usage_type_on_time,
- R.string.usage_type_cpu,
- R.string.usage_type_cpu_foreground,
- R.string.usage_type_wake_lock,
- R.string.usage_type_data_recv,
- R.string.usage_type_data_send,
- R.string.usage_type_data_wifi_recv,
- R.string.usage_type_data_wifi_send,
- };
- values = new double[] {
- sipper.usageTime,
- sipper.cpuTime,
- sipper.cpuFgTime,
- sipper.wakeLockTime,
- sipper.mobileRxPackets,
- sipper.mobileTxPackets,
- sipper.wifiRxPackets,
- sipper.wifiTxPackets,
- };
- } break;
- case UNACCOUNTED:
- case OVERCOUNTED:
- {
- types = new int[] {
- R.string.usage_type_total_battery_capacity,
- R.string.usage_type_computed_power,
- R.string.usage_type_min_actual_power,
- R.string.usage_type_max_actual_power,
- };
- values = new double[] {
- mPowerProfile.getBatteryCapacity(),
- mTotalPowermAh,
- mMinDrainedPower,
- mMaxDrainedPower,
- };
- } break;
- default:
- {
- types = new int[] {
- R.string.usage_type_on_time
- };
- values = new double[] {
- sipper.usageTime
- };
- }
- }
- args.putIntArray(PowerUsageDetail.EXTRA_DETAIL_TYPES, types);
- args.putDoubleArray(PowerUsageDetail.EXTRA_DETAIL_VALUES, values);
- caller.startPreferencePanel(PowerUsageDetail.class.getName(), args,
- R.string.details_title, null, null, 0);
- }
-
- /**
- * Refreshes the power usage list.
- * @param includeZeroConsumption whether includes those applications which have consumed very
- * little power up till now.
- */
- public void refreshStats(boolean includeZeroConsumption) {
- // Initialize mStats if necessary.
- getStats();
-
- mMaxPower = 0;
- mTotalPower = 0;
- mWifiPower = 0;
- mBluetoothPower = 0;
- mAppWifiRunning = 0;
-
- mUsageList.clear();
- mWifiSippers.clear();
- mBluetoothSippers.clear();
- mUserSippers.clear();
- mUserPower.clear();
-
- mMinDrainedPower = (mStats.getLowDischargeAmountSinceCharge()
- * mPowerProfile.getBatteryCapacity()) / 100;
- mMaxDrainedPower = (mStats.getHighDischargeAmountSinceCharge()
- * mPowerProfile.getBatteryCapacity()) / 100;
-
- processAppUsage(includeZeroConsumption);
- processMiscUsage();
-
- // We have been computing totals in seconds, convert to hours.
- mTotalPowermAh = mTotalPower / 3600;
-
- if (true || mStats.getLowDischargeAmountSinceCharge() > 10) {
- if (mMinDrainedPower > mTotalPowermAh) {
- double amount = mMinDrainedPower - mTotalPowermAh;
- if (mMaxPower < amount) {
- mMaxPower = amount;
- }
- addEntryNoTotal(mActivity.getString(R.string.power_unaccounted),
- DrainType.UNACCOUNTED, 0, R.drawable.ic_power_system, amount * 3600);
- } else if (mMaxDrainedPower < mTotalPowermAh) {
- double amount = mTotalPowermAh - mMaxDrainedPower;
- if (mMaxPower < amount) {
- mMaxPower = amount;
- }
- addEntryNoTotal(mActivity.getString(R.string.power_overcounted),
- DrainType.OVERCOUNTED, 0, R.drawable.ic_power_system, amount * 3600);
- }
- }
-
- Collections.sort(mUsageList);
-
- if (mHandler != null) {
- synchronized (mRequestQueue) {
- if (!mRequestQueue.isEmpty()) {
- if (mRequestThread != null) {
- mRequestThread.abort();
- }
- mRequestThread = new NameAndIconLoader();
- mRequestThread.setPriority(Thread.MIN_PRIORITY);
- mRequestThread.start();
- mRequestQueue.notify();
- }
- }
- }
- }
-
- private void processAppUsage(boolean includeZeroConsumption) {
- SensorManager sensorManager = (SensorManager) mActivity.getSystemService(
- Context.SENSOR_SERVICE);
- final int which = mStatsType;
- final int speedSteps = mPowerProfile.getNumSpeedSteps();
- final double[] powerCpuNormal = new double[speedSteps];
- final long[] cpuSpeedStepTimes = new long[speedSteps];
- for (int p = 0; p < speedSteps; p++) {
- powerCpuNormal[p] = mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_ACTIVE, p);
- }
- final double mobilePowerPerPacket = getMobilePowerPerPacket();
- final double wifiPowerPerPacket = getWifiPowerPerPacket();
- long uSecTime = mStats.computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which);
- long appWakelockTime = 0;
- BatterySipper osApp = null;
- mStatsPeriod = uSecTime;
- SparseArray<? extends Uid> uidStats = mStats.getUidStats();
- final int NU = uidStats.size();
- for (int iu = 0; iu < NU; iu++) {
- Uid u = uidStats.valueAt(iu);
- double p; // in mAs
- double power = 0; // in mAs
- double highestDrain = 0;
- String packageWithHighestDrain = null;
- //mUsageList.add(new AppUsage(u.getUid(), new double[] {power}));
- Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
- long cpuTime = 0;
- long cpuFgTime = 0;
- long wakelockTime = 0;
- long gpsTime = 0;
- if (DEBUG) Log.i(TAG, "UID " + u.getUid());
- if (processStats.size() > 0) {
- // Process CPU time
- for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
- : processStats.entrySet()) {
- Uid.Proc ps = ent.getValue();
- final long userTime = ps.getUserTime(which);
- final long systemTime = ps.getSystemTime(which);
- final long foregroundTime = ps.getForegroundTime(which);
- cpuFgTime += foregroundTime * 10; // convert to millis
- final long tmpCpuTime = (userTime + systemTime) * 10; // convert to millis
- int totalTimeAtSpeeds = 0;
- // Get the total first
- for (int step = 0; step < speedSteps; step++) {
- cpuSpeedStepTimes[step] = ps.getTimeAtCpuSpeedStep(step, which);
- totalTimeAtSpeeds += cpuSpeedStepTimes[step];
- }
- if (totalTimeAtSpeeds == 0) totalTimeAtSpeeds = 1;
- // Then compute the ratio of time spent at each speed
- double processPower = 0;
- for (int step = 0; step < speedSteps; step++) {
- double ratio = (double) cpuSpeedStepTimes[step] / totalTimeAtSpeeds;
- processPower += ratio * tmpCpuTime * powerCpuNormal[step];
- }
- cpuTime += tmpCpuTime;
- if (DEBUG && processPower != 0) {
- Log.i(TAG, String.format("process %s, cpu power=%.2f",
- ent.getKey(), processPower / 1000));
- }
- power += processPower;
- if (packageWithHighestDrain == null
- || packageWithHighestDrain.startsWith("*")) {
- highestDrain = processPower;
- packageWithHighestDrain = ent.getKey();
- } else if (highestDrain < processPower
- && !ent.getKey().startsWith("*")) {
- highestDrain = processPower;
- packageWithHighestDrain = ent.getKey();
- }
- }
- }
- if (cpuFgTime > cpuTime) {
- if (DEBUG && cpuFgTime > cpuTime + 10000) {
- Log.i(TAG, "WARNING! Cputime is more than 10 seconds behind Foreground time");
- }
- cpuTime = cpuFgTime; // Statistics may not have been gathered yet.
- }
- power /= 1000;
- if (DEBUG && power != 0) Log.i(TAG, String.format("total cpu power=%.2f", power));
-
- // Process wake lock usage
- Map<String, ? extends BatteryStats.Uid.Wakelock> wakelockStats = u.getWakelockStats();
- for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> wakelockEntry
- : wakelockStats.entrySet()) {
- Uid.Wakelock wakelock = wakelockEntry.getValue();
- // Only care about partial wake locks since full wake locks
- // are canceled when the user turns the screen off.
- BatteryStats.Timer timer = wakelock.getWakeTime(BatteryStats.WAKE_TYPE_PARTIAL);
- if (timer != null) {
- wakelockTime += timer.getTotalTimeLocked(uSecTime, which);
- }
- }
- wakelockTime /= 1000; // convert to millis
- appWakelockTime += wakelockTime;
-
- // Add cost of holding a wake lock
- p = (wakelockTime
- * mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_AWAKE)) / 1000;
- power += p;
- if (DEBUG && p != 0) Log.i(TAG, String.format("wakelock power=%.2f", p));
-
- // Add cost of mobile traffic
- final long mobileRx = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, mStatsType);
- final long mobileTx = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, mStatsType);
- final long mobileRxB = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, mStatsType);
- final long mobileTxB = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, mStatsType);
- p = (mobileRx + mobileTx) * mobilePowerPerPacket;
- power += p;
- if (DEBUG && p != 0) Log.i(TAG, String.format("mobile power=%.2f", p));
-
- // Add cost of wifi traffic
- final long wifiRx = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, mStatsType);
- final long wifiTx = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, mStatsType);
- final long wifiRxB = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, mStatsType);
- final long wifiTxB = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, mStatsType);
- p = (wifiRx + wifiTx) * wifiPowerPerPacket;
- power += p;
- if (DEBUG && p != 0) Log.i(TAG, String.format("wifi power=%.2f", p));
-
- // Add cost of keeping WIFI running.
- long wifiRunningTimeMs = u.getWifiRunningTime(uSecTime, which) / 1000;
- mAppWifiRunning += wifiRunningTimeMs;
- p = (wifiRunningTimeMs
- * mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_ON)) / 1000;
- power += p;
- if (DEBUG && p != 0) Log.i(TAG, String.format("wifi running power=%.2f", p));
-
- // Add cost of WIFI scans
- long wifiScanTimeMs = u.getWifiScanTime(uSecTime, which) / 1000;
- p = (wifiScanTimeMs
- * mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_SCAN)) / 1000;
- power += p;
- if (DEBUG && p != 0) Log.i(TAG, String.format("wifi scanning power=%.2f", p));
- for (int bin = 0; bin < BatteryStats.Uid.NUM_WIFI_BATCHED_SCAN_BINS; bin++) {
- long batchScanTimeMs = u.getWifiBatchedScanTime(bin, uSecTime, which) / 1000;
- p = (batchScanTimeMs
- * mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_BATCHED_SCAN, bin));
- power += p;
- if (DEBUG && p != 0) {
- Log.i(TAG, String.format("wifi batched scanning lvl %d = %.2f", bin, p));
- }
- }
-
- // Process Sensor usage
- Map<Integer, ? extends BatteryStats.Uid.Sensor> sensorStats = u.getSensorStats();
- for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> sensorEntry
- : sensorStats.entrySet()) {
- Uid.Sensor sensor = sensorEntry.getValue();
- int sensorHandle = sensor.getHandle();
- BatteryStats.Timer timer = sensor.getSensorTime();
- long sensorTime = timer.getTotalTimeLocked(uSecTime, which) / 1000;
- double multiplier = 0;
- switch (sensorHandle) {
- case Uid.Sensor.GPS:
- multiplier = mPowerProfile.getAveragePower(PowerProfile.POWER_GPS_ON);
- gpsTime = sensorTime;
- break;
- default:
- List<Sensor> sensorList = sensorManager.getSensorList(
- android.hardware.Sensor.TYPE_ALL);
- for (android.hardware.Sensor s : sensorList) {
- if (s.getHandle() == sensorHandle) {
- multiplier = s.getPower();
- break;
- }
- }
- }
- p = (multiplier * sensorTime) / 1000;
- power += p;
- if (DEBUG && p != 0) {
- Log.i(TAG, String.format("sensor %s power=%.2f", sensor.toString(), p));
- }
- }
-
- if (DEBUG) Log.i(TAG, String.format("UID %d total power=%.2f", u.getUid(), power));
-
- // Add the app to the list if it is consuming power
- boolean isOtherUser = false;
- final int userId = UserHandle.getUserId(u.getUid());
- if (power != 0 || includeZeroConsumption || u.getUid() == 0) {
- BatterySipper app = new BatterySipper(mActivity, mRequestQueue, mHandler,
- packageWithHighestDrain, DrainType.APP, 0, u,
- new double[] {power});
- app.cpuTime = cpuTime;
- app.gpsTime = gpsTime;
- app.wifiRunningTime = wifiRunningTimeMs;
- app.cpuFgTime = cpuFgTime;
- app.wakeLockTime = wakelockTime;
- app.mobileRxPackets = mobileRx;
- app.mobileTxPackets = mobileTx;
- app.wifiRxPackets = wifiRx;
- app.wifiTxPackets = wifiTx;
- app.mobileRxBytes = mobileRxB;
- app.mobileTxBytes = mobileTxB;
- app.wifiRxBytes = wifiRxB;
- app.wifiTxBytes = wifiTxB;
- if (u.getUid() == Process.WIFI_UID) {
- mWifiSippers.add(app);
- } else if (u.getUid() == Process.BLUETOOTH_UID) {
- mBluetoothSippers.add(app);
- } else if (userId != UserHandle.myUserId()
- && UserHandle.getAppId(u.getUid()) >= Process.FIRST_APPLICATION_UID) {
- isOtherUser = true;
- List<BatterySipper> list = mUserSippers.get(userId);
- if (list == null) {
- list = new ArrayList<BatterySipper>();
- mUserSippers.put(userId, list);
- }
- list.add(app);
- } else {
- mUsageList.add(app);
- }
- if (u.getUid() == 0) {
- osApp = app;
- }
- }
- if (power != 0 || includeZeroConsumption) {
- if (u.getUid() == Process.WIFI_UID) {
- mWifiPower += power;
- } else if (u.getUid() == Process.BLUETOOTH_UID) {
- mBluetoothPower += power;
- } else if (isOtherUser) {
- Double userPower = mUserPower.get(userId);
- if (userPower == null) {
- userPower = power;
- } else {
- userPower += power;
- }
- mUserPower.put(userId, userPower);
- } else {
- if (power > mMaxPower) mMaxPower = power;
- mTotalPower += power;
- }
- }
- }
-
- // The device has probably been awake for longer than the screen on
- // time and application wake lock time would account for. Assign
- // this remainder to the OS, if possible.
- if (osApp != null) {
- long wakeTimeMillis = mStats.computeBatteryUptime(
- SystemClock.uptimeMillis() * 1000, which) / 1000;
- wakeTimeMillis -= appWakelockTime + (mStats.getScreenOnTime(
- SystemClock.elapsedRealtime(), which) / 1000);
- if (wakeTimeMillis > 0) {
- double power = (wakeTimeMillis
- * mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_AWAKE)) / 1000;
- if (DEBUG) Log.i(TAG, "OS wakeLockTime " + wakeTimeMillis + " power " + power);
- osApp.wakeLockTime += wakeTimeMillis;
- osApp.value += power;
- osApp.values[0] += power;
- if (osApp.value > mMaxPower) mMaxPower = osApp.value;
- mTotalPower += power;
- }
- }
- }
-
- private void addPhoneUsage(long uSecNow) {
- long phoneOnTimeMs = mStats.getPhoneOnTime(uSecNow, mStatsType) / 1000;
- double phoneOnPower = mPowerProfile.getAveragePower(PowerProfile.POWER_RADIO_ACTIVE)
- * phoneOnTimeMs / 1000;
- addEntry(mActivity.getString(R.string.power_phone), DrainType.PHONE, phoneOnTimeMs,
- R.drawable.ic_settings_voice_calls, phoneOnPower);
- }
-
- private void addScreenUsage(long uSecNow) {
- double power = 0;
- long screenOnTimeMs = mStats.getScreenOnTime(uSecNow, mStatsType) / 1000;
- power += screenOnTimeMs * mPowerProfile.getAveragePower(PowerProfile.POWER_SCREEN_ON);
- final double screenFullPower =
- mPowerProfile.getAveragePower(PowerProfile.POWER_SCREEN_FULL);
- for (int i = 0; i < BatteryStats.NUM_SCREEN_BRIGHTNESS_BINS; i++) {
- double screenBinPower = screenFullPower * (i + 0.5f)
- / BatteryStats.NUM_SCREEN_BRIGHTNESS_BINS;
- long brightnessTime = mStats.getScreenBrightnessTime(i, uSecNow, mStatsType) / 1000;
- power += screenBinPower * brightnessTime;
- if (DEBUG) {
- Log.i(TAG, "Screen bin power = " + (int) screenBinPower + ", time = "
- + brightnessTime);
- }
- }
- power /= 1000; // To seconds
- addEntry(mActivity.getString(R.string.power_screen), DrainType.SCREEN, screenOnTimeMs,
- R.drawable.ic_settings_display, power);
- }
-
- private void addRadioUsage(long uSecNow) {
- double power = 0;
- final int BINS = SignalStrength.NUM_SIGNAL_STRENGTH_BINS;
- long signalTimeMs = 0;
- for (int i = 0; i < BINS; i++) {
- long strengthTimeMs = mStats.getPhoneSignalStrengthTime(i, uSecNow, mStatsType) / 1000;
- power += strengthTimeMs / 1000
- * mPowerProfile.getAveragePower(PowerProfile.POWER_RADIO_ON, i);
- signalTimeMs += strengthTimeMs;
- }
- long scanningTimeMs = mStats.getPhoneSignalScanningTime(uSecNow, mStatsType) / 1000;
- power += scanningTimeMs / 1000 * mPowerProfile.getAveragePower(
- PowerProfile.POWER_RADIO_SCANNING);
- BatterySipper bs =
- addEntry(mActivity.getString(R.string.power_cell), DrainType.CELL,
- signalTimeMs, R.drawable.ic_settings_cell_standby, power);
- if (signalTimeMs != 0) {
- bs.noCoveragePercent = mStats.getPhoneSignalStrengthTime(0, uSecNow, mStatsType)
- / 1000 * 100.0 / signalTimeMs;
- }
- }
-
- private void aggregateSippers(BatterySipper bs, List<BatterySipper> from, String tag) {
- for (int i=0; i<from.size(); i++) {
- BatterySipper wbs = from.get(i);
- if (DEBUG) Log.i(TAG, tag + " adding sipper " + wbs + ": cpu=" + wbs.cpuTime);
- bs.cpuTime += wbs.cpuTime;
- bs.gpsTime += wbs.gpsTime;
- bs.wifiRunningTime += wbs.wifiRunningTime;
- bs.cpuFgTime += wbs.cpuFgTime;
- bs.wakeLockTime += wbs.wakeLockTime;
- bs.mobileRxPackets += wbs.mobileRxPackets;
- bs.mobileTxPackets += wbs.mobileTxPackets;
- bs.wifiRxPackets += wbs.wifiRxPackets;
- bs.wifiTxPackets += wbs.wifiTxPackets;
- bs.mobileRxBytes += wbs.mobileRxBytes;
- bs.mobileTxBytes += wbs.mobileTxBytes;
- bs.wifiRxBytes += wbs.wifiRxBytes;
- bs.wifiTxBytes += wbs.wifiTxBytes;
- }
- }
-
- private void addWiFiUsage(long uSecNow) {
- long onTimeMs = mStats.getWifiOnTime(uSecNow, mStatsType) / 1000;
- long runningTimeMs = mStats.getGlobalWifiRunningTime(uSecNow, mStatsType) / 1000;
- if (DEBUG) Log.i(TAG, "WIFI runningTime=" + runningTimeMs
- + " app runningTime=" + mAppWifiRunning);
- runningTimeMs -= mAppWifiRunning;
- if (runningTimeMs < 0) runningTimeMs = 0;
- double wifiPower = (onTimeMs * 0 /* TODO */
- * mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_ON)
- + runningTimeMs * mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_ON)) / 1000;
- if (DEBUG) Log.i(TAG, "WIFI power=" + wifiPower + " from procs=" + mWifiPower);
- BatterySipper bs = addEntry(mActivity.getString(R.string.power_wifi), DrainType.WIFI,
- runningTimeMs, R.drawable.ic_settings_wifi, wifiPower + mWifiPower);
- aggregateSippers(bs, mWifiSippers, "WIFI");
- }
-
- private void addIdleUsage(long uSecNow) {
- long idleTimeMs = (uSecNow - mStats.getScreenOnTime(uSecNow, mStatsType)) / 1000;
- double idlePower = (idleTimeMs * mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_IDLE))
- / 1000;
- addEntry(mActivity.getString(R.string.power_idle), DrainType.IDLE, idleTimeMs,
- R.drawable.ic_settings_phone_idle, idlePower);
- }
-
- private void addBluetoothUsage(long uSecNow) {
- long btOnTimeMs = mStats.getBluetoothOnTime(uSecNow, mStatsType) / 1000;
- double btPower = btOnTimeMs * mPowerProfile.getAveragePower(PowerProfile.POWER_BLUETOOTH_ON)
- / 1000;
- int btPingCount = mStats.getBluetoothPingCount();
- btPower += (btPingCount
- * mPowerProfile.getAveragePower(PowerProfile.POWER_BLUETOOTH_AT_CMD)) / 1000;
- BatterySipper bs = addEntry(mActivity.getString(R.string.power_bluetooth),
- DrainType.BLUETOOTH, btOnTimeMs, R.drawable.ic_settings_bluetooth,
- btPower + mBluetoothPower);
- aggregateSippers(bs, mBluetoothSippers, "Bluetooth");
- }
-
- private void addUserUsage() {
- for (int i=0; i<mUserSippers.size(); i++) {
- final int userId = mUserSippers.keyAt(i);
- final List<BatterySipper> sippers = mUserSippers.valueAt(i);
- UserInfo info = mUm.getUserInfo(userId);
- Drawable icon;
- String name;
- if (info != null) {
- icon = UserUtils.getUserIcon(mActivity, mUm, info, mActivity.getResources());
- name = info != null ? info.name : null;
- if (name == null) {
- name = Integer.toString(info.id);
- }
- name = mActivity.getResources().getString(
- R.string.running_process_item_user_label, name);
- } else {
- icon = null;
- name = mActivity.getResources().getString(
- R.string.running_process_item_removed_user_label);
- }
- Double userPower = mUserPower.get(userId);
- double power = (userPower != null) ? userPower : 0.0;
- BatterySipper bs = addEntry(name, DrainType.USER, 0, 0, power);
- bs.icon = icon;
- aggregateSippers(bs, sippers, "User");
- }
- }
-
- /**
- * Return estimated power (in mAs) of sending or receiving a packet with the mobile radio.
- */
- private double getMobilePowerPerPacket() {
- final long MOBILE_BPS = 200000; // TODO: Extract average bit rates from system
- final double MOBILE_POWER = mPowerProfile.getAveragePower(PowerProfile.POWER_RADIO_ACTIVE)
- / 3600;
-
- final long mobileRx = mStats.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, mStatsType);
- final long mobileTx = mStats.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, mStatsType);
- final long mobileData = mobileRx + mobileTx;
-
- final long radioDataUptimeMs = mStats.getRadioDataUptime() / 1000;
- final double mobilePps = radioDataUptimeMs != 0
- ? mobileData / (double)radioDataUptimeMs
- : (((double)MOBILE_BPS) / 8 / 2048);
-
- return MOBILE_POWER / mobilePps;
- }
-
- /**
- * Return estimated power (in mAs) of sending a byte with the Wi-Fi radio.
- */
- private double getWifiPowerPerPacket() {
- final long WIFI_BPS = 1000000; // TODO: Extract average bit rates from system
- final double WIFI_POWER = mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_ACTIVE)
- / 3600;
- return WIFI_POWER / (((double)WIFI_BPS) / 8 / 2048);
- }
-
- private void processMiscUsage() {
- final int which = mStatsType;
- long uSecTime = SystemClock.elapsedRealtime() * 1000;
- final long uSecNow = mStats.computeBatteryRealtime(uSecTime, which);
- final long timeSinceUnplugged = uSecNow;
- if (DEBUG) {
- Log.i(TAG, "Uptime since last unplugged = " + (timeSinceUnplugged / 1000));
- }
-
- addUserUsage();
- addPhoneUsage(uSecNow);
- addScreenUsage(uSecNow);
- addWiFiUsage(uSecNow);
- addBluetoothUsage(uSecNow);
- addIdleUsage(uSecNow); // Not including cellular idle power
- // Don't compute radio usage if it's a wifi-only device
- if (!com.android.settings.Utils.isWifiOnly(mActivity)) {
- addRadioUsage(uSecNow);
- }
- }
-
- private BatterySipper addEntry(String label, DrainType drainType, long time, int iconId,
- double power) {
- mTotalPower += power;
- return addEntryNoTotal(label, drainType, time, iconId, power);
- }
-
- private BatterySipper addEntryNoTotal(String label, DrainType drainType, long time, int iconId,
- double power) {
- if (power > mMaxPower) mMaxPower = power;
- mTotalPower += power;
- BatterySipper bs = new BatterySipper(mActivity, mRequestQueue, mHandler,
- label, drainType, iconId, null, new double[] {power});
- bs.usageTime = time;
- bs.iconId = iconId;
- mUsageList.add(bs);
- return bs;
- }
-
- public List<BatterySipper> getUsageList() {
- return mUsageList;
- }
-
- static final int MSG_UPDATE_NAME_ICON = 1;
- static final int MSG_REPORT_FULLY_DRAWN = 2;
-
- public double getMaxPower() {
- return mMaxPower;
- }
-
- public double getTotalPower() {
- return mTotalPower;
- }
-
- public double getMinDrainedPower() {
- return mMinDrainedPower;
- }
-
- public double getMaxDrainedPower() {
- return mMaxDrainedPower;
- }
-
- private void load() {
- try {
- byte[] data = mBatteryInfo.getStatistics();
- Parcel parcel = Parcel.obtain();
- parcel.unmarshall(data, 0, data.length);
- parcel.setDataPosition(0);
- mStats = com.android.internal.os.BatteryStatsImpl.CREATOR
- .createFromParcel(parcel);
- mStats.distributeWorkLocked(BatteryStats.STATS_SINCE_CHARGED);
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException:", e);
- }
- }
-}
diff --git a/src/com/android/settings/fuelgauge/PowerGaugePreference.java b/src/com/android/settings/fuelgauge/PowerGaugePreference.java
index c8bfa21..e10b74f 100644
--- a/src/com/android/settings/fuelgauge/PowerGaugePreference.java
+++ b/src/com/android/settings/fuelgauge/PowerGaugePreference.java
@@ -24,6 +24,7 @@ import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
+import com.android.internal.os.BatterySipper;
import com.android.settings.R;
/**
@@ -31,11 +32,11 @@ import com.android.settings.R;
* the left for the subsystem/app type.
*/
public class PowerGaugePreference extends Preference {
- private BatterySipper mInfo;
+ private BatteryEntry mInfo;
private int mProgress;
private CharSequence mProgressText;
- public PowerGaugePreference(Context context, Drawable icon, BatterySipper info) {
+ public PowerGaugePreference(Context context, Drawable icon, BatteryEntry info) {
super(context);
setLayoutResource(R.layout.app_percentage_item);
setIcon(icon != null ? icon : new ColorDrawable(0));
@@ -49,7 +50,7 @@ public class PowerGaugePreference extends Preference {
notifyChanged();
}
- BatterySipper getInfo() {
+ BatteryEntry getInfo() {
return mInfo;
}
diff --git a/src/com/android/settings/fuelgauge/PowerUsageDetail.java b/src/com/android/settings/fuelgauge/PowerUsageDetail.java
index 79b7c42..6a3a31b 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageDetail.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageDetail.java
@@ -34,13 +34,13 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.net.Uri;
+import android.os.BatteryStats;
import android.os.Bundle;
import android.os.Process;
import android.os.UserHandle;
import android.preference.PreferenceActivity;
import android.provider.Settings;
import android.text.TextUtils;
-import android.text.format.Formatter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -49,6 +49,9 @@ import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
+import com.android.internal.os.BatterySipper;
+import com.android.internal.os.BatteryStatsHelper;
+import com.android.internal.util.FastPrintWriter;
import com.android.settings.DisplaySettings;
import com.android.settings.R;
import com.android.settings.WirelessSettings;
@@ -57,20 +60,11 @@ import com.android.settings.bluetooth.BluetoothSettings;
import com.android.settings.location.LocationSettings;
import com.android.settings.wifi.WifiSettings;
-public class PowerUsageDetail extends Fragment implements Button.OnClickListener {
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.Writer;
- enum DrainType {
- IDLE,
- CELL,
- PHONE,
- WIFI,
- BLUETOOTH,
- SCREEN,
- APP,
- USER,
- UNACCOUNTED,
- OVERCOUNTED
- }
+public class PowerUsageDetail extends Fragment implements Button.OnClickListener {
// Note: Must match the sequence of the DrainType
private static int[] sDrainTypeDesciptions = new int[] {
@@ -86,6 +80,170 @@ public class PowerUsageDetail extends Fragment implements Button.OnClickListener
R.string.battery_desc_overcounted,
};
+ public static void startBatteryDetailPage(
+ PreferenceActivity caller, BatteryStatsHelper helper, BatteryEntry entry,
+ boolean showLocationButton) {
+ // Initialize mStats if necessary.
+ helper.getStats();
+
+ Bundle args = new Bundle();
+ args.putString(PowerUsageDetail.EXTRA_TITLE, entry.name);
+ args.putInt(PowerUsageDetail.EXTRA_PERCENT, (int)
+ Math.ceil(entry.sipper.value * 100 / helper.getTotalPower()));
+ args.putInt(PowerUsageDetail.EXTRA_GAUGE, (int)
+ Math.ceil(entry.sipper.value * 100 / helper.getMaxPower()));
+ args.putLong(PowerUsageDetail.EXTRA_USAGE_DURATION, helper.getStatsPeriod());
+ args.putString(PowerUsageDetail.EXTRA_ICON_PACKAGE, entry.defaultPackageName);
+ args.putInt(PowerUsageDetail.EXTRA_ICON_ID, entry.iconId);
+ args.putDouble(PowerUsageDetail.EXTRA_NO_COVERAGE, entry.sipper.noCoveragePercent);
+ if (entry.sipper.uidObj != null) {
+ args.putInt(PowerUsageDetail.EXTRA_UID, entry.sipper.uidObj.getUid());
+ }
+ args.putSerializable(PowerUsageDetail.EXTRA_DRAIN_TYPE, entry.sipper.drainType);
+ args.putBoolean(PowerUsageDetail.EXTRA_SHOW_LOCATION_BUTTON, showLocationButton);
+
+ int[] types;
+ double[] values;
+ switch (entry.sipper.drainType) {
+ case APP:
+ case USER:
+ {
+ BatteryStats.Uid uid = entry.sipper.uidObj;
+ types = new int[] {
+ R.string.usage_type_cpu,
+ R.string.usage_type_cpu_foreground,
+ R.string.usage_type_wake_lock,
+ R.string.usage_type_gps,
+ R.string.usage_type_wifi_running,
+ R.string.usage_type_data_recv,
+ R.string.usage_type_data_send,
+ R.string.usage_type_data_wifi_recv,
+ R.string.usage_type_data_wifi_send,
+ R.string.usage_type_audio,
+ R.string.usage_type_video,
+ };
+ values = new double[] {
+ entry.sipper.cpuTime,
+ entry.sipper.cpuFgTime,
+ entry.sipper.wakeLockTime,
+ entry.sipper.gpsTime,
+ entry.sipper.wifiRunningTime,
+ entry.sipper.mobileRxPackets,
+ entry.sipper.mobileTxPackets,
+ entry.sipper.wifiRxPackets,
+ entry.sipper.wifiTxPackets,
+ 0,
+ 0
+ };
+
+ if (entry.sipper.drainType == BatterySipper.DrainType.APP) {
+ Writer result = new StringWriter();
+ PrintWriter printWriter = new FastPrintWriter(result, false, 1024);
+ helper.getStats().dumpLocked(caller, printWriter, "", helper.getStatsType(),
+ uid.getUid());
+ printWriter.flush();
+ args.putString(PowerUsageDetail.EXTRA_REPORT_DETAILS, result.toString());
+
+ result = new StringWriter();
+ printWriter = new FastPrintWriter(result, false, 1024);
+ helper.getStats().dumpCheckinLocked(caller, printWriter, helper.getStatsType(),
+ uid.getUid());
+ printWriter.flush();
+ args.putString(PowerUsageDetail.EXTRA_REPORT_CHECKIN_DETAILS,
+ result.toString());
+ }
+ }
+ break;
+ case CELL:
+ {
+ types = new int[] {
+ R.string.usage_type_on_time,
+ R.string.usage_type_no_coverage
+ };
+ values = new double[] {
+ entry.sipper.usageTime,
+ entry.sipper.noCoveragePercent
+ };
+ }
+ break;
+ case WIFI:
+ {
+ types = new int[] {
+ R.string.usage_type_wifi_running,
+ R.string.usage_type_cpu,
+ R.string.usage_type_cpu_foreground,
+ R.string.usage_type_wake_lock,
+ R.string.usage_type_data_recv,
+ R.string.usage_type_data_send,
+ R.string.usage_type_data_wifi_recv,
+ R.string.usage_type_data_wifi_send,
+ };
+ values = new double[] {
+ entry.sipper.usageTime,
+ entry.sipper.cpuTime,
+ entry.sipper.cpuFgTime,
+ entry.sipper.wakeLockTime,
+ entry.sipper.mobileRxPackets,
+ entry.sipper.mobileTxPackets,
+ entry.sipper.wifiRxPackets,
+ entry.sipper.wifiTxPackets,
+ };
+ } break;
+ case BLUETOOTH:
+ {
+ types = new int[] {
+ R.string.usage_type_on_time,
+ R.string.usage_type_cpu,
+ R.string.usage_type_cpu_foreground,
+ R.string.usage_type_wake_lock,
+ R.string.usage_type_data_recv,
+ R.string.usage_type_data_send,
+ R.string.usage_type_data_wifi_recv,
+ R.string.usage_type_data_wifi_send,
+ };
+ values = new double[] {
+ entry.sipper.usageTime,
+ entry.sipper.cpuTime,
+ entry.sipper.cpuFgTime,
+ entry.sipper.wakeLockTime,
+ entry.sipper.mobileRxPackets,
+ entry.sipper.mobileTxPackets,
+ entry.sipper.wifiRxPackets,
+ entry.sipper.wifiTxPackets,
+ };
+ } break;
+ case UNACCOUNTED:
+ case OVERCOUNTED:
+ {
+ types = new int[] {
+ R.string.usage_type_total_battery_capacity,
+ R.string.usage_type_computed_power,
+ R.string.usage_type_min_actual_power,
+ R.string.usage_type_max_actual_power,
+ };
+ values = new double[] {
+ helper.getPowerProfile().getBatteryCapacity(),
+ helper.getTotalPower(),
+ helper.getMinDrainedPower(),
+ helper.getMaxDrainedPower(),
+ };
+ } break;
+ default:
+ {
+ types = new int[] {
+ R.string.usage_type_on_time
+ };
+ values = new double[] {
+ entry.sipper.usageTime
+ };
+ }
+ }
+ args.putIntArray(PowerUsageDetail.EXTRA_DETAIL_TYPES, types);
+ args.putDoubleArray(PowerUsageDetail.EXTRA_DETAIL_VALUES, values);
+ caller.startPreferencePanel(PowerUsageDetail.class.getName(), args,
+ R.string.details_title, null, null, 0);
+ }
+
public static final int ACTION_DISPLAY_SETTINGS = 1;
public static final int ACTION_WIFI_SETTINGS = 2;
public static final int ACTION_BLUETOOTH_SETTINGS = 3;
@@ -129,7 +287,7 @@ public class PowerUsageDetail extends Fragment implements Button.OnClickListener
private ViewGroup mDetailsParent;
private ViewGroup mControlsParent;
private long mStartTime;
- private DrainType mDrainType;
+ private BatterySipper.DrainType mDrainType;
private Drawable mAppIcon;
private double mNoCoverage; // Percentage of time that there was no coverage
@@ -179,7 +337,7 @@ public class PowerUsageDetail extends Fragment implements Button.OnClickListener
final int gaugeValue = args.getInt(EXTRA_GAUGE, 1);
mUsageSince = args.getInt(EXTRA_USAGE_SINCE, USAGE_SINCE_UNPLUGGED);
mUid = args.getInt(EXTRA_UID, 0);
- mDrainType = (DrainType) args.getSerializable(EXTRA_DRAIN_TYPE);
+ mDrainType = (BatterySipper.DrainType) args.getSerializable(EXTRA_DRAIN_TYPE);
mNoCoverage = args.getDouble(EXTRA_NO_COVERAGE, 0);
String iconPackage = args.getString(EXTRA_ICON_PACKAGE);
int iconId = args.getInt(EXTRA_ICON_ID, 0);
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
index 2c78375..06aff2e 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
@@ -26,6 +26,8 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Parcel;
+import android.os.UserHandle;
+import android.os.UserManager;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment;
@@ -36,6 +38,8 @@ import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
+import com.android.internal.os.BatterySipper;
+import com.android.internal.os.BatteryStatsHelper;
import com.android.internal.os.PowerProfile;
import com.android.settings.HelpUtils;
import com.android.settings.R;
@@ -59,6 +63,8 @@ public class PowerUsageSummary extends PreferenceFragment {
private static final int MENU_STATS_REFRESH = Menu.FIRST + 1;
private static final int MENU_HELP = Menu.FIRST + 2;
+ private UserManager mUm;
+
private PreferenceGroup mAppListGroup;
private String mBatteryLevel;
private String mBatteryStatus;
@@ -87,7 +93,8 @@ public class PowerUsageSummary extends PreferenceFragment {
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
- mStatsHelper = new BatteryStatsHelper(activity, mHandler);
+ mUm = (UserManager) activity.getSystemService(Context.USER_SERVICE);
+ mStatsHelper = new BatteryStatsHelper(activity);
}
@Override
@@ -111,8 +118,8 @@ public class PowerUsageSummary extends PreferenceFragment {
@Override
public void onPause() {
- mStatsHelper.pause();
- mHandler.removeMessages(BatteryStatsHelper.MSG_UPDATE_NAME_ICON);
+ BatteryEntry.stopRequestQueue();
+ mHandler.removeMessages(BatteryEntry.MSG_UPDATE_NAME_ICON);
getActivity().unregisterReceiver(mBatteryInfoReceiver);
super.onPause();
}
@@ -120,7 +127,10 @@ public class PowerUsageSummary extends PreferenceFragment {
@Override
public void onDestroy() {
super.onDestroy();
- mStatsHelper.destroy();
+ if (getActivity().isChangingConfigurations()) {
+ mStatsHelper.storeState();
+ BatteryEntry.clearUidCache();
+ }
}
@Override
@@ -140,8 +150,9 @@ public class PowerUsageSummary extends PreferenceFragment {
return false;
}
PowerGaugePreference pgp = (PowerGaugePreference) preference;
- BatterySipper sipper = pgp.getInfo();
- mStatsHelper.startBatteryDetailPage((PreferenceActivity) getActivity(), sipper, true);
+ BatteryEntry entry = pgp.getInfo();
+ PowerUsageDetail.startBatteryDetailPage((PreferenceActivity) getActivity(), mStatsHelper,
+ entry, true);
return super.onPreferenceTreeClick(preferenceScreen, preference);
}
@@ -227,20 +238,22 @@ public class PowerUsageSummary extends PreferenceFragment {
addNotAvailableMessage();
return;
}
- mStatsHelper.refreshStats(false);
+ mStatsHelper.refreshStats(BatteryStats.STATS_SINCE_CHARGED, UserHandle.myUserId());
List<BatterySipper> usageList = mStatsHelper.getUsageList();
- for (BatterySipper sipper : usageList) {
- if (sipper.getSortValue() < MIN_POWER_THRESHOLD) continue;
+ for (int i=0; i<usageList.size(); i++) {
+ BatterySipper sipper = usageList.get(i);
+ if ((sipper.value*60*60) < MIN_POWER_THRESHOLD) continue;
final double percentOfTotal =
- ((sipper.getSortValue() / mStatsHelper.getTotalPower()) * 100);
+ ((sipper.value / mStatsHelper.getTotalPower()) * 100);
if (percentOfTotal < 1) continue;
+ BatteryEntry entry = new BatteryEntry(getActivity(), mHandler, mUm, sipper);
PowerGaugePreference pref =
- new PowerGaugePreference(getActivity(), sipper.getIcon(), sipper);
+ new PowerGaugePreference(getActivity(), entry.getIcon(), entry);
final double percentOfMax =
- (sipper.getSortValue() * 100) / mStatsHelper.getMaxPower();
+ (sipper.value * 100) / mStatsHelper.getMaxPower();
sipper.percent = percentOfTotal;
- pref.setTitle(sipper.name);
- pref.setOrder(Integer.MAX_VALUE - (int) sipper.getSortValue()); // Invert the order
+ pref.setTitle(entry.getLabel());
+ pref.setOrder(i+1);
pref.setPercent(percentOfMax, percentOfTotal);
if (sipper.uidObj != null) {
pref.setKey(Integer.toString(sipper.uidObj.getUid()));
@@ -248,6 +261,8 @@ public class PowerUsageSummary extends PreferenceFragment {
mAppListGroup.addPreference(pref);
if (mAppListGroup.getPreferenceCount() > (MAX_ITEMS_TO_LIST+1)) break;
}
+
+ BatteryEntry.startRequestQueue();
}
Handler mHandler = new Handler() {
@@ -255,17 +270,17 @@ public class PowerUsageSummary extends PreferenceFragment {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
- case BatteryStatsHelper.MSG_UPDATE_NAME_ICON:
- BatterySipper bs = (BatterySipper) msg.obj;
+ case BatteryEntry.MSG_UPDATE_NAME_ICON:
+ BatteryEntry entry = (BatteryEntry) msg.obj;
PowerGaugePreference pgp =
(PowerGaugePreference) findPreference(
- Integer.toString(bs.uidObj.getUid()));
+ Integer.toString(entry.sipper.uidObj.getUid()));
if (pgp != null) {
- pgp.setIcon(bs.icon);
- pgp.setTitle(bs.name);
+ pgp.setIcon(entry.icon);
+ pgp.setTitle(entry.name);
}
break;
- case BatteryStatsHelper.MSG_REPORT_FULLY_DRAWN:
+ case BatteryEntry.MSG_REPORT_FULLY_DRAWN:
Activity activity = getActivity();
if (activity != null) {
activity.reportFullyDrawn();