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 final HashMap<String,UidToDetail> mUidCache = new HashMap<String,UidToDetail>(); 36 final ArrayList<BatterySipper> mRequestQueue; 37 final Handler mHandler; 38 String name; 39 Drawable icon; 40 int iconId; // For passing to the detail screen. 41 Uid uidObj; 42 double value; 43 double[] values; 44 DrainType drainType; 45 long usageTime; 46 long cpuTime; 47 long gpsTime; 48 long wifiRunningTime; 49 long cpuFgTime; 50 long wakeLockTime; 51 long tcpBytesReceived; 52 long tcpBytesSent; 53 double percent; 54 double noCoveragePercent; 55 String defaultPackageName; 56 57 static class UidToDetail { 58 String name; 59 String packageName; 60 Drawable icon; 61 } 62 63 BatterySipper(Context context, ArrayList<BatterySipper> requestQueue, 64 Handler handler, String label, DrainType drainType, 65 int iconId, Uid uid, double[] values) { 66 mContext = context; 67 mRequestQueue = requestQueue; 68 mHandler = handler; 69 this.values = values; 70 name = label; 71 this.drainType = drainType; 72 if (iconId > 0) { 73 icon = mContext.getResources().getDrawable(iconId); 74 } 75 if (values != null) value = values[0]; 76 if ((label == null || iconId == 0) && uid != null) { 77 getQuickNameIconForUid(uid); 78 } 79 uidObj = uid; 80 } 81 82 double getSortValue() { 83 return value; 84 } 85 86 double[] getValues() { 87 return values; 88 } 89 90 Drawable getIcon() { 91 return icon; 92 } 93 94 public int compareTo(BatterySipper other) { 95 // Return the flipped value because we want the items in descending order 96 return (int) (other.getSortValue() - getSortValue()); 97 } 98 99 void getQuickNameIconForUid(Uid uidObj) { 100 final int uid = uidObj.getUid(); 101 final String uidString = Integer.toString(uid); 102 if (mUidCache.containsKey(uidString)) { 103 UidToDetail utd = mUidCache.get(uidString); 104 defaultPackageName = utd.packageName; 105 name = utd.name; 106 icon = utd.icon; 107 return; 108 } 109 PackageManager pm = mContext.getPackageManager(); 110 final Drawable defaultActivityIcon = pm.getDefaultActivityIcon(); 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 */ 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 mUidCache.put(uidString, utd); 198 mHandler.sendMessage(mHandler.obtainMessage(PowerUsageSummary.MSG_UPDATE_NAME_ICON, this)); 199 } 200 }