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 19b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeyimport android.content.Context; 20b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeyimport android.content.pm.ApplicationInfo; 21b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeyimport android.content.pm.PackageInfo; 22b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeyimport android.content.pm.PackageManager; 23b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeyimport android.content.pm.PackageManager.NameNotFoundException; 2438305fb1777147cbcb86774c466e88434daff141Jeff Sharkeyimport android.content.pm.UserInfo; 25b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeyimport android.content.res.Resources; 26ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkeyimport android.graphics.drawable.Drawable; 27a83a24f48a8286ee3d67acc5fdcfb723acc56adaJeff Sharkeyimport android.net.ConnectivityManager; 28b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeyimport android.net.TrafficStats; 2938305fb1777147cbcb86774c466e88434daff141Jeff Sharkeyimport android.os.UserManager; 30b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeyimport android.text.TextUtils; 31b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeyimport android.util.SparseArray; 32b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey 33b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeyimport com.android.settings.R; 34a83a24f48a8286ee3d67acc5fdcfb723acc56adaJeff Sharkeyimport com.android.settings.Utils; 358882ccdd3eafc338213b312f1b73fb4de1776a60Jeff Sharkeyimport com.android.settings.users.UserUtils; 36b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey 3738305fb1777147cbcb86774c466e88434daff141Jeff Sharkey/** 3838305fb1777147cbcb86774c466e88434daff141Jeff Sharkey * Return details about a specific UID, handling special cases like 3938305fb1777147cbcb86774c466e88434daff141Jeff Sharkey * {@link TrafficStats#UID_TETHERING} and {@link UserInfo}. 4038305fb1777147cbcb86774c466e88434daff141Jeff Sharkey */ 41b98c55bd097e006703352f84f0271dec5181160aJeff Sharkeypublic class UidDetailProvider { 42b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey private final Context mContext; 43b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey private final SparseArray<UidDetail> mUidDetailCache; 44b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey 4538305fb1777147cbcb86774c466e88434daff141Jeff Sharkey public static int buildKeyForUser(int userHandle) { 4638305fb1777147cbcb86774c466e88434daff141Jeff Sharkey return -(2000 + userHandle); 4738305fb1777147cbcb86774c466e88434daff141Jeff Sharkey } 4838305fb1777147cbcb86774c466e88434daff141Jeff Sharkey 49b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey public UidDetailProvider(Context context) { 50b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey mContext = context.getApplicationContext(); 51b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey mUidDetailCache = new SparseArray<UidDetail>(); 52b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey } 53b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey 54ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey public void clearCache() { 55ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey synchronized (mUidDetailCache) { 56ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey mUidDetailCache.clear(); 57ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey } 58b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey } 59b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey 60b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey /** 61b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey * Resolve best descriptive label for the given UID. 62b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey */ 63ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey public UidDetail getUidDetail(int uid, boolean blocking) { 64ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey UidDetail detail; 65ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey 66ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey synchronized (mUidDetailCache) { 67ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey detail = mUidDetailCache.get(uid); 68ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey } 69ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey 70ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey if (detail != null) { 71ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey return detail; 72b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey } else if (!blocking) { 73b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey return null; 74b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey } 75b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey 76ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey detail = buildUidDetail(uid); 77ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey 78ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey synchronized (mUidDetailCache) { 79ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey mUidDetailCache.put(uid, detail); 80ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey } 81ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey 82ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey return detail; 83ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey } 84ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey 85ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey /** 86ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey * Build {@link UidDetail} object, blocking until all {@link Drawable} 87ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey * lookup is finished. 88ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey */ 89ae30d12a5f650ec6f2ba0604c908a0f5361334f3Jeff Sharkey private UidDetail buildUidDetail(int uid) { 90b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey final Resources res = mContext.getResources(); 91b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey final PackageManager pm = mContext.getPackageManager(); 92b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey 93b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey final UidDetail detail = new UidDetail(); 94b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey detail.label = pm.getNameForUid(uid); 95b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey detail.icon = pm.getDefaultActivityIcon(); 96b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey 97b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey // handle special case labels 98b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey switch (uid) { 99b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey case android.os.Process.SYSTEM_UID: 100b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey detail.label = res.getString(R.string.process_kernel_label); 101b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey detail.icon = pm.getDefaultActivityIcon(); 102b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey return detail; 103b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey case TrafficStats.UID_REMOVED: 1046bf72119fd2f53ae363f8dd5dc105790e86a8973Jeff Sharkey detail.label = res.getString(UserManager.supportsMultipleUsers() 1056bf72119fd2f53ae363f8dd5dc105790e86a8973Jeff Sharkey ? R.string.data_usage_uninstalled_apps_users 1066bf72119fd2f53ae363f8dd5dc105790e86a8973Jeff Sharkey : R.string.data_usage_uninstalled_apps); 107b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey detail.icon = pm.getDefaultActivityIcon(); 108b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey return detail; 109a83a24f48a8286ee3d67acc5fdcfb723acc56adaJeff Sharkey case TrafficStats.UID_TETHERING: 110a83a24f48a8286ee3d67acc5fdcfb723acc56adaJeff Sharkey final ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService( 111a83a24f48a8286ee3d67acc5fdcfb723acc56adaJeff Sharkey Context.CONNECTIVITY_SERVICE); 112a83a24f48a8286ee3d67acc5fdcfb723acc56adaJeff Sharkey detail.label = res.getString(Utils.getTetheringLabel(cm)); 113a83a24f48a8286ee3d67acc5fdcfb723acc56adaJeff Sharkey detail.icon = pm.getDefaultActivityIcon(); 114a83a24f48a8286ee3d67acc5fdcfb723acc56adaJeff Sharkey return detail; 115b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey } 116b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey 11738305fb1777147cbcb86774c466e88434daff141Jeff Sharkey // Handle keys that are actually user handles 11838305fb1777147cbcb86774c466e88434daff141Jeff Sharkey if (uid <= -2000) { 11938305fb1777147cbcb86774c466e88434daff141Jeff Sharkey final int userHandle = (-uid) - 2000; 12038305fb1777147cbcb86774c466e88434daff141Jeff Sharkey final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 12138305fb1777147cbcb86774c466e88434daff141Jeff Sharkey final UserInfo info = um.getUserInfo(userHandle); 12238305fb1777147cbcb86774c466e88434daff141Jeff Sharkey if (info != null) { 12338305fb1777147cbcb86774c466e88434daff141Jeff Sharkey detail.label = res.getString(R.string.running_process_item_user_label, info.name); 124b0b0b110c04ddbbe5e2651dcb1a6f13551c61fb8Amith Yamasani detail.icon = UserUtils.getUserIcon(mContext, um, info, res); 12538305fb1777147cbcb86774c466e88434daff141Jeff Sharkey return detail; 12638305fb1777147cbcb86774c466e88434daff141Jeff Sharkey } 12738305fb1777147cbcb86774c466e88434daff141Jeff Sharkey } 12838305fb1777147cbcb86774c466e88434daff141Jeff Sharkey 129b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey // otherwise fall back to using packagemanager labels 130b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey final String[] packageNames = pm.getPackagesForUid(uid); 131b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey final int length = packageNames != null ? packageNames.length : 0; 132b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey try { 133b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey if (length == 1) { 134b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey final ApplicationInfo info = pm.getApplicationInfo(packageNames[0], 0); 135b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey detail.label = info.loadLabel(pm).toString(); 136b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey detail.icon = info.loadIcon(pm); 137b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey } else if (length > 1) { 138b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey detail.detailLabels = new CharSequence[length]; 139b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey for (int i = 0; i < length; i++) { 140b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey final String packageName = packageNames[i]; 141b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey final PackageInfo packageInfo = pm.getPackageInfo(packageName, 0); 142b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey final ApplicationInfo appInfo = pm.getApplicationInfo(packageName, 0); 143b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey 144b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey detail.detailLabels[i] = appInfo.loadLabel(pm).toString(); 145b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey if (packageInfo.sharedUserLabel != 0) { 146b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey detail.label = pm.getText(packageName, packageInfo.sharedUserLabel, 147b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey packageInfo.applicationInfo).toString(); 148b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey detail.icon = appInfo.loadIcon(pm); 149b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey } 150b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey } 151b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey } 152b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey } catch (NameNotFoundException e) { 153b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey } 154b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey 155b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey if (TextUtils.isEmpty(detail.label)) { 156b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey detail.label = Integer.toString(uid); 157b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey } 158b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey 159b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey return detail; 160b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey } 161b98c55bd097e006703352f84f0271dec5181160aJeff Sharkey} 162