Switch Settings from IConnectivityManager to VpnManager.

The VPN code is moving out of ConnectivityService to a new
VpnManagerService. Update Settings to call into the VpnManager
class instead of using the AIDL interface directly. This way,
the VPN code can be moved without touching Settings.

Bug: 173331190
Test: builds, boots
Test: manually verified VPN settings page
Change-Id: Id2731a166b5d6783acb1c711a54604b69aa8c0d7
diff --git a/src/com/android/settings/network/VpnPreferenceController.java b/src/com/android/settings/network/VpnPreferenceController.java
index 62589d5..9295414 100644
--- a/src/com/android/settings/network/VpnPreferenceController.java
+++ b/src/com/android/settings/network/VpnPreferenceController.java
@@ -19,12 +19,10 @@
 import android.content.pm.PackageManager;
 import android.content.pm.UserInfo;
 import android.net.ConnectivityManager;
-import android.net.IConnectivityManager;
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
-import android.os.RemoteException;
-import android.os.ServiceManager;
+import android.net.VpnManager;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
@@ -64,7 +62,7 @@
     private final String mToggleable;
     private final UserManager mUserManager;
     private final ConnectivityManager mConnectivityManager;
-    private final IConnectivityManager mConnectivityManagerService;
+    private final VpnManager mVpnManager;
     private Preference mPreference;
 
     public VpnPreferenceController(Context context) {
@@ -74,8 +72,7 @@
         mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
         mConnectivityManager =
                 (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
-        mConnectivityManagerService = IConnectivityManager.Stub.asInterface(
-                ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
+        mVpnManager = context.getSystemService(VpnManager.class);
     }
 
     @Override
@@ -122,27 +119,20 @@
         }
         // Copied from SystemUI::SecurityControllerImpl
         SparseArray<VpnConfig> vpns = new SparseArray<>();
-        try {
-            final List<UserInfo> users = mUserManager.getUsers();
-            for (UserInfo user : users) {
-                VpnConfig cfg = mConnectivityManagerService.getVpnConfig(user.id);
-                if (cfg == null) {
+        final List<UserInfo> users = mUserManager.getUsers();
+        for (UserInfo user : users) {
+            VpnConfig cfg = mVpnManager.getVpnConfig(user.id);
+            if (cfg == null) {
+                continue;
+            } else if (cfg.legacy) {
+                // Legacy VPNs should do nothing if the network is disconnected. Third-party
+                // VPN warnings need to continue as traffic can still go to the app.
+                final LegacyVpnInfo legacyVpn = mVpnManager.getLegacyVpnInfo(user.id);
+                if (legacyVpn == null || legacyVpn.state != LegacyVpnInfo.STATE_CONNECTED) {
                     continue;
-                } else if (cfg.legacy) {
-                    // Legacy VPNs should do nothing if the network is disconnected. Third-party
-                    // VPN warnings need to continue as traffic can still go to the app.
-                    final LegacyVpnInfo legacyVpn =
-                            mConnectivityManagerService.getLegacyVpnInfo(user.id);
-                    if (legacyVpn == null || legacyVpn.state != LegacyVpnInfo.STATE_CONNECTED) {
-                        continue;
-                    }
                 }
-                vpns.put(user.id, cfg);
             }
-        } catch (RemoteException rme) {
-            // Roll back to previous state
-            Log.e(TAG, "Unable to list active VPNs", rme);
-            return;
+            vpns.put(user.id, cfg);
         }
         final UserInfo userInfo = mUserManager.getUserInfo(UserHandle.myUserId());
         final int uid;
diff --git a/src/com/android/settings/vpn2/AppDialogFragment.java b/src/com/android/settings/vpn2/AppDialogFragment.java
index ea9e546..45fb9bd 100644
--- a/src/com/android/settings/vpn2/AppDialogFragment.java
+++ b/src/com/android/settings/vpn2/AppDialogFragment.java
@@ -18,17 +18,13 @@
 
 import android.app.Dialog;
 import android.app.settings.SettingsEnums;
-import android.content.Context;
 import android.content.DialogInterface;
 import android.content.pm.PackageInfo;
-import android.net.IConnectivityManager;
+import android.net.ConnectivityManager;
 import android.net.VpnManager;
 import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.util.Log;
 
 import androidx.appcompat.app.AlertDialog;
 import androidx.fragment.app.Fragment;
@@ -52,9 +48,9 @@
     private PackageInfo mPackageInfo;
     private Listener mListener;
 
+    private ConnectivityManager mConnectivityManager;
     private UserManager mUserManager;
-    private final IConnectivityManager mService = IConnectivityManager.Stub.asInterface(
-            ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
+    private VpnManager mVpnManager;
 
     @Override
     public int getMetricsCategory() {
@@ -97,7 +93,9 @@
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        mConnectivityManager = getContext().getSystemService(ConnectivityManager.class);
         mUserManager = UserManager.get(getContext());
+        mVpnManager = getContext().getSystemService(VpnManager.class);
     }
 
     @Override
@@ -145,14 +143,9 @@
             return;
         }
         final int userId = getUserId();
-        try {
-            mService.setVpnPackageAuthorization(
-                    mPackageInfo.packageName, userId, VpnManager.TYPE_VPN_NONE);
-            onDisconnect(dialog);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to forget authorization of " + mPackageInfo.packageName +
-                    " for user " + userId, e);
-        }
+        mVpnManager.setVpnPackageAuthorization(
+                mPackageInfo.packageName, userId, VpnManager.TYPE_VPN_NONE);
+        onDisconnect(dialog);
 
         if (mListener != null) {
             mListener.onForget();
@@ -164,15 +157,10 @@
             return;
         }
         final int userId = getUserId();
-        try {
-            if (mPackageInfo.packageName.equals(VpnUtils.getConnectedPackage(mService, userId))) {
-                mService.setAlwaysOnVpnPackage(userId, null, /* lockdownEnabled */ false,
-                        /* lockdownWhitelist */ null);
-                mService.prepareVpn(mPackageInfo.packageName, VpnConfig.LEGACY_VPN, userId);
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to disconnect package " + mPackageInfo.packageName +
-                    " for user " + userId, e);
+        if (mPackageInfo.packageName.equals(VpnUtils.getConnectedPackage(mVpnManager, userId))) {
+            mConnectivityManager.setAlwaysOnVpnPackageForUser(userId, null,
+                    /* lockdownEnabled */ false, /* lockdownAllowlist */ null);
+            mVpnManager.prepareVpn(mPackageInfo.packageName, VpnConfig.LEGACY_VPN, userId);
         }
     }
 
diff --git a/src/com/android/settings/vpn2/AppManagementFragment.java b/src/com/android/settings/vpn2/AppManagementFragment.java
index 8280a3d..8ab6a4f 100644
--- a/src/com/android/settings/vpn2/AppManagementFragment.java
+++ b/src/com/android/settings/vpn2/AppManagementFragment.java
@@ -29,10 +29,8 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.net.ConnectivityManager;
-import android.net.IConnectivityManager;
+import android.net.VpnManager;
 import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.text.TextUtils;
@@ -72,7 +70,7 @@
     private PackageManager mPackageManager;
     private DevicePolicyManager mDevicePolicyManager;
     private ConnectivityManager mConnectivityManager;
-    private IConnectivityManager mConnectivityService;
+    private VpnManager mVpnManager;
 
     // VPN app info
     private final int mUserId = UserHandle.myUserId();
@@ -125,8 +123,7 @@
         mPackageManager = getContext().getPackageManager();
         mDevicePolicyManager = getContext().getSystemService(DevicePolicyManager.class);
         mConnectivityManager = getContext().getSystemService(ConnectivityManager.class);
-        mConnectivityService = IConnectivityManager.Stub
-                .asInterface(ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
+        mVpnManager = getContext().getSystemService(VpnManager.class);
 
         mPreferenceVersion = findPreference(KEY_VERSION);
         mPreferenceAlwaysOn = (RestrictedSwitchPreference) findPreference(KEY_ALWAYS_ON_VPN);
@@ -335,13 +332,8 @@
      * @return {@code true} if another VPN (VpnService or legacy) is connected or set as always-on.
      */
     private boolean isAnotherVpnActive() {
-        try {
-            final VpnConfig config = mConnectivityService.getVpnConfig(mUserId);
-            return config != null && !TextUtils.equals(config.user, mPackageName);
-        } catch (RemoteException e) {
-            Log.w(TAG, "Failure to look up active VPN", e);
-            return false;
-        }
+        final VpnConfig config = mVpnManager.getVpnConfig(mUserId);
+        return config != null && !TextUtils.equals(config.user, mPackageName);
     }
 
     public static class CannotConnectFragment extends InstrumentedDialogFragment {
diff --git a/src/com/android/settings/vpn2/ConfigDialogFragment.java b/src/com/android/settings/vpn2/ConfigDialogFragment.java
index 57ba8bf..a478eb9 100644
--- a/src/com/android/settings/vpn2/ConfigDialogFragment.java
+++ b/src/com/android/settings/vpn2/ConfigDialogFragment.java
@@ -21,10 +21,9 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.net.ConnectivityManager;
-import android.net.IConnectivityManager;
+import android.net.VpnManager;
 import android.os.Bundle;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.security.Credentials;
 import android.security.KeyStore;
@@ -52,9 +51,8 @@
     private static final String ARG_EDITING = "editing";
     private static final String ARG_EXISTS = "exists";
 
-    private final IConnectivityManager mService = IConnectivityManager.Stub.asInterface(
-            ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
     private Context mContext;
+    private VpnManager mService;
 
 
     @Override
@@ -80,6 +78,7 @@
     public void onAttach(final Context context) {
         super.onAttach(context);
         mContext = context;
+        mService = context.getSystemService(VpnManager.class);
     }
 
     @Override
@@ -212,8 +211,6 @@
                 mService.startLegacyVpn(profile);
             } catch (IllegalStateException e) {
                 Toast.makeText(mContext, R.string.vpn_no_network, Toast.LENGTH_LONG).show();
-            } catch (RemoteException e) {
-                Log.e(TAG, "Failed to connect", e);
             }
         }
     }
diff --git a/src/com/android/settings/vpn2/VpnSettings.java b/src/com/android/settings/vpn2/VpnSettings.java
index 8a2b465..79f6be3 100644
--- a/src/com/android/settings/vpn2/VpnSettings.java
+++ b/src/com/android/settings/vpn2/VpnSettings.java
@@ -30,16 +30,14 @@
 import android.content.pm.PackageManager;
 import android.net.ConnectivityManager;
 import android.net.ConnectivityManager.NetworkCallback;
-import android.net.IConnectivityManager;
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
+import android.net.VpnManager;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Message;
-import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.security.Credentials;
@@ -92,10 +90,9 @@
             .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
             .build();
 
-    private final IConnectivityManager mConnectivityService = IConnectivityManager.Stub
-            .asInterface(ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
     private ConnectivityManager mConnectivityManager;
     private UserManager mUserManager;
+    private VpnManager mVpnManager;
 
     private final KeyStore mKeyStore = KeyStore.getInstance();
 
@@ -124,6 +121,7 @@
 
         mUserManager = (UserManager) getSystemService(Context.USER_SERVICE);
         mConnectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
+        mVpnManager = (VpnManager) getSystemService(Context.VPN_MANAGEMENT_SERVICE);
 
         mUnavailable = isUiRestricted();
         setHasOptionsMenu(!mUnavailable);
@@ -467,13 +465,9 @@
 
     @WorkerThread
     private Map<String, LegacyVpnInfo> getConnectedLegacyVpns() {
-        try {
-            mConnectedLegacyVpn = mConnectivityService.getLegacyVpnInfo(UserHandle.myUserId());
-            if (mConnectedLegacyVpn != null) {
-                return Collections.singletonMap(mConnectedLegacyVpn.key, mConnectedLegacyVpn);
-            }
-        } catch (RemoteException e) {
-            Log.e(LOG_TAG, "Failure updating VPN list with connected legacy VPNs", e);
+        mConnectedLegacyVpn = mVpnManager.getLegacyVpnInfo(UserHandle.myUserId());
+        if (mConnectedLegacyVpn != null) {
+            return Collections.singletonMap(mConnectedLegacyVpn.key, mConnectedLegacyVpn);
         }
         return Collections.emptyMap();
     }
@@ -482,15 +476,11 @@
     private Set<AppVpnInfo> getConnectedAppVpns() {
         // Mark connected third-party services
         Set<AppVpnInfo> connections = new ArraySet<>();
-        try {
-            for (UserHandle profile : mUserManager.getUserProfiles()) {
-                VpnConfig config = mConnectivityService.getVpnConfig(profile.getIdentifier());
-                if (config != null && !config.legacy) {
-                    connections.add(new AppVpnInfo(profile.getIdentifier(), config.user));
-                }
+        for (UserHandle profile : mUserManager.getUserProfiles()) {
+            VpnConfig config = mVpnManager.getVpnConfig(profile.getIdentifier());
+            if (config != null && !config.legacy) {
+                connections.add(new AppVpnInfo(profile.getIdentifier(), config.user));
             }
-        } catch (RemoteException e) {
-            Log.e(LOG_TAG, "Failure updating VPN list with connected app VPNs", e);
         }
         return connections;
     }
diff --git a/src/com/android/settings/vpn2/VpnUtils.java b/src/com/android/settings/vpn2/VpnUtils.java
index 38c56c5..c6b79b4 100644
--- a/src/com/android/settings/vpn2/VpnUtils.java
+++ b/src/com/android/settings/vpn2/VpnUtils.java
@@ -17,13 +17,11 @@
 
 import android.content.Context;
 import android.net.ConnectivityManager;
-import android.net.IConnectivityManager;
+import android.net.VpnManager;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.provider.Settings;
 import android.security.Credentials;
 import android.security.KeyStore;
-import android.util.Log;
 
 import com.android.internal.net.LegacyVpnInfo;
 import com.android.internal.net.VpnConfig;
@@ -71,12 +69,11 @@
     }
 
     public static boolean isVpnActive(Context context) throws RemoteException {
-        return getIConnectivityManager().getVpnConfig(context.getUserId()) != null;
+        return getVpnManager(context).getVpnConfig(context.getUserId()) != null;
     }
 
-    public static String getConnectedPackage(IConnectivityManager service, final int userId)
-            throws RemoteException {
-        final VpnConfig config = service.getVpnConfig(userId);
+    public static String getConnectedPackage(VpnManager vpnManager, final int userId) {
+        final VpnConfig config = vpnManager.getVpnConfig(userId);
         return config != null ? config.user : null;
     }
 
@@ -84,9 +81,8 @@
         return context.getSystemService(ConnectivityManager.class);
     }
 
-    private static IConnectivityManager getIConnectivityManager() {
-        return IConnectivityManager.Stub.asInterface(
-                ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
+    private static VpnManager getVpnManager(Context context) {
+        return context.getSystemService(VpnManager.class);
     }
 
     public static boolean isAlwaysOnVpnSet(ConnectivityManager cm, final int userId) {
@@ -94,17 +90,12 @@
     }
 
     public static boolean disconnectLegacyVpn(Context context) {
-        try {
-            int userId = context.getUserId();
-            IConnectivityManager connectivityService = getIConnectivityManager();
-            LegacyVpnInfo currentLegacyVpn = connectivityService.getLegacyVpnInfo(userId);
-            if (currentLegacyVpn != null) {
-                clearLockdownVpn(context);
-                connectivityService.prepareVpn(null, VpnConfig.LEGACY_VPN, userId);
-                return true;
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "Legacy VPN could not be disconnected", e);
+        int userId = context.getUserId();
+        LegacyVpnInfo currentLegacyVpn = getVpnManager(context).getLegacyVpnInfo(userId);
+        if (currentLegacyVpn != null) {
+            clearLockdownVpn(context);
+            getVpnManager(context).prepareVpn(null, VpnConfig.LEGACY_VPN, userId);
+            return true;
         }
         return false;
     }