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.app.AppGlobals; 20 import android.content.Context; 21 import android.content.pm.PackageInfo; 22 import android.content.pm.PackageManager; 23 import android.graphics.drawable.Drawable; 24 import android.os.RemoteException; 25 import android.os.UserHandle; 26 import android.preference.Preference; 27 import android.view.View.OnClickListener; 28 29 import com.android.internal.net.LegacyVpnInfo; 30 import com.android.internal.net.VpnConfig; 31 import com.android.settings.R; 32 33 /** 34 * {@link android.preference.Preference} containing information about a VPN 35 * application. Tracks the package name and connection state. 36 */ 37 public class AppPreference extends ManageablePreference { 38 public static final int STATE_CONNECTED = LegacyVpnInfo.STATE_CONNECTED; 39 public static final int STATE_DISCONNECTED = LegacyVpnInfo.STATE_DISCONNECTED; 40 41 private int mState = STATE_DISCONNECTED; 42 private String mPackageName; 43 private String mName; 44 private int mUid; 45 AppPreference(Context context, OnClickListener onManage, final String packageName, int uid)46 public AppPreference(Context context, OnClickListener onManage, final String packageName, 47 int uid) { 48 super(context, null /* attrs */, onManage); 49 mPackageName = packageName; 50 mUid = uid; 51 update(); 52 } 53 getPackageInfo()54 public PackageInfo getPackageInfo() { 55 UserHandle user = new UserHandle(UserHandle.getUserId(mUid)); 56 try { 57 PackageManager pm = getUserContext().getPackageManager(); 58 return pm.getPackageInfo(mPackageName, 0 /* flags */); 59 } catch (PackageManager.NameNotFoundException nnfe) { 60 return null; 61 } 62 } 63 getLabel()64 public String getLabel() { 65 return mName; 66 } 67 getPackageName()68 public String getPackageName() { 69 return mPackageName; 70 } 71 getUid()72 public int getUid() { 73 return mUid; 74 } 75 getState()76 public int getState() { 77 return mState; 78 } 79 setState(int state)80 public void setState(int state) { 81 mState = state; 82 update(); 83 } 84 update()85 private void update() { 86 final String[] states = getContext().getResources().getStringArray(R.array.vpn_states); 87 setSummary(mState != STATE_DISCONNECTED ? states[mState] : ""); 88 89 mName = mPackageName; 90 Drawable icon = null; 91 92 try { 93 // Make all calls to the package manager as the appropriate user. 94 Context userContext = getUserContext(); 95 PackageManager pm = userContext.getPackageManager(); 96 // Fetch icon and VPN label- the nested catch block is for the case that the app doesn't 97 // exist, in which case we can fall back to the default activity icon for an activity in 98 // that user. 99 try { 100 PackageInfo pkgInfo = pm.getPackageInfo(mPackageName, 0 /* flags */); 101 if (pkgInfo != null) { 102 icon = pkgInfo.applicationInfo.loadIcon(pm); 103 mName = VpnConfig.getVpnLabel(userContext, mPackageName).toString(); 104 } 105 } catch (PackageManager.NameNotFoundException pkgNotFound) { 106 // Use default app label and icon as fallback 107 } 108 if (icon == null) { 109 icon = pm.getDefaultActivityIcon(); 110 } 111 } catch (PackageManager.NameNotFoundException userNotFound) { 112 // No user, no useful information to obtain. Quietly fail. 113 } 114 setTitle(mName); 115 setIcon(icon); 116 117 notifyHierarchyChanged(); 118 } 119 getUserContext()120 private Context getUserContext() throws PackageManager.NameNotFoundException { 121 UserHandle user = new UserHandle(UserHandle.getUserId(mUid)); 122 return getContext().createPackageContextAsUser( 123 getContext().getPackageName(), 0 /* flags */, user); 124 } 125 compareTo(Preference preference)126 public int compareTo(Preference preference) { 127 if (preference instanceof AppPreference) { 128 AppPreference another = (AppPreference) preference; 129 int result; 130 if ((result = another.mState - mState) == 0 && 131 (result = mName.compareToIgnoreCase(another.mName)) == 0 && 132 (result = mPackageName.compareTo(another.mPackageName)) == 0) { 133 result = mUid - another.mUid; 134 } 135 return result; 136 } else if (preference instanceof ConfigPreference) { 137 // Use comparator from ConfigPreference 138 ConfigPreference another = (ConfigPreference) preference; 139 return -another.compareTo(this); 140 } else { 141 return super.compareTo(preference); 142 } 143 } 144 } 145 146