Be more aggressive caching Vpn preference attrs
As any change to the preference title will cause it to lose focus,
best not to do this too often.
Change-Id: Ibac27ee1de42fd7ca05f3e3685b84f37dac39517
Fix: 28191965
diff --git a/src/com/android/settings/vpn2/AppPreference.java b/src/com/android/settings/vpn2/AppPreference.java
index fa9daf6..3369970 100644
--- a/src/com/android/settings/vpn2/AppPreference.java
+++ b/src/com/android/settings/vpn2/AppPreference.java
@@ -34,17 +34,43 @@
public static final int STATE_CONNECTED = LegacyVpnInfo.STATE_CONNECTED;
public static final int STATE_DISCONNECTED = STATE_NONE;
- 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();
+
+ mPackageName = packageName;
+
+ // 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();
+ // 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);
+ label = VpnConfig.getVpnLabel(userContext, mPackageName).toString();
+ }
+ } catch (PackageManager.NameNotFoundException pkgNotFound) {
+ // Use default app label and icon as fallback
+ }
+ if (icon == null) {
+ icon = pm.getDefaultActivityIcon();
+ }
+ } catch (PackageManager.NameNotFoundException userNotFound) {
+ // No user, no useful information to obtain. Quietly fail.
+ }
+ mName = label;
+
+ setTitle(mName);
+ setIcon(icon);
}
public PackageInfo getPackageInfo() {
@@ -64,48 +90,6 @@
return mPackageName;
}
- public void setPackageName(String name) {
- mPackageName = name;
- update();
- }
-
- private void update() {
- if (mPackageName == null || mUserId == UserHandle.USER_NULL) {
- return;
- }
-
- mName = mPackageName;
- 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.
- try {
- PackageInfo pkgInfo = pm.getPackageInfo(mPackageName, 0 /* flags */);
- if (pkgInfo != null) {
- icon = pkgInfo.applicationInfo.loadIcon(pm);
- mName = VpnConfig.getVpnLabel(userContext, mPackageName).toString();
- }
- } catch (PackageManager.NameNotFoundException pkgNotFound) {
- // Use default app label and icon as fallback
- }
- if (icon == null) {
- icon = pm.getDefaultActivityIcon();
- }
- } catch (PackageManager.NameNotFoundException userNotFound) {
- // No user, no useful information to obtain. Quietly fail.
- }
- setTitle(mName);
- setIcon(icon);
- updateSummary();
-
- notifyHierarchyChanged();
- }
-
private Context getUserContext() throws PackageManager.NameNotFoundException {
UserHandle user = UserHandle.of(mUserId);
return getContext().createPackageContextAsUser(
diff --git a/src/com/android/settings/vpn2/LegacyVpnPreference.java b/src/com/android/settings/vpn2/LegacyVpnPreference.java
index 2ce22d4..c1550e2 100644
--- a/src/com/android/settings/vpn2/LegacyVpnPreference.java
+++ b/src/com/android/settings/vpn2/LegacyVpnPreference.java
@@ -18,6 +18,7 @@
import android.content.Context;
import android.support.v7.preference.Preference;
+import android.text.TextUtils;
import android.view.View;
import com.android.internal.net.VpnProfile;
@@ -33,6 +34,7 @@
LegacyVpnPreference(Context context) {
super(context, null /* attrs */);
+ setIcon(R.mipmap.ic_launcher_settings);
}
public VpnProfile getProfile() {
@@ -40,12 +42,13 @@
}
public void setProfile(VpnProfile profile) {
- mProfile = profile;
- 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();
}
- notifyHierarchyChanged();
+ mProfile = profile;
}
@Override
diff --git a/src/com/android/settings/vpn2/ManageablePreference.java b/src/com/android/settings/vpn2/ManageablePreference.java
index 7c07e20..e31a396 100644
--- a/src/com/android/settings/vpn2/ManageablePreference.java
+++ b/src/com/android/settings/vpn2/ManageablePreference.java
@@ -62,13 +62,18 @@
}
public void setState(int state) {
- mState = state;
- updateSummary();
+ if (mState != state) {
+ mState = state;
+ updateSummary();
+ notifyHierarchyChanged();
+ }
}
public void setAlwaysOn(boolean isEnabled) {
- mIsAlwaysOn = isEnabled;
- updateSummary();
+ if (mIsAlwaysOn != isEnabled) {
+ mIsAlwaysOn = isEnabled;
+ updateSummary();
+ }
}
/**
diff --git a/src/com/android/settings/vpn2/VpnSettings.java b/src/com/android/settings/vpn2/VpnSettings.java
index 6c47b43..a675779 100644
--- a/src/com/android/settings/vpn2/VpnSettings.java
+++ b/src/com/android/settings/vpn2/VpnSettings.java
@@ -34,7 +34,6 @@
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;
@@ -211,8 +210,8 @@
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();
@@ -231,18 +230,26 @@
for (VpnProfile profile : vpnProfiles) {
LegacyVpnPreference p = findOrCreatePreference(profile);
- p.setState(LegacyVpnPreference.STATE_NONE);
+ 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);
- p.setState(AppPreference.STATE_DISCONNECTED);
+ 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);
@@ -260,20 +267,6 @@
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);
- }
- }
}
});
@@ -369,6 +362,7 @@
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;
}
@@ -377,33 +371,31 @@
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());