1b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey/* 2b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey * Copyright (C) 2011 The Android Open Source Project 3b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey * 4b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 5b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey * you may not use this file except in compliance with the License. 6b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey * You may obtain a copy of the License at 7b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey * 8b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 9b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey * 10b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey * Unless required by applicable law or agreed to in writing, software 11b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 12b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey * See the License for the specific language governing permissions and 14b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey * limitations under the License. 15b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey */ 16b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey 17b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeypackage com.android.settings.net; 18b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey 193aaf0eb457639b52228143b84d9624bf73d862eaZoltan Szatmary-Banimport android.app.AppGlobals; 20b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeyimport android.content.Context; 21b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeyimport android.content.pm.ApplicationInfo; 223aaf0eb457639b52228143b84d9624bf73d862eaZoltan Szatmary-Banimport android.content.pm.IPackageManager; 23b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeyimport android.content.pm.PackageInfo; 24b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeyimport android.content.pm.PackageManager; 25b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeyimport android.content.pm.PackageManager.NameNotFoundException; 2638305fb1777147cbcb86774c466e88434daff141Jeff Sharkeyimport android.content.pm.UserInfo; 27b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeyimport android.content.res.Resources; 28ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkeyimport android.graphics.drawable.Drawable; 29a83a24f48a8286ee3d67acc5fdcfb723acc56adaJeff Sharkeyimport android.net.ConnectivityManager; 30b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeyimport android.net.TrafficStats; 3138305fb1777147cbcb86774c466e88434daff141Jeff Sharkeyimport android.os.UserManager; 320924f199e530ce844362c79dfa60ddbe3eceac56Zoltan Szatmary-Banimport android.os.UserHandle; 333aaf0eb457639b52228143b84d9624bf73d862eaZoltan Szatmary-Banimport android.os.RemoteException; 34b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeyimport android.text.TextUtils; 353aaf0eb457639b52228143b84d9624bf73d862eaZoltan Szatmary-Banimport android.util.Log; 36b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeyimport android.util.SparseArray; 37b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey 38b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeyimport com.android.settings.R; 39a83a24f48a8286ee3d67acc5fdcfb723acc56adaJeff Sharkeyimport com.android.settings.Utils; 40b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey 4138305fb1777147cbcb86774c466e88434daff141Jeff Sharkey/** 4238305fb1777147cbcb86774c466e88434daff141Jeff Sharkey * Return details about a specific UID, handling special cases like 4338305fb1777147cbcb86774c466e88434daff141Jeff Sharkey * {@link TrafficStats#UID_TETHERING} and {@link UserInfo}. 4438305fb1777147cbcb86774c466e88434daff141Jeff Sharkey */ 45b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeypublic class UidDetailProvider { 463aaf0eb457639b52228143b84d9624bf73d862eaZoltan Szatmary-Ban private static final String TAG = "DataUsage"; 47b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey private final Context mContext; 48b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey private final SparseArray<UidDetail> mUidDetailCache; 49b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey 500924f199e530ce844362c79dfa60ddbe3eceac56Zoltan Szatmary-Ban public static final int OTHER_USER_RANGE_START = -2000; 510924f199e530ce844362c79dfa60ddbe3eceac56Zoltan Szatmary-Ban 5238305fb1777147cbcb86774c466e88434daff141Jeff Sharkey public static int buildKeyForUser(int userHandle) { 530924f199e530ce844362c79dfa60ddbe3eceac56Zoltan Szatmary-Ban return OTHER_USER_RANGE_START - userHandle; 540924f199e530ce844362c79dfa60ddbe3eceac56Zoltan Szatmary-Ban } 550924f199e530ce844362c79dfa60ddbe3eceac56Zoltan Szatmary-Ban 560924f199e530ce844362c79dfa60ddbe3eceac56Zoltan Szatmary-Ban public static boolean isKeyForUser(int key) { 570924f199e530ce844362c79dfa60ddbe3eceac56Zoltan Szatmary-Ban return key <= OTHER_USER_RANGE_START; 580924f199e530ce844362c79dfa60ddbe3eceac56Zoltan Szatmary-Ban } 590924f199e530ce844362c79dfa60ddbe3eceac56Zoltan Szatmary-Ban 600924f199e530ce844362c79dfa60ddbe3eceac56Zoltan Szatmary-Ban public static int getUserIdForKey(int key) { 610924f199e530ce844362c79dfa60ddbe3eceac56Zoltan Szatmary-Ban return OTHER_USER_RANGE_START - key; 6238305fb1777147cbcb86774c466e88434daff141Jeff Sharkey } 6338305fb1777147cbcb86774c466e88434daff141Jeff Sharkey 64b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey public UidDetailProvider(Context context) { 65b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey mContext = context.getApplicationContext(); 66b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey mUidDetailCache = new SparseArray<UidDetail>(); 67b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey } 68b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey 69ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey public void clearCache() { 70ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey synchronized (mUidDetailCache) { 71ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey mUidDetailCache.clear(); 72ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey } 73b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey } 74b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey 75b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey /** 76b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey * Resolve best descriptive label for the given UID. 77b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey */ 78ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey public UidDetail getUidDetail(int uid, boolean blocking) { 79ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey UidDetail detail; 80ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey 81ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey synchronized (mUidDetailCache) { 82ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey detail = mUidDetailCache.get(uid); 83ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey } 84ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey 85ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey if (detail != null) { 86ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey return detail; 87b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey } else if (!blocking) { 88b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey return null; 89b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey } 90b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey 91ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey detail = buildUidDetail(uid); 92ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey 93ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey synchronized (mUidDetailCache) { 94ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey mUidDetailCache.put(uid, detail); 95ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey } 96ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey 97ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey return detail; 98ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey } 99ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey 100ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey /** 101ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey * Build {@link UidDetail} object, blocking until all {@link Drawable} 102ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey * lookup is finished. 103ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey */ 104ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey private UidDetail buildUidDetail(int uid) { 105b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey final Resources res = mContext.getResources(); 106b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey final PackageManager pm = mContext.getPackageManager(); 107b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey 108b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey final UidDetail detail = new UidDetail(); 109b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey detail.label = pm.getNameForUid(uid); 110b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey detail.icon = pm.getDefaultActivityIcon(); 111b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey 112b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey // handle special case labels 113b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey switch (uid) { 114b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey case android.os.Process.SYSTEM_UID: 115b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey detail.label = res.getString(R.string.process_kernel_label); 116b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey detail.icon = pm.getDefaultActivityIcon(); 117b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey return detail; 118b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey case TrafficStats.UID_REMOVED: 1196bf72119fd2f53ae363f8dd5dc105790e86a8973Jeff Sharkey detail.label = res.getString(UserManager.supportsMultipleUsers() 1206bf72119fd2f53ae363f8dd5dc105790e86a8973Jeff Sharkey ? R.string.data_usage_uninstalled_apps_users 1216bf72119fd2f53ae363f8dd5dc105790e86a8973Jeff Sharkey : R.string.data_usage_uninstalled_apps); 122b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey detail.icon = pm.getDefaultActivityIcon(); 123b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey return detail; 124a83a24f48a8286ee3d67acc5fdcfb723acc56adaJeff Sharkey case TrafficStats.UID_TETHERING: 125a83a24f48a8286ee3d67acc5fdcfb723acc56adaJeff Sharkey final ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService( 126a83a24f48a8286ee3d67acc5fdcfb723acc56adaJeff Sharkey Context.CONNECTIVITY_SERVICE); 127a83a24f48a8286ee3d67acc5fdcfb723acc56adaJeff Sharkey detail.label = res.getString(Utils.getTetheringLabel(cm)); 128a83a24f48a8286ee3d67acc5fdcfb723acc56adaJeff Sharkey detail.icon = pm.getDefaultActivityIcon(); 129a83a24f48a8286ee3d67acc5fdcfb723acc56adaJeff Sharkey return detail; 130b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey } 131b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey 1320924f199e530ce844362c79dfa60ddbe3eceac56Zoltan Szatmary-Ban final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 1330924f199e530ce844362c79dfa60ddbe3eceac56Zoltan Szatmary-Ban 13438305fb1777147cbcb86774c466e88434daff141Jeff Sharkey // Handle keys that are actually user handles 1350924f199e530ce844362c79dfa60ddbe3eceac56Zoltan Szatmary-Ban if (isKeyForUser(uid)) { 1360924f199e530ce844362c79dfa60ddbe3eceac56Zoltan Szatmary-Ban final int userHandle = getUserIdForKey(uid); 13738305fb1777147cbcb86774c466e88434daff141Jeff Sharkey final UserInfo info = um.getUserInfo(userHandle); 13838305fb1777147cbcb86774c466e88434daff141Jeff Sharkey if (info != null) { 1390924f199e530ce844362c79dfa60ddbe3eceac56Zoltan Szatmary-Ban if (info.isManagedProfile()) { 1406b3b751492d01b23b87a4ee6b807dc00c3b5770eAlexandra Gherghina detail.label = res.getString(R.string.managed_user_title); 1410924f199e530ce844362c79dfa60ddbe3eceac56Zoltan Szatmary-Ban detail.icon = Resources.getSystem().getDrawable( 1429017d3fdd607b8978299578721303b8140a64c22Alexandra Gherghina com.android.internal.R.drawable.ic_corp_icon); 1430924f199e530ce844362c79dfa60ddbe3eceac56Zoltan Szatmary-Ban } else { 1440924f199e530ce844362c79dfa60ddbe3eceac56Zoltan Szatmary-Ban detail.label = res.getString(R.string.running_process_item_user_label, 1450924f199e530ce844362c79dfa60ddbe3eceac56Zoltan Szatmary-Ban info.name); 1460924f199e530ce844362c79dfa60ddbe3eceac56Zoltan Szatmary-Ban detail.icon = Utils.getUserIcon(mContext, um, info); 1470924f199e530ce844362c79dfa60ddbe3eceac56Zoltan Szatmary-Ban } 14838305fb1777147cbcb86774c466e88434daff141Jeff Sharkey return detail; 14938305fb1777147cbcb86774c466e88434daff141Jeff Sharkey } 15038305fb1777147cbcb86774c466e88434daff141Jeff Sharkey } 15138305fb1777147cbcb86774c466e88434daff141Jeff Sharkey 152b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey // otherwise fall back to using packagemanager labels 153b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey final String[] packageNames = pm.getPackagesForUid(uid); 154b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey final int length = packageNames != null ? packageNames.length : 0; 155b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey try { 1563aaf0eb457639b52228143b84d9624bf73d862eaZoltan Szatmary-Ban final int userId = UserHandle.getUserId(uid); 1573aaf0eb457639b52228143b84d9624bf73d862eaZoltan Szatmary-Ban UserHandle userHandle = new UserHandle(userId); 1583aaf0eb457639b52228143b84d9624bf73d862eaZoltan Szatmary-Ban IPackageManager ipm = AppGlobals.getPackageManager(); 159b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey if (length == 1) { 1603aaf0eb457639b52228143b84d9624bf73d862eaZoltan Szatmary-Ban final ApplicationInfo info = ipm.getApplicationInfo(packageNames[0], 1613aaf0eb457639b52228143b84d9624bf73d862eaZoltan Szatmary-Ban 0 /* no flags */, userId); 1623aaf0eb457639b52228143b84d9624bf73d862eaZoltan Szatmary-Ban if (info != null) { 1633aaf0eb457639b52228143b84d9624bf73d862eaZoltan Szatmary-Ban detail.label = info.loadLabel(pm).toString(); 1643aaf0eb457639b52228143b84d9624bf73d862eaZoltan Szatmary-Ban detail.icon = um.getBadgedIconForUser(info.loadIcon(pm), 1653aaf0eb457639b52228143b84d9624bf73d862eaZoltan Szatmary-Ban new UserHandle(userId)); 1663aaf0eb457639b52228143b84d9624bf73d862eaZoltan Szatmary-Ban } 167b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey } else if (length > 1) { 168b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey detail.detailLabels = new CharSequence[length]; 169ebb36ec9207c9519f6ae6a1aa39909279aa1d0e9Zoltan Szatmary-Ban detail.detailContentDescriptions = new CharSequence[length]; 170b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey for (int i = 0; i < length; i++) { 171b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey final String packageName = packageNames[i]; 172b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey final PackageInfo packageInfo = pm.getPackageInfo(packageName, 0); 1733aaf0eb457639b52228143b84d9624bf73d862eaZoltan Szatmary-Ban final ApplicationInfo appInfo = ipm.getApplicationInfo(packageName, 1743aaf0eb457639b52228143b84d9624bf73d862eaZoltan Szatmary-Ban 0 /* no flags */, userId); 1753aaf0eb457639b52228143b84d9624bf73d862eaZoltan Szatmary-Ban 1763aaf0eb457639b52228143b84d9624bf73d862eaZoltan Szatmary-Ban if (appInfo != null) { 1773aaf0eb457639b52228143b84d9624bf73d862eaZoltan Szatmary-Ban detail.detailLabels[i] = appInfo.loadLabel(pm).toString(); 1783aaf0eb457639b52228143b84d9624bf73d862eaZoltan Szatmary-Ban detail.detailContentDescriptions[i] = um.getBadgedLabelForUser( 1793aaf0eb457639b52228143b84d9624bf73d862eaZoltan Szatmary-Ban detail.detailLabels[i], userHandle); 1803aaf0eb457639b52228143b84d9624bf73d862eaZoltan Szatmary-Ban if (packageInfo.sharedUserLabel != 0) { 1813aaf0eb457639b52228143b84d9624bf73d862eaZoltan Szatmary-Ban detail.label = pm.getText(packageName, packageInfo.sharedUserLabel, 1823aaf0eb457639b52228143b84d9624bf73d862eaZoltan Szatmary-Ban packageInfo.applicationInfo).toString(); 1833aaf0eb457639b52228143b84d9624bf73d862eaZoltan Szatmary-Ban detail.icon = um.getBadgedIconForUser(appInfo.loadIcon(pm), userHandle); 1843aaf0eb457639b52228143b84d9624bf73d862eaZoltan Szatmary-Ban } 185b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey } 186b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey } 187b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey } 188ebb36ec9207c9519f6ae6a1aa39909279aa1d0e9Zoltan Szatmary-Ban detail.contentDescription = um.getBadgedLabelForUser(detail.label, userHandle); 189b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey } catch (NameNotFoundException e) { 1903aaf0eb457639b52228143b84d9624bf73d862eaZoltan Szatmary-Ban Log.w(TAG, "Error while building UI detail for uid "+uid, e); 1913aaf0eb457639b52228143b84d9624bf73d862eaZoltan Szatmary-Ban } catch (RemoteException e) { 1923aaf0eb457639b52228143b84d9624bf73d862eaZoltan Szatmary-Ban Log.w(TAG, "Error while building UI detail for uid "+uid, e); 193b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey } 194b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey 195b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey if (TextUtils.isEmpty(detail.label)) { 196b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey detail.label = Integer.toString(uid); 197b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey } 198b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey 199b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey return detail; 200b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey } 201b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey} 202