Loading src/com/android/settings/fuelgauge/BatterySipper.java→src/com/android/settings/fuelgauge/BatteryEntry.java +305 −0 Original line number Diff line number Diff line /* * Copyright (C) 2009 The Android Open Source Project * 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. Loading @@ -13,58 +13,105 @@ * 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; 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.PackageManager.NameNotFoundException; import android.content.pm.UserInfo; import android.graphics.drawable.Drawable; import android.os.BatteryStats; import android.os.Handler; import android.os.BatteryStats.Uid; 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; /** * Contains information about package name, icon image, power usage about an * application or a system service. * Wraps the power usage data of a BatterySipper with information about package name * and icon image. */ public class BatterySipper implements Comparable<BatterySipper> { final Context mContext; /* Cache cleared when PowerUsageSummary is destroyed */ 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>(); 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 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; Loading @@ -72,31 +119,69 @@ public class BatterySipper implements Comparable<BatterySipper> { Drawable icon; } BatterySipper(Context context, ArrayList<BatterySipper> requestQueue, Handler handler, String label, DrainType drainType, int iconId, Uid uid, double[] values) { mContext = context; mRequestQueue = requestQueue; public BatteryEntry(Context context, Handler handler, UserManager um, BatterySipper sipper) { mHandler = handler; this.values = values; name = label; this.drainType = drainType; if (iconId > 0) { icon = mContext.getResources().getDrawable(iconId); 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); } if (values != null) value = values[0]; if ((label == null || iconId == 0) && uid != null) { getQuickNameIconForUid(uid); } 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; } uidObj = uid; if (iconId > 0) { icon = context.getResources().getDrawable(iconId); } double getSortValue() { return value; if ((name == null || iconId == 0) && this.sipper.uidObj != null) { getQuickNameIconForUid(this.sipper.uidObj); } double[] getValues() { return values; } public Drawable getIcon() { Loading @@ -110,28 +195,7 @@ public class BatterySipper implements Comparable<BatterySipper> { 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) { void getQuickNameIconForUid(BatteryStats.Uid uidObj) { final int uid = uidObj.getUid(); final String uidString = Integer.toString(uid); if (sUidCache.containsKey(uidString)) { Loading @@ -141,18 +205,18 @@ public class BatterySipper implements Comparable<BatterySipper> { icon = utd.icon; return; } PackageManager pm = mContext.getPackageManager(); PackageManager pm = context.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); name = context.getResources().getString(R.string.process_kernel_label); } else if ("mediaserver".equals(name)) { name = mContext.getResources().getString(R.string.process_mediaserver_label); name = context.getResources().getString(R.string.process_mediaserver_label); } iconId = R.drawable.ic_power_system; icon = mContext.getResources().getDrawable(iconId); icon = context.getResources().getDrawable(iconId); return; } else { //name = packages[0]; Loading @@ -164,29 +228,25 @@ public class BatterySipper implements Comparable<BatterySipper> { } } 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) { if (sipper.uidObj == null) { return; } PackageManager pm = mContext.getPackageManager(); final int uid = uidObj.getUid(); PackageManager pm = context.getPackageManager(); final int uid = sipper.uidObj.getUid(); final Drawable defaultActivityIcon = pm.getDefaultActivityIcon(); mPackages = pm.getPackagesForUid(uid); if (mPackages == null) { sipper.mPackages = pm.getPackagesForUid(uid); if (sipper.mPackages == null) { name = Integer.toString(uid); return; } String[] packageLabels = new String[mPackages.length]; System.arraycopy(mPackages, 0, packageLabels, 0, mPackages.length); 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 Loading @@ -200,11 +260,11 @@ public class BatterySipper implements Comparable<BatterySipper> { packageLabels[i] = label.toString(); } if (ai.icon != 0) { defaultPackageName = mPackages[i]; defaultPackageName = sipper.mPackages[i]; icon = ai.loadIcon(pm); break; } } catch (NameNotFoundException e) { } catch (PackageManager.NameNotFoundException e) { } } if (icon == null) icon = defaultActivityIcon; Loading @@ -213,7 +273,7 @@ public class BatterySipper implements Comparable<BatterySipper> { name = packageLabels[0]; } else { // Look for an official name for this UID. for (String pkgName : mPackages) { for (String pkgName : sipper.mPackages) { try { final PackageInfo pi = pm.getPackageInfo(pkgName, 0); if (pi.sharedUserLabel != 0) { Loading @@ -232,15 +292,14 @@ public class BatterySipper implements Comparable<BatterySipper> { } } } final String uidString = Integer.toString(uidObj.getUid()); 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(BatteryStatsHelper.MSG_UPDATE_NAME_ICON, this)); mHandler.sendMessage(mHandler.obtainMessage(MSG_UPDATE_NAME_ICON, this)); } } } Loading
src/com/android/settings/fuelgauge/BatterySipper.java→src/com/android/settings/fuelgauge/BatteryEntry.java +305 −0 Original line number Diff line number Diff line /* * Copyright (C) 2009 The Android Open Source Project * 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. Loading @@ -13,58 +13,105 @@ * 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; 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.PackageManager.NameNotFoundException; import android.content.pm.UserInfo; import android.graphics.drawable.Drawable; import android.os.BatteryStats; import android.os.Handler; import android.os.BatteryStats.Uid; 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; /** * Contains information about package name, icon image, power usage about an * application or a system service. * Wraps the power usage data of a BatterySipper with information about package name * and icon image. */ public class BatterySipper implements Comparable<BatterySipper> { final Context mContext; /* Cache cleared when PowerUsageSummary is destroyed */ 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>(); 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 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; Loading @@ -72,31 +119,69 @@ public class BatterySipper implements Comparable<BatterySipper> { Drawable icon; } BatterySipper(Context context, ArrayList<BatterySipper> requestQueue, Handler handler, String label, DrainType drainType, int iconId, Uid uid, double[] values) { mContext = context; mRequestQueue = requestQueue; public BatteryEntry(Context context, Handler handler, UserManager um, BatterySipper sipper) { mHandler = handler; this.values = values; name = label; this.drainType = drainType; if (iconId > 0) { icon = mContext.getResources().getDrawable(iconId); 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); } if (values != null) value = values[0]; if ((label == null || iconId == 0) && uid != null) { getQuickNameIconForUid(uid); } 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; } uidObj = uid; if (iconId > 0) { icon = context.getResources().getDrawable(iconId); } double getSortValue() { return value; if ((name == null || iconId == 0) && this.sipper.uidObj != null) { getQuickNameIconForUid(this.sipper.uidObj); } double[] getValues() { return values; } public Drawable getIcon() { Loading @@ -110,28 +195,7 @@ public class BatterySipper implements Comparable<BatterySipper> { 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) { void getQuickNameIconForUid(BatteryStats.Uid uidObj) { final int uid = uidObj.getUid(); final String uidString = Integer.toString(uid); if (sUidCache.containsKey(uidString)) { Loading @@ -141,18 +205,18 @@ public class BatterySipper implements Comparable<BatterySipper> { icon = utd.icon; return; } PackageManager pm = mContext.getPackageManager(); PackageManager pm = context.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); name = context.getResources().getString(R.string.process_kernel_label); } else if ("mediaserver".equals(name)) { name = mContext.getResources().getString(R.string.process_mediaserver_label); name = context.getResources().getString(R.string.process_mediaserver_label); } iconId = R.drawable.ic_power_system; icon = mContext.getResources().getDrawable(iconId); icon = context.getResources().getDrawable(iconId); return; } else { //name = packages[0]; Loading @@ -164,29 +228,25 @@ public class BatterySipper implements Comparable<BatterySipper> { } } 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) { if (sipper.uidObj == null) { return; } PackageManager pm = mContext.getPackageManager(); final int uid = uidObj.getUid(); PackageManager pm = context.getPackageManager(); final int uid = sipper.uidObj.getUid(); final Drawable defaultActivityIcon = pm.getDefaultActivityIcon(); mPackages = pm.getPackagesForUid(uid); if (mPackages == null) { sipper.mPackages = pm.getPackagesForUid(uid); if (sipper.mPackages == null) { name = Integer.toString(uid); return; } String[] packageLabels = new String[mPackages.length]; System.arraycopy(mPackages, 0, packageLabels, 0, mPackages.length); 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 Loading @@ -200,11 +260,11 @@ public class BatterySipper implements Comparable<BatterySipper> { packageLabels[i] = label.toString(); } if (ai.icon != 0) { defaultPackageName = mPackages[i]; defaultPackageName = sipper.mPackages[i]; icon = ai.loadIcon(pm); break; } } catch (NameNotFoundException e) { } catch (PackageManager.NameNotFoundException e) { } } if (icon == null) icon = defaultActivityIcon; Loading @@ -213,7 +273,7 @@ public class BatterySipper implements Comparable<BatterySipper> { name = packageLabels[0]; } else { // Look for an official name for this UID. for (String pkgName : mPackages) { for (String pkgName : sipper.mPackages) { try { final PackageInfo pi = pm.getPackageInfo(pkgName, 0); if (pi.sharedUserLabel != 0) { Loading @@ -232,15 +292,14 @@ public class BatterySipper implements Comparable<BatterySipper> { } } } final String uidString = Integer.toString(uidObj.getUid()); 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(BatteryStatsHelper.MSG_UPDATE_NAME_ICON, this)); mHandler.sendMessage(mHandler.obtainMessage(MSG_UPDATE_NAME_ICON, this)); } } }