From c71cff88374c7f0fd5904ffce064caa5993657be Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Fri, 15 Jan 2021 01:29:01 +0900 Subject: [PATCH] Convert LockdownVpnTracker to NetworkCallbacks. This will allow moving LockdownVpnTracker from the connectivity to the VPN code. This requires moderate refactoring since it's pretty tightly coupled to both. In this CL: 1. Add an @hide API to tell ConnectivityService that legacy lockdown VPN is enabled. I chose not to use the existing setVpnRequiredForUids API because that method has specific semantics and because it will be required long term since it's used by non-legacy VPN types. 2. Instead of updating LockdownVpnTracker inline from the ConnectivityService handler thread, have it listen to NetworkCallbacks. This introduces an extra thread hop, but most of the interactions between the lockdown VPN and CS were via NetworkAgent, which is asynchronous anyway. 3. Add code to LegacyTypeTracker to send the extra CONNECTIVITY_ACTION broadcast for the underlying network type that is sent after the VPN connects. In order to do this, make Make LockdownVpnTracker specify its underlying network (via setUnderlyingNetworks) when it connects. 4. Reimplement LockdownVpnTracker#augmentNetworkInfo based on information that is available in ConnectivityService. 5. Remove the code in LockdownVpnTracker that counted errors. I think this code has not worked since lollipop, because ConnectivityService never sees NetworkInfo objects in state FAILED. This is because ConnectivityService only hears about NetworkInfo objects via NetworkAgents, and LegacyVpnRunner only registers its NetworkAgent when the connection succeeds. Bug: 173331190 Test: passes existing tests in ConnectivityServiceTest Change-Id: I66d18512882efd468ee0ecec61f28786a195b357 --- .../src/android/net/ConnectivityManager.java | 39 +++++++++++++++++++ .../src/android/net/IConnectivityManager.aidl | 1 + 2 files changed, 40 insertions(+) diff --git a/framework/src/android/net/ConnectivityManager.java b/framework/src/android/net/ConnectivityManager.java index 0976b753e6..8437798b7b 100644 --- a/framework/src/android/net/ConnectivityManager.java +++ b/framework/src/android/net/ConnectivityManager.java @@ -1220,6 +1220,45 @@ public class ConnectivityManager { } } + /** + * Informs ConnectivityService of whether the legacy lockdown VPN, as implemented by + * LockdownVpnTracker, is in use. This is deprecated for new devices starting from Android 12 + * but is still supported for backwards compatibility. + *

+ * This type of VPN is assumed always to use the system default network, and must always declare + * exactly one underlying network, which is the network that was the default when the VPN + * connected. + *

+ * Calling this method with {@code true} enables legacy behaviour, specifically: + *

+ * + * @param enabled whether legacy lockdown VPN is enabled or disabled + * + * TODO: @SystemApi(client = MODULE_LIBRARIES) + * + * @hide + */ + @RequiresPermission(anyOf = { + NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, + android.Manifest.permission.NETWORK_SETTINGS}) + public void setLegacyLockdownVpnEnabled(boolean enabled) { + try { + mService.setLegacyLockdownVpnEnabled(enabled); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * Returns details about the currently active default data network * for a given uid. This is for internal use only to avoid spying diff --git a/framework/src/android/net/IConnectivityManager.aidl b/framework/src/android/net/IConnectivityManager.aidl index f909d13625..ab134eb6d2 100644 --- a/framework/src/android/net/IConnectivityManager.aidl +++ b/framework/src/android/net/IConnectivityManager.aidl @@ -151,6 +151,7 @@ interface IConnectivityManager boolean isVpnLockdownEnabled(int userId); List getVpnLockdownWhitelist(int userId); void setRequireVpnForUids(boolean requireVpn, in UidRange[] ranges); + void setLegacyLockdownVpnEnabled(boolean enabled); void setProvisioningNotificationVisible(boolean visible, int networkType, in String action);