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}