Home | History | Annotate | Download | only in fuelgauge
      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 
     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 
     83     double getSortValue() {
     84         return value;
     85     }
     86 
     87     double[] getValues() {
     88         return values;
     89     }
     90 
     91     Drawable getIcon() {
     92         return icon;
     93     }
     94 
     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 
    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      */
    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 }