1 /*
2  * Copyright (C) 2015 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.vpn2;
18 
19 import android.content.Context;
20 import android.content.pm.PackageInfo;
21 import android.content.pm.PackageManager;
22 import android.graphics.drawable.Drawable;
23 import android.os.UserHandle;
24 import android.support.v7.preference.Preference;
25 
26 import com.android.internal.net.LegacyVpnInfo;
27 import com.android.internal.net.VpnConfig;
28 
29 /**
30  * {@link android.support.v7.preference.Preference} containing information about a VPN
31  * application. Tracks the package name and connection state.
32  */
33 public class AppPreference extends ManageablePreference {
34     public static final int STATE_CONNECTED = LegacyVpnInfo.STATE_CONNECTED;
35     public static final int STATE_DISCONNECTED = STATE_NONE;
36 
37     private final String mPackageName;
38     private final String mName;
39 
AppPreference(Context context, int userId, String packageName)40     public AppPreference(Context context, int userId, String packageName) {
41         super(context, null /* attrs */);
42         super.setUserId(userId);
43 
44         mPackageName = packageName;
45 
46         // Fetch icon and VPN label
47         String label = packageName;
48         Drawable icon = null;
49         try {
50             // Make all calls to the package manager as the appropriate user.
51             Context userContext = getUserContext();
52             PackageManager pm = userContext.getPackageManager();
53             // The nested catch block is for the case that the app doesn't exist, so we can fall
54             // back to the default activity icon.
55             try {
56                 PackageInfo pkgInfo = pm.getPackageInfo(mPackageName, 0 /* flags */);
57                 if (pkgInfo != null) {
58                     icon = pkgInfo.applicationInfo.loadIcon(pm);
59                     label = VpnConfig.getVpnLabel(userContext, mPackageName).toString();
60                 }
61             } catch (PackageManager.NameNotFoundException pkgNotFound) {
62                 // Use default app label and icon as fallback
63             }
64             if (icon == null) {
65                 icon = pm.getDefaultActivityIcon();
66             }
67         } catch (PackageManager.NameNotFoundException userNotFound) {
68             // No user, no useful information to obtain. Quietly fail.
69         }
70         mName = label;
71 
72         setTitle(mName);
73         setIcon(icon);
74     }
75 
getPackageInfo()76     public PackageInfo getPackageInfo() {
77         try {
78             PackageManager pm = getUserContext().getPackageManager();
79             return pm.getPackageInfo(mPackageName, 0 /* flags */);
80         } catch (PackageManager.NameNotFoundException nnfe) {
81             return null;
82         }
83     }
84 
getLabel()85     public String getLabel() {
86         return mName;
87     }
88 
getPackageName()89     public String getPackageName() {
90         return mPackageName;
91     }
92 
getUserContext()93     private Context getUserContext() throws PackageManager.NameNotFoundException {
94         UserHandle user = UserHandle.of(mUserId);
95         return getContext().createPackageContextAsUser(
96                 getContext().getPackageName(), 0 /* flags */, user);
97     }
98 
compareTo(Preference preference)99     public int compareTo(Preference preference) {
100         if (preference instanceof AppPreference) {
101             AppPreference another = (AppPreference) preference;
102             int result;
103             if ((result = another.mState - mState) == 0 &&
104                     (result = mName.compareToIgnoreCase(another.mName)) == 0 &&
105                     (result = mPackageName.compareTo(another.mPackageName)) == 0) {
106                 result = mUserId - another.mUserId;
107             }
108             return result;
109         } else if (preference instanceof LegacyVpnPreference) {
110             // Use comparator from ConfigPreference
111             LegacyVpnPreference another = (LegacyVpnPreference) preference;
112             return -another.compareTo(this);
113         } else {
114             return super.compareTo(preference);
115         }
116     }
117 }
118 
119