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