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.res.Resources;
     25 import android.graphics.drawable.Drawable;
     26 import android.net.ConnectivityManager;
     27 import android.net.TrafficStats;
     28 import android.text.TextUtils;
     29 import android.util.SparseArray;
     30 
     31 import com.android.settings.R;
     32 import com.android.settings.Utils;
     33 
     34 public class UidDetailProvider {
     35     private final Context mContext;
     36     private final SparseArray<UidDetail> mUidDetailCache;
     37 
     38     public UidDetailProvider(Context context) {
     39         mContext = context.getApplicationContext();
     40         mUidDetailCache = new SparseArray<UidDetail>();
     41     }
     42 
     43     public void clearCache() {
     44         synchronized (mUidDetailCache) {
     45             mUidDetailCache.clear();
     46         }
     47     }
     48 
     49     /**
     50      * Resolve best descriptive label for the given UID.
     51      */
     52     public UidDetail getUidDetail(int uid, boolean blocking) {
     53         UidDetail detail;
     54 
     55         synchronized (mUidDetailCache) {
     56             detail = mUidDetailCache.get(uid);
     57         }
     58 
     59         if (detail != null) {
     60             return detail;
     61         } else if (!blocking) {
     62             return null;
     63         }
     64 
     65         detail = buildUidDetail(uid);
     66 
     67         synchronized (mUidDetailCache) {
     68             mUidDetailCache.put(uid, detail);
     69         }
     70 
     71         return detail;
     72     }
     73 
     74     /**
     75      * Build {@link UidDetail} object, blocking until all {@link Drawable}
     76      * lookup is finished.
     77      */
     78     private UidDetail buildUidDetail(int uid) {
     79         final Resources res = mContext.getResources();
     80         final PackageManager pm = mContext.getPackageManager();
     81 
     82         final UidDetail detail = new UidDetail();
     83         detail.label = pm.getNameForUid(uid);
     84         detail.icon = pm.getDefaultActivityIcon();
     85 
     86         // handle special case labels
     87         switch (uid) {
     88             case android.os.Process.SYSTEM_UID:
     89                 detail.label = res.getString(R.string.process_kernel_label);
     90                 detail.icon = pm.getDefaultActivityIcon();
     91                 return detail;
     92             case TrafficStats.UID_REMOVED:
     93                 detail.label = res.getString(R.string.data_usage_uninstalled_apps);
     94                 detail.icon = pm.getDefaultActivityIcon();
     95                 return detail;
     96             case TrafficStats.UID_TETHERING:
     97                 final ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(
     98                         Context.CONNECTIVITY_SERVICE);
     99                 detail.label = res.getString(Utils.getTetheringLabel(cm));
    100                 detail.icon = pm.getDefaultActivityIcon();
    101                 return detail;
    102         }
    103 
    104         // otherwise fall back to using packagemanager labels
    105         final String[] packageNames = pm.getPackagesForUid(uid);
    106         final int length = packageNames != null ? packageNames.length : 0;
    107 
    108         try {
    109             if (length == 1) {
    110                 final ApplicationInfo info = pm.getApplicationInfo(packageNames[0], 0);
    111                 detail.label = info.loadLabel(pm).toString();
    112                 detail.icon = info.loadIcon(pm);
    113             } else if (length > 1) {
    114                 detail.detailLabels = new CharSequence[length];
    115                 for (int i = 0; i < length; i++) {
    116                     final String packageName = packageNames[i];
    117                     final PackageInfo packageInfo = pm.getPackageInfo(packageName, 0);
    118                     final ApplicationInfo appInfo = pm.getApplicationInfo(packageName, 0);
    119 
    120                     detail.detailLabels[i] = appInfo.loadLabel(pm).toString();
    121                     if (packageInfo.sharedUserLabel != 0) {
    122                         detail.label = pm.getText(packageName, packageInfo.sharedUserLabel,
    123                                 packageInfo.applicationInfo).toString();
    124                         detail.icon = appInfo.loadIcon(pm);
    125                     }
    126                 }
    127             }
    128         } catch (NameNotFoundException e) {
    129         }
    130 
    131         if (TextUtils.isEmpty(detail.label)) {
    132             detail.label = Integer.toString(uid);
    133         }
    134 
    135         return detail;
    136     }
    137 }
    138