Home | History | Annotate | Download | only in net
      1 /*
      2  * Copyright (C) 2011 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  */
     16 
     17 package com.android.settings.net;
     18 
     19 import android.content.Context;
     20 import android.content.pm.ApplicationInfo;
     21 import android.content.pm.PackageInfo;
     22 import android.content.pm.PackageManager;
     23 import android.content.pm.PackageManager.NameNotFoundException;
     24 import android.content.pm.UserInfo;
     25 import android.content.res.Resources;
     26 import android.graphics.drawable.Drawable;
     27 import android.net.ConnectivityManager;
     28 import android.net.TrafficStats;
     29 import android.os.UserManager;
     30 import android.text.TextUtils;
     31 import android.util.SparseArray;
     32 
     33 import com.android.settings.R;
     34 import com.android.settings.Utils;
     35 import com.android.settings.users.UserUtils;
     36 
     37 /**
     38  * Return details about a specific UID, handling special cases like
     39  * {@link TrafficStats#UID_TETHERING} and {@link UserInfo}.
     40  */
     41 public class UidDetailProvider {
     42     private final Context mContext;
     43     private final SparseArray<UidDetail> mUidDetailCache;
     44 
     45     public static int buildKeyForUser(int userHandle) {
     46         return -(2000 + userHandle);
     47     }
     48 
     49     public UidDetailProvider(Context context) {
     50         mContext = context.getApplicationContext();
     51         mUidDetailCache = new SparseArray<UidDetail>();
     52     }
     53 
     54     public void clearCache() {
     55         synchronized (mUidDetailCache) {
     56             mUidDetailCache.clear();
     57         }
     58     }
     59 
     60     /**
     61      * Resolve best descriptive label for the given UID.
     62      */
     63     public UidDetail getUidDetail(int uid, boolean blocking) {
     64         UidDetail detail;
     65 
     66         synchronized (mUidDetailCache) {
     67             detail = mUidDetailCache.get(uid);
     68         }
     69 
     70         if (detail != null) {
     71             return detail;
     72         } else if (!blocking) {
     73             return null;
     74         }
     75 
     76         detail = buildUidDetail(uid);
     77 
     78         synchronized (mUidDetailCache) {
     79             mUidDetailCache.put(uid, detail);
     80         }
     81 
     82         return detail;
     83     }
     84 
     85     /**
     86      * Build {@link UidDetail} object, blocking until all {@link Drawable}
     87      * lookup is finished.
     88      */
     89     private UidDetail buildUidDetail(int uid) {
     90         final Resources res = mContext.getResources();
     91         final PackageManager pm = mContext.getPackageManager();
     92 
     93         final UidDetail detail = new UidDetail();
     94         detail.label = pm.getNameForUid(uid);
     95         detail.icon = pm.getDefaultActivityIcon();
     96 
     97         // handle special case labels
     98         switch (uid) {
     99             case android.os.Process.SYSTEM_UID:
    100                 detail.label = res.getString(R.string.process_kernel_label);
    101                 detail.icon = pm.getDefaultActivityIcon();
    102                 return detail;
    103             case TrafficStats.UID_REMOVED:
    104                 detail.label = res.getString(UserManager.supportsMultipleUsers()
    105                         ? R.string.data_usage_uninstalled_apps_users
    106                         : R.string.data_usage_uninstalled_apps);
    107                 detail.icon = pm.getDefaultActivityIcon();
    108                 return detail;
    109             case TrafficStats.UID_TETHERING:
    110                 final ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(
    111                         Context.CONNECTIVITY_SERVICE);
    112                 detail.label = res.getString(Utils.getTetheringLabel(cm));
    113                 detail.icon = pm.getDefaultActivityIcon();
    114                 return detail;
    115         }
    116 
    117         // Handle keys that are actually user handles
    118         if (uid <= -2000) {
    119             final int userHandle = (-uid) - 2000;
    120             final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
    121             final UserInfo info = um.getUserInfo(userHandle);
    122             if (info != null) {
    123                 detail.label = res.getString(R.string.running_process_item_user_label, info.name);
    124                 detail.icon = UserUtils.getUserIcon(mContext, um, info, res);
    125                 return detail;
    126             }
    127         }
    128 
    129         // otherwise fall back to using packagemanager labels
    130         final String[] packageNames = pm.getPackagesForUid(uid);
    131         final int length = packageNames != null ? packageNames.length : 0;
    132         try {
    133             if (length == 1) {
    134                 final ApplicationInfo info = pm.getApplicationInfo(packageNames[0], 0);
    135                 detail.label = info.loadLabel(pm).toString();
    136                 detail.icon = info.loadIcon(pm);
    137             } else if (length > 1) {
    138                 detail.detailLabels = new CharSequence[length];
    139                 for (int i = 0; i < length; i++) {
    140                     final String packageName = packageNames[i];
    141                     final PackageInfo packageInfo = pm.getPackageInfo(packageName, 0);
    142                     final ApplicationInfo appInfo = pm.getApplicationInfo(packageName, 0);
    143 
    144                     detail.detailLabels[i] = appInfo.loadLabel(pm).toString();
    145                     if (packageInfo.sharedUserLabel != 0) {
    146                         detail.label = pm.getText(packageName, packageInfo.sharedUserLabel,
    147                                 packageInfo.applicationInfo).toString();
    148                         detail.icon = appInfo.loadIcon(pm);
    149                     }
    150                 }
    151             }
    152         } catch (NameNotFoundException e) {
    153         }
    154 
    155         if (TextUtils.isEmpty(detail.label)) {
    156             detail.label = Integer.toString(uid);
    157         }
    158 
    159         return detail;
    160     }
    161 }
    162