2 * Copyright (C) 2011 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.settings.net;
19 import android.app.AppGlobals;
20 import android.content.Context;
21 import android.content.pm.ApplicationInfo;
22 import android.content.pm.IPackageManager;
23 import android.content.pm.PackageInfo;
24 import android.content.pm.PackageManager;
25 import android.content.pm.PackageManager.NameNotFoundException;
26 import android.content.pm.UserInfo;
27 import android.content.res.Resources;
28 import android.graphics.drawable.Drawable;
29 import android.net.ConnectivityManager;
30 import android.net.TrafficStats;
31 import android.os.UserManager;
32 import android.os.UserHandle;
33 import android.os.RemoteException;
34 import android.text.TextUtils;
35 import android.util.Log;
36 import android.util.SparseArray;
38 import com.android.settings.R;
39 import com.android.settings.Utils;
42 * Return details about a specific UID, handling special cases like
43 * {@link TrafficStats#UID_TETHERING} and {@link UserInfo}.
45 public class UidDetailProvider {
46 private static final String TAG = "DataUsage";
47 private final Context mContext;
48 private final SparseArray<UidDetail> mUidDetailCache;
50 public static final int OTHER_USER_RANGE_START = -2000;
52 public static int buildKeyForUser(int userHandle) {
53 return OTHER_USER_RANGE_START - userHandle;
56 public static boolean isKeyForUser(int key) {
57 return key <= OTHER_USER_RANGE_START;
60 public static int getUserIdForKey(int key) {
61 return OTHER_USER_RANGE_START - key;
64 public UidDetailProvider(Context context) {
65 mContext = context.getApplicationContext();
66 mUidDetailCache = new SparseArray<UidDetail>();
69 public void clearCache() {
70 synchronized (mUidDetailCache) {
71 mUidDetailCache.clear();
76 * Resolve best descriptive label for the given UID.
78 public UidDetail getUidDetail(int uid, boolean blocking) {
81 synchronized (mUidDetailCache) {
82 detail = mUidDetailCache.get(uid);
87 } else if (!blocking) {
91 detail = buildUidDetail(uid);
93 synchronized (mUidDetailCache) {
94 mUidDetailCache.put(uid, detail);
101 * Build {@link UidDetail} object, blocking until all {@link Drawable}
102 * lookup is finished.
104 private UidDetail buildUidDetail(int uid) {
105 final Resources res = mContext.getResources();
106 final PackageManager pm = mContext.getPackageManager();
108 final UidDetail detail = new UidDetail();
109 detail.label = pm.getNameForUid(uid);
110 detail.icon = pm.getDefaultActivityIcon();
112 // handle special case labels
114 case android.os.Process.SYSTEM_UID:
115 detail.label = res.getString(R.string.process_kernel_label);
116 detail.icon = pm.getDefaultActivityIcon();
118 case TrafficStats.UID_REMOVED:
119 detail.label = res.getString(UserManager.supportsMultipleUsers()
120 ? R.string.data_usage_uninstalled_apps_users
121 : R.string.data_usage_uninstalled_apps);
122 detail.icon = pm.getDefaultActivityIcon();
124 case TrafficStats.UID_TETHERING:
125 final ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(
126 Context.CONNECTIVITY_SERVICE);
127 detail.label = res.getString(Utils.getTetheringLabel(cm));
128 detail.icon = pm.getDefaultActivityIcon();
132 final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
134 // Handle keys that are actually user handles
135 if (isKeyForUser(uid)) {
136 final int userHandle = getUserIdForKey(uid);
137 final UserInfo info = um.getUserInfo(userHandle);
139 if (info.isManagedProfile()) {
140 detail.label = res.getString(R.string.managed_user_title);
141 detail.icon = Resources.getSystem().getDrawable(
142 com.android.internal.R.drawable.ic_corp_icon);
144 detail.label = res.getString(R.string.running_process_item_user_label,
146 detail.icon = Utils.getUserIcon(mContext, um, info);
152 // otherwise fall back to using packagemanager labels
153 final String[] packageNames = pm.getPackagesForUid(uid);
154 final int length = packageNames != null ? packageNames.length : 0;
156 final int userId = UserHandle.getUserId(uid);
157 UserHandle userHandle = new UserHandle(userId);
158 IPackageManager ipm = AppGlobals.getPackageManager();
160 final ApplicationInfo info = ipm.getApplicationInfo(packageNames[0],
161 0 /* no flags */, userId);
163 detail.label = info.loadLabel(pm).toString();
164 detail.icon = um.getBadgedIconForUser(info.loadIcon(pm),
165 new UserHandle(userId));
167 } else if (length > 1) {
168 detail.detailLabels = new CharSequence[length];
169 detail.detailContentDescriptions = new CharSequence[length];
170 for (int i = 0; i < length; i++) {
171 final String packageName = packageNames[i];
172 final PackageInfo packageInfo = pm.getPackageInfo(packageName, 0);
173 final ApplicationInfo appInfo = ipm.getApplicationInfo(packageName,
174 0 /* no flags */, userId);
176 if (appInfo != null) {
177 detail.detailLabels[i] = appInfo.loadLabel(pm).toString();
178 detail.detailContentDescriptions[i] = um.getBadgedLabelForUser(
179 detail.detailLabels[i], userHandle);
180 if (packageInfo.sharedUserLabel != 0) {
181 detail.label = pm.getText(packageName, packageInfo.sharedUserLabel,
182 packageInfo.applicationInfo).toString();
183 detail.icon = um.getBadgedIconForUser(appInfo.loadIcon(pm), userHandle);
188 detail.contentDescription = um.getBadgedLabelForUser(detail.label, userHandle);
189 } catch (NameNotFoundException e) {
190 Log.w(TAG, "Error while building UI detail for uid "+uid, e);
191 } catch (RemoteException e) {
192 Log.w(TAG, "Error while building UI detail for uid "+uid, e);
195 if (TextUtils.isEmpty(detail.label)) {
196 detail.label = Integer.toString(uid);