BatterySipper.java revision be5994d20152c7194aac79eb8152240655fd3373
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 */ 16package com.android.settings.fuelgauge; 17 18import com.android.settings.R; 19import com.android.settings.fuelgauge.PowerUsageDetail.DrainType; 20 21import android.content.Context; 22import android.content.pm.ApplicationInfo; 23import android.content.pm.PackageInfo; 24import android.content.pm.PackageManager; 25import android.content.pm.PackageManager.NameNotFoundException; 26import android.graphics.drawable.Drawable; 27import android.os.Handler; 28import android.os.BatteryStats.Uid; 29 30import java.util.ArrayList; 31import java.util.HashMap; 32 33class 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 cpuFgTime; 49 long wakeLockTime; 50 double percent; 51 double noCoveragePercent; 52 String defaultPackageName; 53 54 static class UidToDetail { 55 String name; 56 String packageName; 57 Drawable icon; 58 } 59 60 BatterySipper(Context context, ArrayList<BatterySipper> requestQueue, 61 Handler handler, String label, DrainType drainType, 62 int iconId, Uid uid, double[] values) { 63 mContext = context; 64 mRequestQueue = requestQueue; 65 mHandler = handler; 66 this.values = values; 67 name = label; 68 this.drainType = drainType; 69 if (iconId > 0) { 70 icon = mContext.getResources().getDrawable(iconId); 71 } 72 if (values != null) value = values[0]; 73 if ((label == null || iconId == 0) && uid != null) { 74 getQuickNameIconForUid(uid); 75 } 76 uidObj = uid; 77 } 78 79 double getSortValue() { 80 return value; 81 } 82 83 double[] getValues() { 84 return values; 85 } 86 87 Drawable getIcon() { 88 return icon; 89 } 90 91 public int compareTo(BatterySipper other) { 92 // Return the flipped value because we want the items in descending order 93 return (int) (other.getSortValue() - getSortValue()); 94 } 95 96 void getQuickNameIconForUid(Uid uidObj) { 97 final int uid = uidObj.getUid(); 98 final String uidString = Integer.toString(uid); 99 if (mUidCache.containsKey(uidString)) { 100 UidToDetail utd = mUidCache.get(uidString); 101 defaultPackageName = utd.packageName; 102 name = utd.name; 103 icon = utd.icon; 104 return; 105 } 106 PackageManager pm = mContext.getPackageManager(); 107 final Drawable defaultActivityIcon = pm.getDefaultActivityIcon(); 108 String[] packages = pm.getPackagesForUid(uid); 109 icon = pm.getDefaultActivityIcon(); 110 if (packages == null) { 111 //name = Integer.toString(uid); 112 if (uid == 0) { 113 name = mContext.getResources().getString(R.string.process_kernel_label); 114 } else if ("mediaserver".equals(name)) { 115 name = mContext.getResources().getString(R.string.process_mediaserver_label); 116 } 117 iconId = R.drawable.ic_power_system; 118 icon = mContext.getResources().getDrawable(iconId); 119 return; 120 } else { 121 //name = packages[0]; 122 } 123 synchronized (mRequestQueue) { 124 mRequestQueue.add(this); 125 } 126 } 127 128 /** 129 * Sets name and icon 130 * @param uid Uid of the application 131 */ 132 void getNameIcon() { 133 PackageManager pm = mContext.getPackageManager(); 134 final int uid = uidObj.getUid(); 135 final Drawable defaultActivityIcon = pm.getDefaultActivityIcon(); 136 String[] packages = pm.getPackagesForUid(uid); 137 if (packages == null) { 138 name = Integer.toString(uid); 139 return; 140 } 141 142 String[] packageLabels = new String[packages.length]; 143 System.arraycopy(packages, 0, packageLabels, 0, packages.length); 144 145 int preferredIndex = -1; 146 // Convert package names to user-facing labels where possible 147 for (int i = 0; i < packageLabels.length; i++) { 148 // Check if package matches preferred package 149 if (packageLabels[i].equals(name)) preferredIndex = i; 150 try { 151 ApplicationInfo ai = pm.getApplicationInfo(packageLabels[i], 0); 152 CharSequence label = ai.loadLabel(pm); 153 if (label != null) { 154 packageLabels[i] = label.toString(); 155 } 156 if (ai.icon != 0) { 157 defaultPackageName = packages[i]; 158 icon = ai.loadIcon(pm); 159 break; 160 } 161 } catch (NameNotFoundException e) { 162 } 163 } 164 if (icon == null) icon = defaultActivityIcon; 165 166 if (packageLabels.length == 1) { 167 name = packageLabels[0]; 168 } else { 169 // Look for an official name for this UID. 170 for (String pkgName : packages) { 171 try { 172 final PackageInfo pi = pm.getPackageInfo(pkgName, 0); 173 if (pi.sharedUserLabel != 0) { 174 final CharSequence nm = pm.getText(pkgName, 175 pi.sharedUserLabel, pi.applicationInfo); 176 if (nm != null) { 177 name = nm.toString(); 178 if (pi.applicationInfo.icon != 0) { 179 defaultPackageName = pkgName; 180 icon = pi.applicationInfo.loadIcon(pm); 181 } 182 break; 183 } 184 } 185 } catch (PackageManager.NameNotFoundException e) { 186 } 187 } 188 } 189 final String uidString = Integer.toString(uidObj.getUid()); 190 UidToDetail utd = new UidToDetail(); 191 utd.name = name; 192 utd.icon = icon; 193 utd.packageName = defaultPackageName; 194 mUidCache.put(uidString, utd); 195 mHandler.sendMessage(mHandler.obtainMessage(PowerUsageSummary.MSG_UPDATE_NAME_ICON, this)); 196 } 197}