1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.settings.fuelgauge; 17 18 import com.android.settings.R; 19 import com.android.settings.fuelgauge.PowerUsageDetail.DrainType; 20 21 import android.content.Context; 22 import android.content.pm.ApplicationInfo; 23 import android.content.pm.PackageInfo; 24 import android.content.pm.PackageManager; 25 import android.content.pm.PackageManager.NameNotFoundException; 26 import android.graphics.drawable.Drawable; 27 import android.os.Handler; 28 import android.os.BatteryStats.Uid; 29 30 import java.util.ArrayList; 31 import java.util.HashMap; 32 33 class BatterySipper implements Comparable<BatterySipper> { 34 final Context mContext; 35 /* Cache cleared when PowerUsageSummary is destroyed */ 36 static final HashMap<String,UidToDetail> sUidCache = new HashMap<String,UidToDetail>(); 37 final ArrayList<BatterySipper> mRequestQueue; 38 final Handler mHandler; 39 String name; 40 Drawable icon; 41 int iconId; // For passing to the detail screen. 42 Uid uidObj; 43 double value; 44 double[] values; 45 DrainType drainType; 46 long usageTime; 47 long cpuTime; 48 long gpsTime; 49 long wifiRunningTime; 50 long cpuFgTime; 51 long wakeLockTime; 52 long tcpBytesReceived; 53 long tcpBytesSent; 54 double percent; 55 double noCoveragePercent; 56 String defaultPackageName; 57 58 static class UidToDetail { 59 String name; 60 String packageName; 61 Drawable icon; 62 } 63 BatterySipper(Context context, ArrayList<BatterySipper> requestQueue, Handler handler, String label, DrainType drainType, int iconId, Uid uid, double[] values)64 BatterySipper(Context context, ArrayList<BatterySipper> requestQueue, 65 Handler handler, String label, DrainType drainType, 66 int iconId, Uid uid, double[] values) { 67 mContext = context; 68 mRequestQueue = requestQueue; 69 mHandler = handler; 70 this.values = values; 71 name = label; 72 this.drainType = drainType; 73 if (iconId > 0) { 74 icon = mContext.getResources().getDrawable(iconId); 75 } 76 if (values != null) value = values[0]; 77 if ((label == null || iconId == 0) && uid != null) { 78 getQuickNameIconForUid(uid); 79 } 80 uidObj = uid; 81 } 82 getSortValue()83 double getSortValue() { 84 return value; 85 } 86 getValues()87 double[] getValues() { 88 return values; 89 } 90 getIcon()91 Drawable getIcon() { 92 return icon; 93 } 94 compareTo(BatterySipper other)95 public int compareTo(BatterySipper other) { 96 // Return the flipped value because we want the items in descending order 97 return Double.compare(other.getSortValue(), getSortValue()); 98 } 99 getQuickNameIconForUid(Uid uidObj)100 void getQuickNameIconForUid(Uid uidObj) { 101 final int uid = uidObj.getUid(); 102 final String uidString = Integer.toString(uid); 103 if (sUidCache.containsKey(uidString)) { 104 UidToDetail utd = sUidCache.get(uidString); 105 defaultPackageName = utd.packageName; 106 name = utd.name; 107 icon = utd.icon; 108 return; 109 } 110 PackageManager pm = mContext.getPackageManager(); 111 String[] packages = pm.getPackagesForUid(uid); 112 icon = pm.getDefaultActivityIcon(); 113 if (packages == null) { 114 //name = Integer.toString(uid); 115 if (uid == 0) { 116 name = mContext.getResources().getString(R.string.process_kernel_label); 117 } else if ("mediaserver".equals(name)) { 118 name = mContext.getResources().getString(R.string.process_mediaserver_label); 119 } 120 iconId = R.drawable.ic_power_system; 121 icon = mContext.getResources().getDrawable(iconId); 122 return; 123 } else { 124 //name = packages[0]; 125 } 126 synchronized (mRequestQueue) { 127 mRequestQueue.add(this); 128 } 129 } 130 131 /** 132 * Sets name and icon 133 * @param uid Uid of the application 134 */ getNameIcon()135 void getNameIcon() { 136 PackageManager pm = mContext.getPackageManager(); 137 final int uid = uidObj.getUid(); 138 final Drawable defaultActivityIcon = pm.getDefaultActivityIcon(); 139 String[] packages = pm.getPackagesForUid(uid); 140 if (packages == null) { 141 name = Integer.toString(uid); 142 return; 143 } 144 145 String[] packageLabels = new String[packages.length]; 146 System.arraycopy(packages, 0, packageLabels, 0, packages.length); 147 148 int preferredIndex = -1; 149 // Convert package names to user-facing labels where possible 150 for (int i = 0; i < packageLabels.length; i++) { 151 // Check if package matches preferred package 152 if (packageLabels[i].equals(name)) preferredIndex = i; 153 try { 154 ApplicationInfo ai = pm.getApplicationInfo(packageLabels[i], 0); 155 CharSequence label = ai.loadLabel(pm); 156 if (label != null) { 157 packageLabels[i] = label.toString(); 158 } 159 if (ai.icon != 0) { 160 defaultPackageName = packages[i]; 161 icon = ai.loadIcon(pm); 162 break; 163 } 164 } catch (NameNotFoundException e) { 165 } 166 } 167 if (icon == null) icon = defaultActivityIcon; 168 169 if (packageLabels.length == 1) { 170 name = packageLabels[0]; 171 } else { 172 // Look for an official name for this UID. 173 for (String pkgName : packages) { 174 try { 175 final PackageInfo pi = pm.getPackageInfo(pkgName, 0); 176 if (pi.sharedUserLabel != 0) { 177 final CharSequence nm = pm.getText(pkgName, 178 pi.sharedUserLabel, pi.applicationInfo); 179 if (nm != null) { 180 name = nm.toString(); 181 if (pi.applicationInfo.icon != 0) { 182 defaultPackageName = pkgName; 183 icon = pi.applicationInfo.loadIcon(pm); 184 } 185 break; 186 } 187 } 188 } catch (PackageManager.NameNotFoundException e) { 189 } 190 } 191 } 192 final String uidString = Integer.toString(uidObj.getUid()); 193 UidToDetail utd = new UidToDetail(); 194 utd.name = name; 195 utd.icon = icon; 196 utd.packageName = defaultPackageName; 197 sUidCache.put(uidString, utd); 198 mHandler.sendMessage(mHandler.obtainMessage(PowerUsageSummary.MSG_UPDATE_NAME_ICON, this)); 199 } 200 }