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 /**
     34  * Contains information about package name, icon image, power usage about an
     35  * application or a system service.
     36  */
     37 public class BatterySipper implements Comparable<BatterySipper> {
     38     final Context mContext;
     39     /* Cache cleared when PowerUsageSummary is destroyed */
     40     static final HashMap<String,UidToDetail> sUidCache = new HashMap<String,UidToDetail>();
     41     final ArrayList<BatterySipper> mRequestQueue;
     42     final Handler mHandler;
     43     String name;
     44     Drawable icon;
     45     int iconId; // For passing to the detail screen.
     46     Uid uidObj;
     47     double value;
     48     double[] values;
     49     DrainType drainType;
     50     long usageTime;
     51     long cpuTime;
     52     long gpsTime;
     53     long wifiRunningTime;
     54     long cpuFgTime;
     55     long wakeLockTime;
     56     long mobileRxBytes;
     57     long mobileTxBytes;
     58     long wifiRxBytes;
     59     long wifiTxBytes;
     60     double percent;
     61     double noCoveragePercent;
     62     String defaultPackageName;
     63     String[] mPackages;
     64 
     65     static class UidToDetail {
     66         String name;
     67         String packageName;
     68         Drawable icon;
     69     }
     70 
     71     BatterySipper(Context context, ArrayList<BatterySipper> requestQueue,
     72             Handler handler, String label, DrainType drainType,
     73             int iconId, Uid uid, double[] values) {
     74         mContext = context;
     75         mRequestQueue = requestQueue;
     76         mHandler = handler;
     77         this.values = values;
     78         name = label;
     79         this.drainType = drainType;
     80         if (iconId > 0) {
     81             icon = mContext.getResources().getDrawable(iconId);
     82         }
     83         if (values != null) value = values[0];
     84         if ((label == null || iconId == 0) && uid != null) {
     85             getQuickNameIconForUid(uid);
     86         }
     87         uidObj = uid;
     88     }
     89 
     90     double getSortValue() {
     91         return value;
     92     }
     93 
     94     double[] getValues() {
     95         return values;
     96     }
     97 
     98     public Drawable getIcon() {
     99         return icon;
    100     }
    101 
    102     /**
    103      * Gets the application name
    104      */
    105     public String getLabel() {
    106         return name;
    107     }
    108 
    109     @Override
    110     public int compareTo(BatterySipper other) {
    111         // Return the flipped value because we want the items in descending order
    112         return Double.compare(other.getSortValue(), getSortValue());
    113     }
    114 
    115     /**
    116      * Gets a list of packages associated with the current user
    117      */
    118     public String[] getPackages() {
    119         return mPackages;
    120     }
    121 
    122     public int getUid() {
    123         // Bail out if the current sipper is not an App sipper.
    124         if (uidObj == null) {
    125             return 0;
    126         }
    127         return uidObj.getUid();
    128     }
    129 
    130     void getQuickNameIconForUid(Uid uidObj) {
    131         final int uid = uidObj.getUid();
    132         final String uidString = Integer.toString(uid);
    133         if (sUidCache.containsKey(uidString)) {
    134             UidToDetail utd = sUidCache.get(uidString);
    135             defaultPackageName = utd.packageName;
    136             name = utd.name;
    137             icon = utd.icon;
    138             return;
    139         }
    140         PackageManager pm = mContext.getPackageManager();
    141         String[] packages = pm.getPackagesForUid(uid);
    142         icon = pm.getDefaultActivityIcon();
    143         if (packages == null) {
    144             //name = Integer.toString(uid);
    145             if (uid == 0) {
    146                 name = mContext.getResources().getString(R.string.process_kernel_label);
    147             } else if ("mediaserver".equals(name)) {
    148                 name = mContext.getResources().getString(R.string.process_mediaserver_label);
    149             }
    150             iconId = R.drawable.ic_power_system;
    151             icon = mContext.getResources().getDrawable(iconId);
    152             return;
    153         } else {
    154             //name = packages[0];
    155         }
    156         if (mHandler != null) {
    157             synchronized (mRequestQueue) {
    158                 mRequestQueue.add(this);
    159             }
    160         }
    161     }
    162 
    163     public static void clearUidCache() {
    164         sUidCache.clear();
    165     }
    166 
    167     /**
    168      * Loads the app label and icon image and stores into the cache.
    169      */
    170     public void loadNameAndIcon() {
    171         // Bail out if the current sipper is not an App sipper.
    172         if (uidObj == null) {
    173             return;
    174         }
    175         PackageManager pm = mContext.getPackageManager();
    176         final int uid = uidObj.getUid();
    177         final Drawable defaultActivityIcon = pm.getDefaultActivityIcon();
    178         mPackages = pm.getPackagesForUid(uid);
    179         if (mPackages == null) {
    180             name = Integer.toString(uid);
    181             return;
    182         }
    183 
    184         String[] packageLabels = new String[mPackages.length];
    185         System.arraycopy(mPackages, 0, packageLabels, 0, mPackages.length);
    186 
    187         int preferredIndex = -1;
    188         // Convert package names to user-facing labels where possible
    189         for (int i = 0; i < packageLabels.length; i++) {
    190             // Check if package matches preferred package
    191             if (packageLabels[i].equals(name)) preferredIndex = i;
    192             try {
    193                 ApplicationInfo ai = pm.getApplicationInfo(packageLabels[i], 0);
    194                 CharSequence label = ai.loadLabel(pm);
    195                 if (label != null) {
    196                     packageLabels[i] = label.toString();
    197                 }
    198                 if (ai.icon != 0) {
    199                     defaultPackageName = mPackages[i];
    200                     icon = ai.loadIcon(pm);
    201                     break;
    202                 }
    203             } catch (NameNotFoundException e) {
    204             }
    205         }
    206         if (icon == null) icon = defaultActivityIcon;
    207 
    208         if (packageLabels.length == 1) {
    209             name = packageLabels[0];
    210         } else {
    211             // Look for an official name for this UID.
    212             for (String pkgName : mPackages) {
    213                 try {
    214                     final PackageInfo pi = pm.getPackageInfo(pkgName, 0);
    215                     if (pi.sharedUserLabel != 0) {
    216                         final CharSequence nm = pm.getText(pkgName,
    217                                 pi.sharedUserLabel, pi.applicationInfo);
    218                         if (nm != null) {
    219                             name = nm.toString();
    220                             if (pi.applicationInfo.icon != 0) {
    221                                 defaultPackageName = pkgName;
    222                                 icon = pi.applicationInfo.loadIcon(pm);
    223                             }
    224                             break;
    225                         }
    226                     }
    227                 } catch (PackageManager.NameNotFoundException e) {
    228                 }
    229             }
    230         }
    231         final String uidString = Integer.toString(uidObj.getUid());
    232         UidToDetail utd = new UidToDetail();
    233         utd.name = name;
    234         utd.icon = icon;
    235         utd.packageName = defaultPackageName;
    236         sUidCache.put(uidString, utd);
    237         if (mHandler != null) {
    238             mHandler.sendMessage(
    239                     mHandler.obtainMessage(BatteryStatsHelper.MSG_UPDATE_NAME_ICON, this));
    240         }
    241     }
    242 }
    243