130275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu/* 230275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu * Copyright (C) 2011 The Android Open Source Project 330275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu * 430275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu * Licensed under the Apache License, Version 2.0 (the "License"); 530275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu * you may not use this file except in compliance with the License. 630275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu * You may obtain a copy of the License at 730275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu * 830275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu * http://www.apache.org/licenses/LICENSE-2.0 930275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu * 1030275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu * Unless required by applicable law or agreed to in writing, software 1130275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu * distributed under the License is distributed on an "AS IS" BASIS, 1230275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1330275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu * See the License for the specific language governing permissions and 1430275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu * limitations under the License. 1530275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu */ 1630275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu 1730275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liupackage com.android.settingslib.net; 1830275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu 1930275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liuimport android.app.AppGlobals; 2030275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liuimport android.content.Context; 2130275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liuimport android.content.pm.ApplicationInfo; 2230275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liuimport android.content.pm.IPackageManager; 2330275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liuimport android.content.pm.PackageInfo; 2430275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liuimport android.content.pm.PackageManager; 2530275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liuimport android.content.pm.PackageManager.NameNotFoundException; 2630275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liuimport android.content.pm.UserInfo; 2730275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liuimport android.content.res.Resources; 2830275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liuimport android.graphics.drawable.Drawable; 2930275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liuimport android.net.ConnectivityManager; 3030275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liuimport android.net.TrafficStats; 3130275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liuimport android.os.UserManager; 3230275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liuimport android.os.UserHandle; 3330275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liuimport android.os.RemoteException; 3430275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liuimport android.text.TextUtils; 3530275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liuimport android.util.Log; 3630275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liuimport android.util.SparseArray; 3730275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu 3830275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liuimport com.android.settingslib.R; 3930275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liuimport com.android.settingslib.Utils; 4030275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu 4130275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu/** 4230275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu * Return details about a specific UID, handling special cases like 4330275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu * {@link TrafficStats#UID_TETHERING} and {@link UserInfo}. 4430275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu */ 4530275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liupublic class UidDetailProvider { 4630275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu private static final String TAG = "DataUsage"; 4730275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu private final Context mContext; 4830275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu private final SparseArray<UidDetail> mUidDetailCache; 4930275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu 5030275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu public static final int OTHER_USER_RANGE_START = -2000; 5130275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu 5230275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu public static int buildKeyForUser(int userHandle) { 5330275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu return OTHER_USER_RANGE_START - userHandle; 5430275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu } 5530275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu 5630275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu public static boolean isKeyForUser(int key) { 5730275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu return key <= OTHER_USER_RANGE_START; 5830275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu } 5930275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu 6030275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu public static int getUserIdForKey(int key) { 6130275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu return OTHER_USER_RANGE_START - key; 6230275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu } 6330275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu 6430275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu public UidDetailProvider(Context context) { 6530275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu mContext = context.getApplicationContext(); 6630275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu mUidDetailCache = new SparseArray<UidDetail>(); 6730275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu } 6830275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu 6930275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu public void clearCache() { 7030275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu synchronized (mUidDetailCache) { 7130275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu mUidDetailCache.clear(); 7230275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu } 7330275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu } 7430275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu 7530275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu /** 7630275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu * Resolve best descriptive label for the given UID. 7730275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu */ 7830275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu public UidDetail getUidDetail(int uid, boolean blocking) { 7930275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu UidDetail detail; 8030275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu 8130275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu synchronized (mUidDetailCache) { 8230275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu detail = mUidDetailCache.get(uid); 8330275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu } 8430275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu 8530275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu if (detail != null) { 8630275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu return detail; 8730275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu } else if (!blocking) { 8830275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu return null; 8930275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu } 9030275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu 9130275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu detail = buildUidDetail(uid); 9230275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu 9330275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu synchronized (mUidDetailCache) { 9430275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu mUidDetailCache.put(uid, detail); 9530275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu } 9630275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu 9730275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu return detail; 9830275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu } 9930275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu 10030275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu /** 10130275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu * Build {@link UidDetail} object, blocking until all {@link Drawable} 10230275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu * lookup is finished. 10330275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu */ 10430275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu private UidDetail buildUidDetail(int uid) { 10530275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu final Resources res = mContext.getResources(); 10630275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu final PackageManager pm = mContext.getPackageManager(); 10730275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu 10830275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu final UidDetail detail = new UidDetail(); 10930275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu detail.label = pm.getNameForUid(uid); 11030275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu detail.icon = pm.getDefaultActivityIcon(); 11130275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu 11230275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu // handle special case labels 11330275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu switch (uid) { 11430275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu case android.os.Process.SYSTEM_UID: 11530275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu detail.label = res.getString(R.string.process_kernel_label); 11630275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu detail.icon = pm.getDefaultActivityIcon(); 11730275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu return detail; 11830275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu case TrafficStats.UID_REMOVED: 11930275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu detail.label = res.getString(UserManager.supportsMultipleUsers() 12030275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu ? R.string.data_usage_uninstalled_apps_users 12130275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu : R.string.data_usage_uninstalled_apps); 12230275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu detail.icon = pm.getDefaultActivityIcon(); 12330275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu return detail; 12430275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu case TrafficStats.UID_TETHERING: 12530275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu final ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService( 12630275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu Context.CONNECTIVITY_SERVICE); 12730275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu detail.label = res.getString(Utils.getTetheringLabel(cm)); 12830275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu detail.icon = pm.getDefaultActivityIcon(); 12930275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu return detail; 13030275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu } 13130275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu 13230275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 13330275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu 13430275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu // Handle keys that are actually user handles 13530275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu if (isKeyForUser(uid)) { 13630275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu final int userHandle = getUserIdForKey(uid); 13730275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu final UserInfo info = um.getUserInfo(userHandle); 13830275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu if (info != null) { 13930275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu detail.label = Utils.getUserLabel(mContext, info); 14030275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu detail.icon = Utils.getUserIcon(mContext, um, info); 14130275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu return detail; 14230275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu } 14330275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu } 14430275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu 14530275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu // otherwise fall back to using packagemanager labels 14630275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu final String[] packageNames = pm.getPackagesForUid(uid); 14730275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu final int length = packageNames != null ? packageNames.length : 0; 14830275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu try { 14930275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu final int userId = UserHandle.getUserId(uid); 15030275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu UserHandle userHandle = new UserHandle(userId); 15130275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu IPackageManager ipm = AppGlobals.getPackageManager(); 15230275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu if (length == 1) { 15330275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu final ApplicationInfo info = ipm.getApplicationInfo(packageNames[0], 15430275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu 0 /* no flags */, userId); 15530275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu if (info != null) { 15630275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu detail.label = info.loadLabel(pm).toString(); 15730275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu detail.icon = um.getBadgedIconForUser(info.loadIcon(pm), 15830275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu new UserHandle(userId)); 15930275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu } 16030275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu } else if (length > 1) { 16130275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu detail.detailLabels = new CharSequence[length]; 16230275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu detail.detailContentDescriptions = new CharSequence[length]; 16330275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu for (int i = 0; i < length; i++) { 16430275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu final String packageName = packageNames[i]; 16530275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu final PackageInfo packageInfo = pm.getPackageInfo(packageName, 0); 16630275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu final ApplicationInfo appInfo = ipm.getApplicationInfo(packageName, 16730275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu 0 /* no flags */, userId); 16830275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu 16930275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu if (appInfo != null) { 17030275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu detail.detailLabels[i] = appInfo.loadLabel(pm).toString(); 17130275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu detail.detailContentDescriptions[i] = um.getBadgedLabelForUser( 17230275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu detail.detailLabels[i], userHandle); 17330275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu if (packageInfo.sharedUserLabel != 0) { 17430275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu detail.label = pm.getText(packageName, packageInfo.sharedUserLabel, 17530275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu packageInfo.applicationInfo).toString(); 17630275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu detail.icon = um.getBadgedIconForUser(appInfo.loadIcon(pm), userHandle); 17730275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu } 17830275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu } 17930275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu } 18030275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu } 18130275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu detail.contentDescription = um.getBadgedLabelForUser(detail.label, userHandle); 18230275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu } catch (NameNotFoundException e) { 18330275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu Log.w(TAG, "Error while building UI detail for uid "+uid, e); 18430275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu } catch (RemoteException e) { 18530275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu Log.w(TAG, "Error while building UI detail for uid "+uid, e); 18630275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu } 18730275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu 18830275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu if (TextUtils.isEmpty(detail.label)) { 18930275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu detail.label = Integer.toString(uid); 19030275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu } 19130275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu 19230275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu return detail; 19330275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu } 19430275c1924b2bd45b05bd9c98f8648ecbc71374fWei Liu} 195