VpnSettings: show connected VPN even if deleted
So there's a way to disconnect from it, if someone deletes all the keystore entries and the VPN doesn't actually exist any more (but is still sitting around in memory somewhere keeping the connection alive). Bug: 29093779 Fix: 32880676 Test: runtest -x tests/app/src/com/android/settings/vpn2/VpnTests.java Change-Id: I97671a74af746e5baaa5be0b5cff24e2b1766f53
This commit is contained in:
@@ -49,6 +49,7 @@ import android.view.Menu;
|
|||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
|
||||||
|
import com.android.internal.annotations.GuardedBy;
|
||||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||||
import com.android.internal.net.LegacyVpnInfo;
|
import com.android.internal.net.LegacyVpnInfo;
|
||||||
import com.android.internal.net.VpnConfig;
|
import com.android.internal.net.VpnConfig;
|
||||||
@@ -96,8 +97,9 @@ public class VpnSettings extends RestrictedSettingsFragment implements
|
|||||||
private Map<String, LegacyVpnPreference> mLegacyVpnPreferences = new ArrayMap<>();
|
private Map<String, LegacyVpnPreference> mLegacyVpnPreferences = new ArrayMap<>();
|
||||||
private Map<AppVpnInfo, AppPreference> mAppPreferences = new ArrayMap<>();
|
private Map<AppVpnInfo, AppPreference> mAppPreferences = new ArrayMap<>();
|
||||||
|
|
||||||
private HandlerThread mUpdaterThread;
|
@GuardedBy("this")
|
||||||
private Handler mUpdater;
|
private Handler mUpdater;
|
||||||
|
private HandlerThread mUpdaterThread;
|
||||||
private LegacyVpnInfo mConnectedLegacyVpn;
|
private LegacyVpnInfo mConnectedLegacyVpn;
|
||||||
|
|
||||||
private boolean mUnavailable;
|
private boolean mUnavailable;
|
||||||
@@ -181,11 +183,9 @@ public class VpnSettings extends RestrictedSettingsFragment implements
|
|||||||
mConnectivityManager.registerNetworkCallback(VPN_REQUEST, mNetworkCallback);
|
mConnectivityManager.registerNetworkCallback(VPN_REQUEST, mNetworkCallback);
|
||||||
|
|
||||||
// Trigger a refresh
|
// Trigger a refresh
|
||||||
if (mUpdater == null) {
|
|
||||||
mUpdaterThread = new HandlerThread("Refresh VPN list in background");
|
mUpdaterThread = new HandlerThread("Refresh VPN list in background");
|
||||||
mUpdaterThread.start();
|
mUpdaterThread.start();
|
||||||
mUpdater = new Handler(mUpdaterThread.getLooper(), this);
|
mUpdater = new Handler(mUpdaterThread.getLooper(), this);
|
||||||
}
|
|
||||||
mUpdater.sendEmptyMessage(RESCAN_MESSAGE);
|
mUpdater.sendEmptyMessage(RESCAN_MESSAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,7 +199,7 @@ public class VpnSettings extends RestrictedSettingsFragment implements
|
|||||||
// Stop monitoring
|
// Stop monitoring
|
||||||
mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
|
mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
|
||||||
|
|
||||||
if (mUpdater != null) {
|
synchronized (this) {
|
||||||
mUpdater.removeCallbacksAndMessages(null);
|
mUpdater.removeCallbacksAndMessages(null);
|
||||||
mUpdater = null;
|
mUpdater = null;
|
||||||
mUpdaterThread.quit();
|
mUpdaterThread.quit();
|
||||||
@@ -211,8 +211,6 @@ public class VpnSettings extends RestrictedSettingsFragment implements
|
|||||||
|
|
||||||
@Override @WorkerThread
|
@Override @WorkerThread
|
||||||
public boolean handleMessage(Message message) {
|
public boolean handleMessage(Message message) {
|
||||||
mUpdater.removeMessages(RESCAN_MESSAGE);
|
|
||||||
|
|
||||||
// Run heavy RPCs before switching to UI thread
|
// Run heavy RPCs before switching to UI thread
|
||||||
final List<VpnProfile> vpnProfiles = loadVpnProfiles(mKeyStore);
|
final List<VpnProfile> vpnProfiles = loadVpnProfiles(mKeyStore);
|
||||||
final List<AppVpnInfo> vpnApps = getVpnApps(getActivity(), /* includeProfiles */ true);
|
final List<AppVpnInfo> vpnApps = getVpnApps(getActivity(), /* includeProfiles */ true);
|
||||||
@@ -223,6 +221,13 @@ public class VpnSettings extends RestrictedSettingsFragment implements
|
|||||||
final Set<AppVpnInfo> alwaysOnAppVpnInfos = getAlwaysOnAppVpnInfos();
|
final Set<AppVpnInfo> alwaysOnAppVpnInfos = getAlwaysOnAppVpnInfos();
|
||||||
final String lockdownVpnKey = VpnUtils.getLockdownVpn();
|
final String lockdownVpnKey = VpnUtils.getLockdownVpn();
|
||||||
|
|
||||||
|
synchronized (this) {
|
||||||
|
if (mUpdater != null) {
|
||||||
|
mUpdater.removeMessages(RESCAN_MESSAGE);
|
||||||
|
mUpdater.sendEmptyMessageDelayed(RESCAN_MESSAGE, RESCAN_INTERVAL_MS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Refresh list of VPNs
|
// Refresh list of VPNs
|
||||||
getActivity().runOnUiThread(new Runnable() {
|
getActivity().runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
@@ -235,8 +240,9 @@ public class VpnSettings extends RestrictedSettingsFragment implements
|
|||||||
// Find new VPNs by subtracting existing ones from the full set
|
// Find new VPNs by subtracting existing ones from the full set
|
||||||
final Set<Preference> updates = new ArraySet<>();
|
final Set<Preference> updates = new ArraySet<>();
|
||||||
|
|
||||||
|
// Add legacy VPNs
|
||||||
for (VpnProfile profile : vpnProfiles) {
|
for (VpnProfile profile : vpnProfiles) {
|
||||||
LegacyVpnPreference p = findOrCreatePreference(profile);
|
LegacyVpnPreference p = findOrCreatePreference(profile, true);
|
||||||
if (connectedLegacyVpns.containsKey(profile.key)) {
|
if (connectedLegacyVpns.containsKey(profile.key)) {
|
||||||
p.setState(connectedLegacyVpns.get(profile.key).state);
|
p.setState(connectedLegacyVpns.get(profile.key).state);
|
||||||
} else {
|
} else {
|
||||||
@@ -245,6 +251,17 @@ public class VpnSettings extends RestrictedSettingsFragment implements
|
|||||||
p.setAlwaysOn(lockdownVpnKey != null && lockdownVpnKey.equals(profile.key));
|
p.setAlwaysOn(lockdownVpnKey != null && lockdownVpnKey.equals(profile.key));
|
||||||
updates.add(p);
|
updates.add(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Show connected VPNs even if the original entry in keystore is gone
|
||||||
|
for (LegacyVpnInfo vpn : connectedLegacyVpns.values()) {
|
||||||
|
final VpnProfile stubProfile = new VpnProfile(vpn.key);
|
||||||
|
LegacyVpnPreference p = findOrCreatePreference(stubProfile, false);
|
||||||
|
p.setState(vpn.state);
|
||||||
|
p.setAlwaysOn(lockdownVpnKey != null && lockdownVpnKey.equals(vpn.key));
|
||||||
|
updates.add(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add VpnService VPNs
|
||||||
for (AppVpnInfo app : vpnApps) {
|
for (AppVpnInfo app : vpnApps) {
|
||||||
AppPreference p = findOrCreatePreference(app);
|
AppPreference p = findOrCreatePreference(app);
|
||||||
if (connectedAppVpns.contains(app)) {
|
if (connectedAppVpns.contains(app)) {
|
||||||
@@ -276,8 +293,6 @@ public class VpnSettings extends RestrictedSettingsFragment implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
mUpdater.sendEmptyMessageDelayed(RESCAN_MESSAGE, RESCAN_INTERVAL_MS);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -361,16 +376,20 @@ public class VpnSettings extends RestrictedSettingsFragment implements
|
|||||||
};
|
};
|
||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
private LegacyVpnPreference findOrCreatePreference(VpnProfile profile) {
|
private LegacyVpnPreference findOrCreatePreference(VpnProfile profile, boolean update) {
|
||||||
LegacyVpnPreference pref = mLegacyVpnPreferences.get(profile.key);
|
LegacyVpnPreference pref = mLegacyVpnPreferences.get(profile.key);
|
||||||
if (pref == null) {
|
boolean created = false;
|
||||||
|
if (pref == null ) {
|
||||||
pref = new LegacyVpnPreference(getPrefContext());
|
pref = new LegacyVpnPreference(getPrefContext());
|
||||||
pref.setOnGearClickListener(mGearListener);
|
pref.setOnGearClickListener(mGearListener);
|
||||||
pref.setOnPreferenceClickListener(this);
|
pref.setOnPreferenceClickListener(this);
|
||||||
mLegacyVpnPreferences.put(profile.key, pref);
|
mLegacyVpnPreferences.put(profile.key, pref);
|
||||||
|
created = true;
|
||||||
}
|
}
|
||||||
// This may change as the profile can update and keep the same key.
|
if (created || update) {
|
||||||
|
// This can change call-to-call because the profile can update and keep the same key.
|
||||||
pref.setProfile(profile);
|
pref.setProfile(profile);
|
||||||
|
}
|
||||||
return pref;
|
return pref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user