Loading src/com/android/settings/vpn2/AppPreference.java +28 −55 Original line number Diff line number Diff line Loading @@ -32,75 +32,31 @@ import com.android.internal.net.VpnConfig; */ public class AppPreference extends ManageablePreference { public static final int STATE_CONNECTED = LegacyVpnInfo.STATE_CONNECTED; public static final int STATE_DISCONNECTED = LegacyVpnInfo.STATE_DISCONNECTED; public static final int STATE_DISCONNECTED = STATE_NONE; private int mState = STATE_DISCONNECTED; private String mPackageName; private String mName; private final String mPackageName; private final String mName; public AppPreference(Context context) { public AppPreference(Context context, int userId, String packageName) { super(context, null /* attrs */); } @Override public void setUserId(int userId) { super.setUserId(userId); update(); } public PackageInfo getPackageInfo() { try { PackageManager pm = getUserContext().getPackageManager(); return pm.getPackageInfo(mPackageName, 0 /* flags */); } catch (PackageManager.NameNotFoundException nnfe) { return null; } } public String getLabel() { return mName; } public String getPackageName() { return mPackageName; } public void setPackageName(String name) { mPackageName = name; update(); } public int getState() { return mState; } public void setState(int state) { mState = state; update(); } private void update() { if (mPackageName == null || mUserId == UserHandle.USER_NULL) { return; } setSummary(getSummaryString(mState == STATE_DISCONNECTED ? STATE_NONE : mState)); mPackageName = packageName; mName = mPackageName; // Fetch icon and VPN label String label = packageName; Drawable icon = null; try { // Make all calls to the package manager as the appropriate user. Context userContext = getUserContext(); PackageManager pm = userContext.getPackageManager(); // Fetch icon and VPN label- the nested catch block is for the case that the app doesn't // exist, in which case we can fall back to the default activity icon for an activity in // that user. // The nested catch block is for the case that the app doesn't exist, so we can fall // back to the default activity icon. try { PackageInfo pkgInfo = pm.getPackageInfo(mPackageName, 0 /* flags */); if (pkgInfo != null) { icon = pkgInfo.applicationInfo.loadIcon(pm); mName = VpnConfig.getVpnLabel(userContext, mPackageName).toString(); label = VpnConfig.getVpnLabel(userContext, mPackageName).toString(); } } catch (PackageManager.NameNotFoundException pkgNotFound) { // Use default app label and icon as fallback Loading @@ -111,10 +67,27 @@ public class AppPreference extends ManageablePreference { } catch (PackageManager.NameNotFoundException userNotFound) { // No user, no useful information to obtain. Quietly fail. } mName = label; setTitle(mName); setIcon(icon); } notifyHierarchyChanged(); public PackageInfo getPackageInfo() { try { PackageManager pm = getUserContext().getPackageManager(); return pm.getPackageInfo(mPackageName, 0 /* flags */); } catch (PackageManager.NameNotFoundException nnfe) { return null; } } public String getLabel() { return mName; } public String getPackageName() { return mPackageName; } private Context getUserContext() throws PackageManager.NameNotFoundException { Loading src/com/android/settings/vpn2/LegacyVpnPreference.java +9 −20 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.settings.vpn2; import android.content.Context; import android.support.v7.preference.Preference; import android.text.TextUtils; import android.view.View; import com.android.internal.net.VpnProfile; Loading @@ -31,11 +32,9 @@ import static com.android.internal.net.LegacyVpnInfo.STATE_CONNECTED; public class LegacyVpnPreference extends ManageablePreference { private VpnProfile mProfile; /** One of the STATE_* fields from LegacyVpnInfo, or STATE_NONE */ private int mState = STATE_NONE; LegacyVpnPreference(Context context) { super(context, null /* attrs */); setIcon(R.mipmap.ic_launcher_settings); } public VpnProfile getProfile() { Loading @@ -43,23 +42,14 @@ public class LegacyVpnPreference extends ManageablePreference { } public void setProfile(VpnProfile profile) { mProfile = profile; update(); } public void setState(int state) { mState = state; update(); } private void update() { setSummary(getSummaryString(mState)); if (mProfile != null) { setIcon(R.mipmap.ic_launcher_settings); setTitle(mProfile.name); } final String oldLabel = (mProfile != null ? mProfile.name : null); final String newLabel = (profile != null ? profile.name : null); if (!TextUtils.equals(oldLabel, newLabel)) { setTitle(newLabel); notifyHierarchyChanged(); } mProfile = profile; } @Override public int compareTo(Preference preference) { Loading Loading @@ -93,5 +83,4 @@ public class LegacyVpnPreference extends ManageablePreference { } super.onClick(v); } } src/com/android/settings/vpn2/ManageablePreference.java +23 −6 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ public abstract class ManageablePreference extends GearPreference { public static int STATE_NONE = -1; boolean mIsAlwaysOn = false; int mState = STATE_NONE; int mUserId; public ManageablePreference(Context context, AttributeSet attrs) { Loading @@ -56,24 +57,40 @@ public abstract class ManageablePreference extends GearPreference { return mIsAlwaysOn; } public int getState() { return mState; } public void setState(int state) { if (mState != state) { mState = state; updateSummary(); notifyHierarchyChanged(); } } public void setAlwaysOn(boolean isEnabled) { if (mIsAlwaysOn != isEnabled) { mIsAlwaysOn = isEnabled; updateSummary(); } } /** * State is not shown for {@code STATE_NONE} * Update the preference summary string (see {@see Preference#setSummary}) with a string * reflecting connection status and always-on setting. * * @return summary string showing current connection state and always-on-vpn state * State is not shown for {@code STATE_NONE}. */ protected String getSummaryString(int state) { protected void updateSummary() { final Resources res = getContext().getResources(); final String[] states = res.getStringArray(R.array.vpn_states); String summary = state == STATE_NONE ? "" : states[state]; String summary = (mState == STATE_NONE ? "" : states[mState]); if (mIsAlwaysOn) { final String alwaysOnString = res.getString(R.string.vpn_always_on_active); summary = TextUtils.isEmpty(summary) ? alwaysOnString : res.getString( R.string.join_two_unrelated_items, summary, alwaysOnString); } return summary; setSummary(summary); } } src/com/android/settings/vpn2/VpnSettings.java +20 −28 Original line number Diff line number Diff line Loading @@ -34,7 +34,6 @@ import android.os.Handler; import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; import android.os.UserHandle; import android.os.UserManager; import android.security.Credentials; Loading Loading @@ -211,8 +210,8 @@ public class VpnSettings extends RestrictedSettingsFragment implements final List<VpnProfile> vpnProfiles = loadVpnProfiles(mKeyStore); final List<AppVpnInfo> vpnApps = getVpnApps(getActivity(), /* includeProfiles */ true); final List<LegacyVpnInfo> connectedLegacyVpns = getConnectedLegacyVpns(); final List<AppVpnInfo> connectedAppVpns = getConnectedAppVpns(); final Map<String, LegacyVpnInfo> connectedLegacyVpns = getConnectedLegacyVpns(); final Set<AppVpnInfo> connectedAppVpns = getConnectedAppVpns(); final Set<AppVpnInfo> alwaysOnAppVpnInfos = getAlwaysOnAppVpnInfos(); final String lockdownVpnKey = VpnUtils.getLockdownVpn(); Loading @@ -231,18 +230,26 @@ public class VpnSettings extends RestrictedSettingsFragment implements for (VpnProfile profile : vpnProfiles) { LegacyVpnPreference p = findOrCreatePreference(profile); if (connectedLegacyVpns.containsKey(profile.key)) { p.setState(connectedLegacyVpns.get(profile.key).state); } else { p.setState(LegacyVpnPreference.STATE_NONE); } p.setAlwaysOn(lockdownVpnKey != null && lockdownVpnKey.equals(profile.key)); updates.add(p); } for (AppVpnInfo app : vpnApps) { AppPreference p = findOrCreatePreference(app); if (connectedAppVpns.contains(app)) { p.setState(AppPreference.STATE_CONNECTED); } else { p.setState(AppPreference.STATE_DISCONNECTED); } p.setAlwaysOn(alwaysOnAppVpnInfos.contains(app)); updates.add(p); } // Trim preferences for deleted VPNs // Trim out deleted VPN preferences mLegacyVpnPreferences.values().retainAll(updates); mAppPreferences.values().retainAll(updates); Loading @@ -260,20 +267,6 @@ public class VpnSettings extends RestrictedSettingsFragment implements for (Preference pref : updates) { vpnGroup.addPreference(pref); } // Mark connected VPNs for (LegacyVpnInfo info : connectedLegacyVpns) { final LegacyVpnPreference preference = mLegacyVpnPreferences.get(info.key); if (preference != null) { preference.setState(info.state); } } for (AppVpnInfo app : connectedAppVpns) { final AppPreference preference = mAppPreferences.get(app); if (preference != null) { preference.setState(AppPreference.STATE_CONNECTED); } } } }); Loading Loading @@ -369,6 +362,7 @@ public class VpnSettings extends RestrictedSettingsFragment implements pref.setOnPreferenceClickListener(this); mLegacyVpnPreferences.put(profile.key, pref); } // This may change as the profile can update and keep the same key. pref.setProfile(profile); return pref; } Loading @@ -377,33 +371,31 @@ public class VpnSettings extends RestrictedSettingsFragment implements private AppPreference findOrCreatePreference(AppVpnInfo app) { AppPreference pref = mAppPreferences.get(app); if (pref == null) { pref = new AppPreference(getPrefContext()); pref = new AppPreference(getPrefContext(), app.userId, app.packageName); pref.setOnGearClickListener(mGearListener); pref.setOnPreferenceClickListener(this); mAppPreferences.put(app, pref); } pref.setUserId(app.userId); pref.setPackageName(app.packageName); return pref; } @WorkerThread private List<LegacyVpnInfo> getConnectedLegacyVpns() { private Map<String, LegacyVpnInfo> getConnectedLegacyVpns() { try { mConnectedLegacyVpn = mConnectivityService.getLegacyVpnInfo(UserHandle.myUserId()); if (mConnectedLegacyVpn != null) { return Collections.singletonList(mConnectedLegacyVpn); return Collections.singletonMap(mConnectedLegacyVpn.key, mConnectedLegacyVpn); } } catch (RemoteException e) { Log.e(LOG_TAG, "Failure updating VPN list with connected legacy VPNs", e); } return Collections.emptyList(); return Collections.emptyMap(); } @WorkerThread private List<AppVpnInfo> getConnectedAppVpns() { private Set<AppVpnInfo> getConnectedAppVpns() { // Mark connected third-party services List<AppVpnInfo> connections = new ArrayList<>(); Set<AppVpnInfo> connections = new ArraySet<>(); try { for (UserHandle profile : mUserManager.getUserProfiles()) { VpnConfig config = mConnectivityService.getVpnConfig(profile.getIdentifier()); Loading Loading
src/com/android/settings/vpn2/AppPreference.java +28 −55 Original line number Diff line number Diff line Loading @@ -32,75 +32,31 @@ import com.android.internal.net.VpnConfig; */ public class AppPreference extends ManageablePreference { public static final int STATE_CONNECTED = LegacyVpnInfo.STATE_CONNECTED; public static final int STATE_DISCONNECTED = LegacyVpnInfo.STATE_DISCONNECTED; public static final int STATE_DISCONNECTED = STATE_NONE; private int mState = STATE_DISCONNECTED; private String mPackageName; private String mName; private final String mPackageName; private final String mName; public AppPreference(Context context) { public AppPreference(Context context, int userId, String packageName) { super(context, null /* attrs */); } @Override public void setUserId(int userId) { super.setUserId(userId); update(); } public PackageInfo getPackageInfo() { try { PackageManager pm = getUserContext().getPackageManager(); return pm.getPackageInfo(mPackageName, 0 /* flags */); } catch (PackageManager.NameNotFoundException nnfe) { return null; } } public String getLabel() { return mName; } public String getPackageName() { return mPackageName; } public void setPackageName(String name) { mPackageName = name; update(); } public int getState() { return mState; } public void setState(int state) { mState = state; update(); } private void update() { if (mPackageName == null || mUserId == UserHandle.USER_NULL) { return; } setSummary(getSummaryString(mState == STATE_DISCONNECTED ? STATE_NONE : mState)); mPackageName = packageName; mName = mPackageName; // Fetch icon and VPN label String label = packageName; Drawable icon = null; try { // Make all calls to the package manager as the appropriate user. Context userContext = getUserContext(); PackageManager pm = userContext.getPackageManager(); // Fetch icon and VPN label- the nested catch block is for the case that the app doesn't // exist, in which case we can fall back to the default activity icon for an activity in // that user. // The nested catch block is for the case that the app doesn't exist, so we can fall // back to the default activity icon. try { PackageInfo pkgInfo = pm.getPackageInfo(mPackageName, 0 /* flags */); if (pkgInfo != null) { icon = pkgInfo.applicationInfo.loadIcon(pm); mName = VpnConfig.getVpnLabel(userContext, mPackageName).toString(); label = VpnConfig.getVpnLabel(userContext, mPackageName).toString(); } } catch (PackageManager.NameNotFoundException pkgNotFound) { // Use default app label and icon as fallback Loading @@ -111,10 +67,27 @@ public class AppPreference extends ManageablePreference { } catch (PackageManager.NameNotFoundException userNotFound) { // No user, no useful information to obtain. Quietly fail. } mName = label; setTitle(mName); setIcon(icon); } notifyHierarchyChanged(); public PackageInfo getPackageInfo() { try { PackageManager pm = getUserContext().getPackageManager(); return pm.getPackageInfo(mPackageName, 0 /* flags */); } catch (PackageManager.NameNotFoundException nnfe) { return null; } } public String getLabel() { return mName; } public String getPackageName() { return mPackageName; } private Context getUserContext() throws PackageManager.NameNotFoundException { Loading
src/com/android/settings/vpn2/LegacyVpnPreference.java +9 −20 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.settings.vpn2; import android.content.Context; import android.support.v7.preference.Preference; import android.text.TextUtils; import android.view.View; import com.android.internal.net.VpnProfile; Loading @@ -31,11 +32,9 @@ import static com.android.internal.net.LegacyVpnInfo.STATE_CONNECTED; public class LegacyVpnPreference extends ManageablePreference { private VpnProfile mProfile; /** One of the STATE_* fields from LegacyVpnInfo, or STATE_NONE */ private int mState = STATE_NONE; LegacyVpnPreference(Context context) { super(context, null /* attrs */); setIcon(R.mipmap.ic_launcher_settings); } public VpnProfile getProfile() { Loading @@ -43,23 +42,14 @@ public class LegacyVpnPreference extends ManageablePreference { } public void setProfile(VpnProfile profile) { mProfile = profile; update(); } public void setState(int state) { mState = state; update(); } private void update() { setSummary(getSummaryString(mState)); if (mProfile != null) { setIcon(R.mipmap.ic_launcher_settings); setTitle(mProfile.name); } final String oldLabel = (mProfile != null ? mProfile.name : null); final String newLabel = (profile != null ? profile.name : null); if (!TextUtils.equals(oldLabel, newLabel)) { setTitle(newLabel); notifyHierarchyChanged(); } mProfile = profile; } @Override public int compareTo(Preference preference) { Loading Loading @@ -93,5 +83,4 @@ public class LegacyVpnPreference extends ManageablePreference { } super.onClick(v); } }
src/com/android/settings/vpn2/ManageablePreference.java +23 −6 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ public abstract class ManageablePreference extends GearPreference { public static int STATE_NONE = -1; boolean mIsAlwaysOn = false; int mState = STATE_NONE; int mUserId; public ManageablePreference(Context context, AttributeSet attrs) { Loading @@ -56,24 +57,40 @@ public abstract class ManageablePreference extends GearPreference { return mIsAlwaysOn; } public int getState() { return mState; } public void setState(int state) { if (mState != state) { mState = state; updateSummary(); notifyHierarchyChanged(); } } public void setAlwaysOn(boolean isEnabled) { if (mIsAlwaysOn != isEnabled) { mIsAlwaysOn = isEnabled; updateSummary(); } } /** * State is not shown for {@code STATE_NONE} * Update the preference summary string (see {@see Preference#setSummary}) with a string * reflecting connection status and always-on setting. * * @return summary string showing current connection state and always-on-vpn state * State is not shown for {@code STATE_NONE}. */ protected String getSummaryString(int state) { protected void updateSummary() { final Resources res = getContext().getResources(); final String[] states = res.getStringArray(R.array.vpn_states); String summary = state == STATE_NONE ? "" : states[state]; String summary = (mState == STATE_NONE ? "" : states[mState]); if (mIsAlwaysOn) { final String alwaysOnString = res.getString(R.string.vpn_always_on_active); summary = TextUtils.isEmpty(summary) ? alwaysOnString : res.getString( R.string.join_two_unrelated_items, summary, alwaysOnString); } return summary; setSummary(summary); } }
src/com/android/settings/vpn2/VpnSettings.java +20 −28 Original line number Diff line number Diff line Loading @@ -34,7 +34,6 @@ import android.os.Handler; import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; import android.os.UserHandle; import android.os.UserManager; import android.security.Credentials; Loading Loading @@ -211,8 +210,8 @@ public class VpnSettings extends RestrictedSettingsFragment implements final List<VpnProfile> vpnProfiles = loadVpnProfiles(mKeyStore); final List<AppVpnInfo> vpnApps = getVpnApps(getActivity(), /* includeProfiles */ true); final List<LegacyVpnInfo> connectedLegacyVpns = getConnectedLegacyVpns(); final List<AppVpnInfo> connectedAppVpns = getConnectedAppVpns(); final Map<String, LegacyVpnInfo> connectedLegacyVpns = getConnectedLegacyVpns(); final Set<AppVpnInfo> connectedAppVpns = getConnectedAppVpns(); final Set<AppVpnInfo> alwaysOnAppVpnInfos = getAlwaysOnAppVpnInfos(); final String lockdownVpnKey = VpnUtils.getLockdownVpn(); Loading @@ -231,18 +230,26 @@ public class VpnSettings extends RestrictedSettingsFragment implements for (VpnProfile profile : vpnProfiles) { LegacyVpnPreference p = findOrCreatePreference(profile); if (connectedLegacyVpns.containsKey(profile.key)) { p.setState(connectedLegacyVpns.get(profile.key).state); } else { p.setState(LegacyVpnPreference.STATE_NONE); } p.setAlwaysOn(lockdownVpnKey != null && lockdownVpnKey.equals(profile.key)); updates.add(p); } for (AppVpnInfo app : vpnApps) { AppPreference p = findOrCreatePreference(app); if (connectedAppVpns.contains(app)) { p.setState(AppPreference.STATE_CONNECTED); } else { p.setState(AppPreference.STATE_DISCONNECTED); } p.setAlwaysOn(alwaysOnAppVpnInfos.contains(app)); updates.add(p); } // Trim preferences for deleted VPNs // Trim out deleted VPN preferences mLegacyVpnPreferences.values().retainAll(updates); mAppPreferences.values().retainAll(updates); Loading @@ -260,20 +267,6 @@ public class VpnSettings extends RestrictedSettingsFragment implements for (Preference pref : updates) { vpnGroup.addPreference(pref); } // Mark connected VPNs for (LegacyVpnInfo info : connectedLegacyVpns) { final LegacyVpnPreference preference = mLegacyVpnPreferences.get(info.key); if (preference != null) { preference.setState(info.state); } } for (AppVpnInfo app : connectedAppVpns) { final AppPreference preference = mAppPreferences.get(app); if (preference != null) { preference.setState(AppPreference.STATE_CONNECTED); } } } }); Loading Loading @@ -369,6 +362,7 @@ public class VpnSettings extends RestrictedSettingsFragment implements pref.setOnPreferenceClickListener(this); mLegacyVpnPreferences.put(profile.key, pref); } // This may change as the profile can update and keep the same key. pref.setProfile(profile); return pref; } Loading @@ -377,33 +371,31 @@ public class VpnSettings extends RestrictedSettingsFragment implements private AppPreference findOrCreatePreference(AppVpnInfo app) { AppPreference pref = mAppPreferences.get(app); if (pref == null) { pref = new AppPreference(getPrefContext()); pref = new AppPreference(getPrefContext(), app.userId, app.packageName); pref.setOnGearClickListener(mGearListener); pref.setOnPreferenceClickListener(this); mAppPreferences.put(app, pref); } pref.setUserId(app.userId); pref.setPackageName(app.packageName); return pref; } @WorkerThread private List<LegacyVpnInfo> getConnectedLegacyVpns() { private Map<String, LegacyVpnInfo> getConnectedLegacyVpns() { try { mConnectedLegacyVpn = mConnectivityService.getLegacyVpnInfo(UserHandle.myUserId()); if (mConnectedLegacyVpn != null) { return Collections.singletonList(mConnectedLegacyVpn); return Collections.singletonMap(mConnectedLegacyVpn.key, mConnectedLegacyVpn); } } catch (RemoteException e) { Log.e(LOG_TAG, "Failure updating VPN list with connected legacy VPNs", e); } return Collections.emptyList(); return Collections.emptyMap(); } @WorkerThread private List<AppVpnInfo> getConnectedAppVpns() { private Set<AppVpnInfo> getConnectedAppVpns() { // Mark connected third-party services List<AppVpnInfo> connections = new ArrayList<>(); Set<AppVpnInfo> connections = new ArraySet<>(); try { for (UserHandle profile : mUserManager.getUserProfiles()) { VpnConfig config = mConnectivityService.getVpnConfig(profile.getIdentifier()); Loading