diff --git a/framework/src/android/net/VpnManager.java b/framework/src/android/net/VpnManager.java
deleted file mode 100644
index f472ed4..0000000
--- a/framework/src/android/net/VpnManager.java
+++ /dev/null
@@ -1,406 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import static com.android.internal.util.Preconditions.checkNotNull;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.UserIdInt;
-import android.app.Activity;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.os.RemoteException;
-
-import com.android.internal.net.LegacyVpnInfo;
-import com.android.internal.net.VpnConfig;
-import com.android.internal.net.VpnProfile;
-
-import java.io.IOException;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.security.GeneralSecurityException;
-import java.util.List;
-
-/**
- * This class provides an interface for apps to manage platform VPN profiles
- *
- * <p>Apps can use this API to provide profiles with which the platform can set up a VPN without
- * further app intermediation. When a VPN profile is present and the app is selected as an always-on
- * VPN, the platform will directly trigger the negotiation of the VPN without starting or waking the
- * app (unlike VpnService).
- *
- * <p>VPN apps using supported protocols should preferentially use this API over the {@link
- * VpnService} API for ease-of-development and reduced maintainance burden. This also give the user
- * the guarantee that VPN network traffic is not subjected to on-device packet interception.
- *
- * @see Ikev2VpnProfile
- */
-public class VpnManager {
-    /** Type representing a lack of VPN @hide */
-    public static final int TYPE_VPN_NONE = -1;
-
-    /**
-     * A VPN created by an app using the {@link VpnService} API.
-     * @hide
-     */
-    public static final int TYPE_VPN_SERVICE = 1;
-
-    /**
-     * A VPN created using a {@link VpnManager} API such as {@link #startProvisionedVpnProfile}.
-     * @hide
-     */
-    public static final int TYPE_VPN_PLATFORM = 2;
-
-    /**
-     * An IPsec VPN created by the built-in LegacyVpnRunner.
-     * @deprecated new Android devices should use VPN_TYPE_PLATFORM instead.
-     * @hide
-     */
-    @Deprecated
-    public static final int TYPE_VPN_LEGACY = 3;
-
-    /**
-     * Channel for VPN notifications.
-     * @hide
-     */
-    public static final String NOTIFICATION_CHANNEL_VPN = "VPN";
-
-    /** @hide */
-    @IntDef(value = {TYPE_VPN_NONE, TYPE_VPN_SERVICE, TYPE_VPN_PLATFORM, TYPE_VPN_LEGACY})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface VpnType {}
-
-    @NonNull private final Context mContext;
-    @NonNull private final IVpnManager mService;
-
-    private static Intent getIntentForConfirmation() {
-        final Intent intent = new Intent();
-        final ComponentName componentName = ComponentName.unflattenFromString(
-                Resources.getSystem().getString(
-                        com.android.internal.R.string.config_platformVpnConfirmDialogComponent));
-        intent.setComponent(componentName);
-        return intent;
-    }
-
-    /**
-     * Create an instance of the VpnManager with the given context.
-     *
-     * <p>Internal only. Applications are expected to obtain an instance of the VpnManager via the
-     * {@link Context.getSystemService()} method call.
-     *
-     * @hide
-     */
-    public VpnManager(@NonNull Context ctx, @NonNull IVpnManager service) {
-        mContext = checkNotNull(ctx, "missing Context");
-        mService = checkNotNull(service, "missing IVpnManager");
-    }
-
-    /**
-     * Install a VpnProfile configuration keyed on the calling app's package name.
-     *
-     * <p>This method returns {@code null} if user consent has already been granted, or an {@link
-     * Intent} to a system activity. If an intent is returned, the application should launch the
-     * activity using {@link Activity#startActivityForResult} to request user consent. The activity
-     * may pop up a dialog to require user action, and the result will come back via its {@link
-     * Activity#onActivityResult}. If the result is {@link Activity#RESULT_OK}, the user has
-     * consented, and the VPN profile can be started.
-     *
-     * @param profile the VpnProfile provided by this package. Will override any previous VpnProfile
-     *     stored for this package.
-     * @return an Intent requesting user consent to start the VPN, or null if consent is not
-     *     required based on privileges or previous user consent.
-     */
-    @Nullable
-    public Intent provisionVpnProfile(@NonNull PlatformVpnProfile profile) {
-        final VpnProfile internalProfile;
-
-        try {
-            internalProfile = profile.toVpnProfile();
-        } catch (GeneralSecurityException | IOException e) {
-            // Conversion to VpnProfile failed; this is an invalid profile. Both of these exceptions
-            // indicate a failure to convert a PrivateKey or X509Certificate to a Base64 encoded
-            // string as required by the VpnProfile.
-            throw new IllegalArgumentException("Failed to serialize PlatformVpnProfile", e);
-        }
-
-        try {
-            // Profile can never be null; it either gets set, or an exception is thrown.
-            if (mService.provisionVpnProfile(internalProfile, mContext.getOpPackageName())) {
-                return null;
-            }
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-        return getIntentForConfirmation();
-    }
-
-    /**
-     * Delete the VPN profile configuration that was provisioned by the calling app
-     *
-     * @throws SecurityException if this would violate user settings
-     */
-    public void deleteProvisionedVpnProfile() {
-        try {
-            mService.deleteVpnProfile(mContext.getOpPackageName());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Request the startup of a previously provisioned VPN.
-     *
-     * @throws SecurityException exception if user or device settings prevent this VPN from being
-     *     setup, or if user consent has not been granted
-     */
-    public void startProvisionedVpnProfile() {
-        try {
-            mService.startVpnProfile(mContext.getOpPackageName());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /** Tear down the VPN provided by the calling app (if any) */
-    public void stopProvisionedVpnProfile() {
-        try {
-            mService.stopVpnProfile(mContext.getOpPackageName());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Return the VPN configuration for the given user ID.
-     * @hide
-     */
-    @Nullable
-    public VpnConfig getVpnConfig(@UserIdInt int userId) {
-        try {
-            return mService.getVpnConfig(userId);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Resets all VPN settings back to factory defaults.
-     * @hide
-     */
-    @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
-    public void factoryReset() {
-        try {
-            mService.factoryReset();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Prepare for a VPN application.
-     * VPN permissions are checked in the {@link Vpn} class. If the caller is not {@code userId},
-     * {@link android.Manifest.permission.INTERACT_ACROSS_USERS_FULL} permission is required.
-     *
-     * @param oldPackage Package name of the application which currently controls VPN, which will
-     *                   be replaced. If there is no such application, this should should either be
-     *                   {@code null} or {@link VpnConfig.LEGACY_VPN}.
-     * @param newPackage Package name of the application which should gain control of VPN, or
-     *                   {@code null} to disable.
-     * @param userId User for whom to prepare the new VPN.
-     *
-     * @hide
-     */
-    public boolean prepareVpn(@Nullable String oldPackage, @Nullable String newPackage,
-            int userId) {
-        try {
-            return mService.prepareVpn(oldPackage, newPackage, userId);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Set whether the VPN package has the ability to launch VPNs without user intervention. This
-     * method is used by system-privileged apps. VPN permissions are checked in the {@link Vpn}
-     * class. If the caller is not {@code userId}, {@link
-     * android.Manifest.permission.INTERACT_ACROSS_USERS_FULL} permission is required.
-     *
-     * @param packageName The package for which authorization state should change.
-     * @param userId User for whom {@code packageName} is installed.
-     * @param vpnType The {@link VpnManager.VpnType} constant representing what class of VPN
-     *     permissions should be granted. When unauthorizing an app, {@link
-     *     VpnManager.TYPE_VPN_NONE} should be used.
-     * @hide
-     */
-    public void setVpnPackageAuthorization(
-            String packageName, int userId, @VpnManager.VpnType int vpnType) {
-        try {
-            mService.setVpnPackageAuthorization(packageName, userId, vpnType);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Checks if a VPN app supports always-on mode.
-     *
-     * In order to support the always-on feature, an app has to
-     * <ul>
-     *     <li>target {@link VERSION_CODES#N API 24} or above, and
-     *     <li>not opt out through the {@link VpnService#SERVICE_META_DATA_SUPPORTS_ALWAYS_ON}
-     *         meta-data field.
-     * </ul>
-     *
-     * @param userId The identifier of the user for whom the VPN app is installed.
-     * @param vpnPackage The canonical package name of the VPN app.
-     * @return {@code true} if and only if the VPN app exists and supports always-on mode.
-     * @hide
-     */
-    public boolean isAlwaysOnVpnPackageSupportedForUser(int userId, @Nullable String vpnPackage) {
-        try {
-            return mService.isAlwaysOnVpnPackageSupported(userId, vpnPackage);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Configures an always-on VPN connection through a specific application.
-     * This connection is automatically granted and persisted after a reboot.
-     *
-     * <p>The designated package should declare a {@link VpnService} in its
-     *    manifest guarded by {@link android.Manifest.permission.BIND_VPN_SERVICE},
-     *    otherwise the call will fail.
-     *
-     * @param userId The identifier of the user to set an always-on VPN for.
-     * @param vpnPackage The package name for an installed VPN app on the device, or {@code null}
-     *                   to remove an existing always-on VPN configuration.
-     * @param lockdownEnabled {@code true} to disallow networking when the VPN is not connected or
-     *        {@code false} otherwise.
-     * @param lockdownAllowlist The list of packages that are allowed to access network directly
-     *         when VPN is in lockdown mode but is not running. Non-existent packages are ignored so
-     *         this method must be called when a package that should be allowed is installed or
-     *         uninstalled.
-     * @return {@code true} if the package is set as always-on VPN controller;
-     *         {@code false} otherwise.
-     * @hide
-     */
-    @RequiresPermission(android.Manifest.permission.CONTROL_ALWAYS_ON_VPN)
-    public boolean setAlwaysOnVpnPackageForUser(int userId, @Nullable String vpnPackage,
-            boolean lockdownEnabled, @Nullable List<String> lockdownAllowlist) {
-        try {
-            return mService.setAlwaysOnVpnPackage(
-                    userId, vpnPackage, lockdownEnabled, lockdownAllowlist);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Returns the package name of the currently set always-on VPN application.
-     * If there is no always-on VPN set, or the VPN is provided by the system instead
-     * of by an app, {@code null} will be returned.
-     *
-     * @return Package name of VPN controller responsible for always-on VPN,
-     *         or {@code null} if none is set.
-     * @hide
-     */
-    @RequiresPermission(android.Manifest.permission.CONTROL_ALWAYS_ON_VPN)
-    public String getAlwaysOnVpnPackageForUser(int userId) {
-        try {
-            return mService.getAlwaysOnVpnPackage(userId);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * @return whether always-on VPN is in lockdown mode.
-     *
-     * @hide
-     **/
-    @RequiresPermission(android.Manifest.permission.CONTROL_ALWAYS_ON_VPN)
-    public boolean isVpnLockdownEnabled(int userId) {
-        try {
-            return mService.isVpnLockdownEnabled(userId);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * @return the list of packages that are allowed to access network when always-on VPN is in
-     * lockdown mode but not connected. Returns {@code null} when VPN lockdown is not active.
-     *
-     * @hide
-     **/
-    @RequiresPermission(android.Manifest.permission.CONTROL_ALWAYS_ON_VPN)
-    public List<String> getVpnLockdownAllowlist(int userId) {
-        try {
-            return mService.getVpnLockdownAllowlist(userId);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Return the legacy VPN information for the specified user ID.
-     * @hide
-     */
-    public LegacyVpnInfo getLegacyVpnInfo(@UserIdInt int userId) {
-        try {
-            return mService.getLegacyVpnInfo(userId);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Starts a legacy VPN.
-     * @hide
-     */
-    public void startLegacyVpn(VpnProfile profile) {
-        try {
-            mService.startLegacyVpn(profile);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Informs the service that legacy lockdown VPN state should be updated (e.g., if its keystore
-     * entry has been updated). If the LockdownVpn mechanism is enabled, updates the vpn
-     * with a reload of its profile.
-     *
-     * <p>This method can only be called by the system UID
-     * @return a boolean indicating success
-     *
-     * @hide
-     */
-    public boolean updateLockdownVpn() {
-        try {
-            return mService.updateLockdownVpn();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-}
\ No newline at end of file
diff --git a/framework/src/android/net/VpnService.java b/framework/src/android/net/VpnService.java
deleted file mode 100644
index e43b0b6..0000000
--- a/framework/src/android/net/VpnService.java
+++ /dev/null
@@ -1,902 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import static android.system.OsConstants.AF_INET;
-import static android.system.OsConstants.AF_INET6;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.SystemApi;
-import android.app.Activity;
-import android.app.PendingIntent;
-import android.app.Service;
-import android.app.admin.DevicePolicyManager;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
-import android.os.Binder;
-import android.os.IBinder;
-import android.os.Parcel;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.UserHandle;
-
-import com.android.internal.net.VpnConfig;
-
-import java.net.DatagramSocket;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-
-/**
- * VpnService is a base class for applications to extend and build their
- * own VPN solutions. In general, it creates a virtual network interface,
- * configures addresses and routing rules, and returns a file descriptor
- * to the application. Each read from the descriptor retrieves an outgoing
- * packet which was routed to the interface. Each write to the descriptor
- * injects an incoming packet just like it was received from the interface.
- * The interface is running on Internet Protocol (IP), so packets are
- * always started with IP headers. The application then completes a VPN
- * connection by processing and exchanging packets with the remote server
- * over a tunnel.
- *
- * <p>Letting applications intercept packets raises huge security concerns.
- * A VPN application can easily break the network. Besides, two of them may
- * conflict with each other. The system takes several actions to address
- * these issues. Here are some key points:
- * <ul>
- *   <li>User action is required the first time an application creates a VPN
- *       connection.</li>
- *   <li>There can be only one VPN connection running at the same time. The
- *       existing interface is deactivated when a new one is created.</li>
- *   <li>A system-managed notification is shown during the lifetime of a
- *       VPN connection.</li>
- *   <li>A system-managed dialog gives the information of the current VPN
- *       connection. It also provides a button to disconnect.</li>
- *   <li>The network is restored automatically when the file descriptor is
- *       closed. It also covers the cases when a VPN application is crashed
- *       or killed by the system.</li>
- * </ul>
- *
- * <p>There are two primary methods in this class: {@link #prepare} and
- * {@link Builder#establish}. The former deals with user action and stops
- * the VPN connection created by another application. The latter creates
- * a VPN interface using the parameters supplied to the {@link Builder}.
- * An application must call {@link #prepare} to grant the right to use
- * other methods in this class, and the right can be revoked at any time.
- * Here are the general steps to create a VPN connection:
- * <ol>
- *   <li>When the user presses the button to connect, call {@link #prepare}
- *       and launch the returned intent, if non-null.</li>
- *   <li>When the application becomes prepared, start the service.</li>
- *   <li>Create a tunnel to the remote server and negotiate the network
- *       parameters for the VPN connection.</li>
- *   <li>Supply those parameters to a {@link Builder} and create a VPN
- *       interface by calling {@link Builder#establish}.</li>
- *   <li>Process and exchange packets between the tunnel and the returned
- *       file descriptor.</li>
- *   <li>When {@link #onRevoke} is invoked, close the file descriptor and
- *       shut down the tunnel gracefully.</li>
- * </ol>
- *
- * <p>Services extending this class need to be declared with an appropriate
- * permission and intent filter. Their access must be secured by
- * {@link android.Manifest.permission#BIND_VPN_SERVICE} permission, and
- * their intent filter must match {@link #SERVICE_INTERFACE} action. Here
- * is an example of declaring a VPN service in {@code AndroidManifest.xml}:
- * <pre>
- * &lt;service android:name=".ExampleVpnService"
- *         android:permission="android.permission.BIND_VPN_SERVICE"&gt;
- *     &lt;intent-filter&gt;
- *         &lt;action android:name="android.net.VpnService"/&gt;
- *     &lt;/intent-filter&gt;
- * &lt;/service&gt;</pre>
- *
- * <p> The Android system starts a VPN in the background by calling
- * {@link android.content.Context#startService startService()}. In Android 8.0
- * (API level 26) and higher, the system places VPN apps on the temporary
- * allowlist for a short period so the app can start in the background. The VPN
- * app must promote itself to the foreground after it's launched or the system
- * will shut down the app.
- *
- * <h3>Developer's guide</h3>
- *
- * <p>To learn more about developing VPN apps, read the
- * <a href="{@docRoot}guide/topics/connectivity/vpn">VPN developer's guide</a>.
- *
- * @see Builder
- */
-public class VpnService extends Service {
-
-    /**
-     * The action must be matched by the intent filter of this service. It also
-     * needs to require {@link android.Manifest.permission#BIND_VPN_SERVICE}
-     * permission so that other applications cannot abuse it.
-     */
-    public static final String SERVICE_INTERFACE = VpnConfig.SERVICE_INTERFACE;
-
-    /**
-     * Key for boolean meta-data field indicating whether this VpnService supports always-on mode.
-     *
-     * <p>For a VPN app targeting {@link android.os.Build.VERSION_CODES#N API 24} or above, Android
-     * provides users with the ability to set it as always-on, so that VPN connection is
-     * persisted after device reboot and app upgrade. Always-on VPN can also be enabled by device
-     * owner and profile owner apps through
-     * {@link DevicePolicyManager#setAlwaysOnVpnPackage}.
-     *
-     * <p>VPN apps not supporting this feature should opt out by adding this meta-data field to the
-     * {@code VpnService} component of {@code AndroidManifest.xml}. In case there is more than one
-     * {@code VpnService} component defined in {@code AndroidManifest.xml}, opting out any one of
-     * them will opt out the entire app. For example,
-     * <pre> {@code
-     * <service android:name=".ExampleVpnService"
-     *         android:permission="android.permission.BIND_VPN_SERVICE">
-     *     <intent-filter>
-     *         <action android:name="android.net.VpnService"/>
-     *     </intent-filter>
-     *     <meta-data android:name="android.net.VpnService.SUPPORTS_ALWAYS_ON"
-     *             android:value=false/>
-     * </service>
-     * } </pre>
-     *
-     * <p>This meta-data field defaults to {@code true} if absent. It will only have effect on
-     * {@link android.os.Build.VERSION_CODES#O_MR1} or higher.
-     */
-    public static final String SERVICE_META_DATA_SUPPORTS_ALWAYS_ON =
-            "android.net.VpnService.SUPPORTS_ALWAYS_ON";
-
-    /**
-     * Use IVpnManager since those methods are hidden and not available in VpnManager.
-     */
-    private static IVpnManager getService() {
-        return IVpnManager.Stub.asInterface(
-                ServiceManager.getService(Context.VPN_MANAGEMENT_SERVICE));
-    }
-
-    /**
-     * Prepare to establish a VPN connection. This method returns {@code null}
-     * if the VPN application is already prepared or if the user has previously
-     * consented to the VPN application. Otherwise, it returns an
-     * {@link Intent} to a system activity. The application should launch the
-     * activity using {@link Activity#startActivityForResult} to get itself
-     * prepared. The activity may pop up a dialog to require user action, and
-     * the result will come back via its {@link Activity#onActivityResult}.
-     * If the result is {@link Activity#RESULT_OK}, the application becomes
-     * prepared and is granted to use other methods in this class.
-     *
-     * <p>Only one application can be granted at the same time. The right
-     * is revoked when another application is granted. The application
-     * losing the right will be notified via its {@link #onRevoke}. Unless
-     * it becomes prepared again, subsequent calls to other methods in this
-     * class will fail.
-     *
-     * <p>The user may disable the VPN at any time while it is activated, in
-     * which case this method will return an intent the next time it is
-     * executed to obtain the user's consent again.
-     *
-     * @see #onRevoke
-     */
-    public static Intent prepare(Context context) {
-        try {
-            if (getService().prepareVpn(context.getPackageName(), null, context.getUserId())) {
-                return null;
-            }
-        } catch (RemoteException e) {
-            // ignore
-        }
-        return VpnConfig.getIntentForConfirmation();
-    }
-
-    /**
-     * Version of {@link #prepare(Context)} which does not require user consent.
-     *
-     * <p>Requires {@link android.Manifest.permission#CONTROL_VPN} and should generally not be
-     * used. Only acceptable in situations where user consent has been obtained through other means.
-     *
-     * <p>Once this is run, future preparations may be done with the standard prepare method as this
-     * will authorize the package to prepare the VPN without consent in the future.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresPermission(android.Manifest.permission.CONTROL_VPN)
-    public static void prepareAndAuthorize(Context context) {
-        IVpnManager vm = getService();
-        String packageName = context.getPackageName();
-        try {
-            // Only prepare if we're not already prepared.
-            int userId = context.getUserId();
-            if (!vm.prepareVpn(packageName, null, userId)) {
-                vm.prepareVpn(null, packageName, userId);
-            }
-            vm.setVpnPackageAuthorization(packageName, userId, VpnManager.TYPE_VPN_SERVICE);
-        } catch (RemoteException e) {
-            // ignore
-        }
-    }
-
-    /**
-     * Protect a socket from VPN connections. After protecting, data sent
-     * through this socket will go directly to the underlying network,
-     * so its traffic will not be forwarded through the VPN.
-     * This method is useful if some connections need to be kept
-     * outside of VPN. For example, a VPN tunnel should protect itself if its
-     * destination is covered by VPN routes. Otherwise its outgoing packets
-     * will be sent back to the VPN interface and cause an infinite loop. This
-     * method will fail if the application is not prepared or is revoked.
-     *
-     * <p class="note">The socket is NOT closed by this method.
-     *
-     * @return {@code true} on success.
-     */
-    public boolean protect(int socket) {
-        return NetworkUtils.protectFromVpn(socket);
-    }
-
-    /**
-     * Convenience method to protect a {@link Socket} from VPN connections.
-     *
-     * @return {@code true} on success.
-     * @see #protect(int)
-     */
-    public boolean protect(Socket socket) {
-        return protect(socket.getFileDescriptor$().getInt$());
-    }
-
-    /**
-     * Convenience method to protect a {@link DatagramSocket} from VPN
-     * connections.
-     *
-     * @return {@code true} on success.
-     * @see #protect(int)
-     */
-    public boolean protect(DatagramSocket socket) {
-        return protect(socket.getFileDescriptor$().getInt$());
-    }
-
-    /**
-     * Adds a network address to the VPN interface.
-     *
-     * Both IPv4 and IPv6 addresses are supported. The VPN must already be established. Fails if the
-     * address is already in use or cannot be assigned to the interface for any other reason.
-     *
-     * Adding an address implicitly allows traffic from that address family (i.e., IPv4 or IPv6) to
-     * be routed over the VPN. @see Builder#allowFamily
-     *
-     * @throws IllegalArgumentException if the address is invalid.
-     *
-     * @param address The IP address (IPv4 or IPv6) to assign to the VPN interface.
-     * @param prefixLength The prefix length of the address.
-     *
-     * @return {@code true} on success.
-     * @see Builder#addAddress
-     *
-     * @hide
-     */
-    public boolean addAddress(InetAddress address, int prefixLength) {
-        check(address, prefixLength);
-        try {
-            return getService().addVpnAddress(address.getHostAddress(), prefixLength);
-        } catch (RemoteException e) {
-            throw new IllegalStateException(e);
-        }
-    }
-
-    /**
-     * Removes a network address from the VPN interface.
-     *
-     * Both IPv4 and IPv6 addresses are supported. The VPN must already be established. Fails if the
-     * address is not assigned to the VPN interface, or if it is the only address assigned (thus
-     * cannot be removed), or if the address cannot be removed for any other reason.
-     *
-     * After removing an address, if there are no addresses, routes or DNS servers of a particular
-     * address family (i.e., IPv4 or IPv6) configured on the VPN, that <b>DOES NOT</b> block that
-     * family from being routed. In other words, once an address family has been allowed, it stays
-     * allowed for the rest of the VPN's session. @see Builder#allowFamily
-     *
-     * @throws IllegalArgumentException if the address is invalid.
-     *
-     * @param address The IP address (IPv4 or IPv6) to assign to the VPN interface.
-     * @param prefixLength The prefix length of the address.
-     *
-     * @return {@code true} on success.
-     *
-     * @hide
-     */
-    public boolean removeAddress(InetAddress address, int prefixLength) {
-        check(address, prefixLength);
-        try {
-            return getService().removeVpnAddress(address.getHostAddress(), prefixLength);
-        } catch (RemoteException e) {
-            throw new IllegalStateException(e);
-        }
-    }
-
-    /**
-     * Sets the underlying networks used by the VPN for its upstream connections.
-     *
-     * <p>Used by the system to know the actual networks that carry traffic for apps affected by
-     * this VPN in order to present this information to the user (e.g., via status bar icons).
-     *
-     * <p>This method only needs to be called if the VPN has explicitly bound its underlying
-     * communications channels &mdash; such as the socket(s) passed to {@link #protect(int)} &mdash;
-     * to a {@code Network} using APIs such as {@link Network#bindSocket(Socket)} or
-     * {@link Network#bindSocket(DatagramSocket)}. The VPN should call this method every time
-     * the set of {@code Network}s it is using changes.
-     *
-     * <p>{@code networks} is one of the following:
-     * <ul>
-     * <li><strong>a non-empty array</strong>: an array of one or more {@link Network}s, in
-     * decreasing preference order. For example, if this VPN uses both wifi and mobile (cellular)
-     * networks to carry app traffic, but prefers or uses wifi more than mobile, wifi should appear
-     * first in the array.</li>
-     * <li><strong>an empty array</strong>: a zero-element array, meaning that the VPN has no
-     * underlying network connection, and thus, app traffic will not be sent or received.</li>
-     * <li><strong>null</strong>: (default) signifies that the VPN uses whatever is the system's
-     * default network. I.e., it doesn't use the {@code bindSocket} or {@code bindDatagramSocket}
-     * APIs mentioned above to send traffic over specific channels.</li>
-     * </ul>
-     *
-     * <p>This call will succeed only if the VPN is currently established. For setting this value
-     * when the VPN has not yet been established, see {@link Builder#setUnderlyingNetworks}.
-     *
-     * @param networks An array of networks the VPN uses to tunnel traffic to/from its servers.
-     *
-     * @return {@code true} on success.
-     */
-    public boolean setUnderlyingNetworks(Network[] networks) {
-        try {
-            return getService().setUnderlyingNetworksForVpn(networks);
-        } catch (RemoteException e) {
-            throw new IllegalStateException(e);
-        }
-    }
-
-    /**
-     * Returns whether the service is running in always-on VPN mode. In this mode the system ensures
-     * that the service is always running by restarting it when necessary, e.g. after reboot.
-     *
-     * @see DevicePolicyManager#setAlwaysOnVpnPackage(ComponentName, String, boolean, Set)
-     */
-    public final boolean isAlwaysOn() {
-        try {
-            return getService().isCallerCurrentAlwaysOnVpnApp();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Returns whether the service is running in always-on VPN lockdown mode. In this mode the
-     * system ensures that the service is always running and that the apps aren't allowed to bypass
-     * the VPN.
-     *
-     * @see DevicePolicyManager#setAlwaysOnVpnPackage(ComponentName, String, boolean, Set)
-     */
-    public final boolean isLockdownEnabled() {
-        try {
-            return getService().isCallerCurrentAlwaysOnVpnLockdownApp();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Return the communication interface to the service. This method returns
-     * {@code null} on {@link Intent}s other than {@link #SERVICE_INTERFACE}
-     * action. Applications overriding this method must identify the intent
-     * and return the corresponding interface accordingly.
-     *
-     * @see Service#onBind
-     */
-    @Override
-    public IBinder onBind(Intent intent) {
-        if (intent != null && SERVICE_INTERFACE.equals(intent.getAction())) {
-            return new Callback();
-        }
-        return null;
-    }
-
-    /**
-     * Invoked when the application is revoked. At this moment, the VPN
-     * interface is already deactivated by the system. The application should
-     * close the file descriptor and shut down gracefully. The default
-     * implementation of this method is calling {@link Service#stopSelf()}.
-     *
-     * <p class="note">Calls to this method may not happen on the main thread
-     * of the process.
-     *
-     * @see #prepare
-     */
-    public void onRevoke() {
-        stopSelf();
-    }
-
-    /**
-     * Use raw Binder instead of AIDL since now there is only one usage.
-     */
-    private class Callback extends Binder {
-        @Override
-        protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) {
-            if (code == IBinder.LAST_CALL_TRANSACTION) {
-                onRevoke();
-                return true;
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Private method to validate address and prefixLength.
-     */
-    private static void check(InetAddress address, int prefixLength) {
-        if (address.isLoopbackAddress()) {
-            throw new IllegalArgumentException("Bad address");
-        }
-        if (address instanceof Inet4Address) {
-            if (prefixLength < 0 || prefixLength > 32) {
-                throw new IllegalArgumentException("Bad prefixLength");
-            }
-        } else if (address instanceof Inet6Address) {
-            if (prefixLength < 0 || prefixLength > 128) {
-                throw new IllegalArgumentException("Bad prefixLength");
-            }
-        } else {
-            throw new IllegalArgumentException("Unsupported family");
-        }
-    }
-
-    /**
-     * Helper class to create a VPN interface. This class should be always
-     * used within the scope of the outer {@link VpnService}.
-     *
-     * @see VpnService
-     */
-    public class Builder {
-
-        private final VpnConfig mConfig = new VpnConfig();
-        @UnsupportedAppUsage
-        private final List<LinkAddress> mAddresses = new ArrayList<LinkAddress>();
-        @UnsupportedAppUsage
-        private final List<RouteInfo> mRoutes = new ArrayList<RouteInfo>();
-
-        public Builder() {
-            mConfig.user = VpnService.this.getClass().getName();
-        }
-
-        /**
-         * Set the name of this session. It will be displayed in
-         * system-managed dialogs and notifications. This is recommended
-         * not required.
-         */
-        @NonNull
-        public Builder setSession(@NonNull String session) {
-            mConfig.session = session;
-            return this;
-        }
-
-        /**
-         * Set the {@link PendingIntent} to an activity for users to
-         * configure the VPN connection. If it is not set, the button
-         * to configure will not be shown in system-managed dialogs.
-         */
-        @NonNull
-        public Builder setConfigureIntent(@NonNull PendingIntent intent) {
-            mConfig.configureIntent = intent;
-            return this;
-        }
-
-        /**
-         * Set the maximum transmission unit (MTU) of the VPN interface. If
-         * it is not set, the default value in the operating system will be
-         * used.
-         *
-         * @throws IllegalArgumentException if the value is not positive.
-         */
-        @NonNull
-        public Builder setMtu(int mtu) {
-            if (mtu <= 0) {
-                throw new IllegalArgumentException("Bad mtu");
-            }
-            mConfig.mtu = mtu;
-            return this;
-        }
-
-        /**
-         * Sets an HTTP proxy for the VPN network. This proxy is only a recommendation
-         * and it is possible that some apps will ignore it.
-         */
-        @NonNull
-        public Builder setHttpProxy(@NonNull ProxyInfo proxyInfo) {
-            mConfig.proxyInfo = proxyInfo;
-            return this;
-        }
-
-        /**
-         * Add a network address to the VPN interface. Both IPv4 and IPv6
-         * addresses are supported. At least one address must be set before
-         * calling {@link #establish}.
-         *
-         * Adding an address implicitly allows traffic from that address family
-         * (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily
-         *
-         * @throws IllegalArgumentException if the address is invalid.
-         */
-        @NonNull
-        public Builder addAddress(@NonNull InetAddress address, int prefixLength) {
-            check(address, prefixLength);
-
-            if (address.isAnyLocalAddress()) {
-                throw new IllegalArgumentException("Bad address");
-            }
-            mAddresses.add(new LinkAddress(address, prefixLength));
-            mConfig.updateAllowedFamilies(address);
-            return this;
-        }
-
-        /**
-         * Convenience method to add a network address to the VPN interface
-         * using a numeric address string. See {@link InetAddress} for the
-         * definitions of numeric address formats.
-         *
-         * Adding an address implicitly allows traffic from that address family
-         * (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily
-         *
-         * @throws IllegalArgumentException if the address is invalid.
-         * @see #addAddress(InetAddress, int)
-         */
-        @NonNull
-        public Builder addAddress(@NonNull String address, int prefixLength) {
-            return addAddress(InetAddress.parseNumericAddress(address), prefixLength);
-        }
-
-        /**
-         * Add a network route to the VPN interface. Both IPv4 and IPv6
-         * routes are supported.
-         *
-         * Adding a route implicitly allows traffic from that address family
-         * (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily
-         *
-         * @throws IllegalArgumentException if the route is invalid.
-         */
-        @NonNull
-        public Builder addRoute(@NonNull InetAddress address, int prefixLength) {
-            check(address, prefixLength);
-
-            int offset = prefixLength / 8;
-            byte[] bytes = address.getAddress();
-            if (offset < bytes.length) {
-                for (bytes[offset] <<= prefixLength % 8; offset < bytes.length; ++offset) {
-                    if (bytes[offset] != 0) {
-                        throw new IllegalArgumentException("Bad address");
-                    }
-                }
-            }
-            mRoutes.add(new RouteInfo(new IpPrefix(address, prefixLength), null));
-            mConfig.updateAllowedFamilies(address);
-            return this;
-        }
-
-        /**
-         * Convenience method to add a network route to the VPN interface
-         * using a numeric address string. See {@link InetAddress} for the
-         * definitions of numeric address formats.
-         *
-         * Adding a route implicitly allows traffic from that address family
-         * (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily
-         *
-         * @throws IllegalArgumentException if the route is invalid.
-         * @see #addRoute(InetAddress, int)
-         */
-        @NonNull
-        public Builder addRoute(@NonNull String address, int prefixLength) {
-            return addRoute(InetAddress.parseNumericAddress(address), prefixLength);
-        }
-
-        /**
-         * Add a DNS server to the VPN connection. Both IPv4 and IPv6
-         * addresses are supported. If none is set, the DNS servers of
-         * the default network will be used.
-         *
-         * Adding a server implicitly allows traffic from that address family
-         * (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily
-         *
-         * @throws IllegalArgumentException if the address is invalid.
-         */
-        @NonNull
-        public Builder addDnsServer(@NonNull InetAddress address) {
-            if (address.isLoopbackAddress() || address.isAnyLocalAddress()) {
-                throw new IllegalArgumentException("Bad address");
-            }
-            if (mConfig.dnsServers == null) {
-                mConfig.dnsServers = new ArrayList<String>();
-            }
-            mConfig.dnsServers.add(address.getHostAddress());
-            return this;
-        }
-
-        /**
-         * Convenience method to add a DNS server to the VPN connection
-         * using a numeric address string. See {@link InetAddress} for the
-         * definitions of numeric address formats.
-         *
-         * Adding a server implicitly allows traffic from that address family
-         * (i.e., IPv4 or IPv6) to be routed over the VPN. @see #allowFamily
-         *
-         * @throws IllegalArgumentException if the address is invalid.
-         * @see #addDnsServer(InetAddress)
-         */
-        @NonNull
-        public Builder addDnsServer(@NonNull String address) {
-            return addDnsServer(InetAddress.parseNumericAddress(address));
-        }
-
-        /**
-         * Add a search domain to the DNS resolver.
-         */
-        @NonNull
-        public Builder addSearchDomain(@NonNull String domain) {
-            if (mConfig.searchDomains == null) {
-                mConfig.searchDomains = new ArrayList<String>();
-            }
-            mConfig.searchDomains.add(domain);
-            return this;
-        }
-
-        /**
-         * Allows traffic from the specified address family.
-         *
-         * By default, if no address, route or DNS server of a specific family (IPv4 or IPv6) is
-         * added to this VPN, then all outgoing traffic of that family is blocked. If any address,
-         * route or DNS server is added, that family is allowed.
-         *
-         * This method allows an address family to be unblocked even without adding an address,
-         * route or DNS server of that family. Traffic of that family will then typically
-         * fall-through to the underlying network if it's supported.
-         *
-         * {@code family} must be either {@code AF_INET} (for IPv4) or {@code AF_INET6} (for IPv6).
-         * {@link IllegalArgumentException} is thrown if it's neither.
-         *
-         * @param family The address family ({@code AF_INET} or {@code AF_INET6}) to allow.
-         *
-         * @return this {@link Builder} object to facilitate chaining of method calls.
-         */
-        @NonNull
-        public Builder allowFamily(int family) {
-            if (family == AF_INET) {
-                mConfig.allowIPv4 = true;
-            } else if (family == AF_INET6) {
-                mConfig.allowIPv6 = true;
-            } else {
-                throw new IllegalArgumentException(family + " is neither " + AF_INET + " nor " +
-                        AF_INET6);
-            }
-            return this;
-        }
-
-        private void verifyApp(String packageName) throws PackageManager.NameNotFoundException {
-            IPackageManager pm = IPackageManager.Stub.asInterface(
-                    ServiceManager.getService("package"));
-            try {
-                pm.getApplicationInfo(packageName, 0, UserHandle.getCallingUserId());
-            } catch (RemoteException e) {
-                throw new IllegalStateException(e);
-            }
-        }
-
-        /**
-         * Adds an application that's allowed to access the VPN connection.
-         *
-         * If this method is called at least once, only applications added through this method (and
-         * no others) are allowed access. Else (if this method is never called), all applications
-         * are allowed by default.  If some applications are added, other, un-added applications
-         * will use networking as if the VPN wasn't running.
-         *
-         * A {@link Builder} may have only a set of allowed applications OR a set of disallowed
-         * ones, but not both. Calling this method after {@link #addDisallowedApplication} has
-         * already been called, or vice versa, will throw an {@link UnsupportedOperationException}.
-         *
-         * {@code packageName} must be the canonical name of a currently installed application.
-         * {@link PackageManager.NameNotFoundException} is thrown if there's no such application.
-         *
-         * @throws PackageManager.NameNotFoundException If the application isn't installed.
-         *
-         * @param packageName The full name (e.g.: "com.google.apps.contacts") of an application.
-         *
-         * @return this {@link Builder} object to facilitate chaining method calls.
-         */
-        @NonNull
-        public Builder addAllowedApplication(@NonNull String packageName)
-                throws PackageManager.NameNotFoundException {
-            if (mConfig.disallowedApplications != null) {
-                throw new UnsupportedOperationException("addDisallowedApplication already called");
-            }
-            verifyApp(packageName);
-            if (mConfig.allowedApplications == null) {
-                mConfig.allowedApplications = new ArrayList<String>();
-            }
-            mConfig.allowedApplications.add(packageName);
-            return this;
-        }
-
-        /**
-         * Adds an application that's denied access to the VPN connection.
-         *
-         * By default, all applications are allowed access, except for those denied through this
-         * method.  Denied applications will use networking as if the VPN wasn't running.
-         *
-         * A {@link Builder} may have only a set of allowed applications OR a set of disallowed
-         * ones, but not both. Calling this method after {@link #addAllowedApplication} has already
-         * been called, or vice versa, will throw an {@link UnsupportedOperationException}.
-         *
-         * {@code packageName} must be the canonical name of a currently installed application.
-         * {@link PackageManager.NameNotFoundException} is thrown if there's no such application.
-         *
-         * @throws PackageManager.NameNotFoundException If the application isn't installed.
-         *
-         * @param packageName The full name (e.g.: "com.google.apps.contacts") of an application.
-         *
-         * @return this {@link Builder} object to facilitate chaining method calls.
-         */
-        @NonNull
-        public Builder addDisallowedApplication(@NonNull String packageName)
-                throws PackageManager.NameNotFoundException {
-            if (mConfig.allowedApplications != null) {
-                throw new UnsupportedOperationException("addAllowedApplication already called");
-            }
-            verifyApp(packageName);
-            if (mConfig.disallowedApplications == null) {
-                mConfig.disallowedApplications = new ArrayList<String>();
-            }
-            mConfig.disallowedApplications.add(packageName);
-            return this;
-        }
-
-        /**
-         * Allows all apps to bypass this VPN connection.
-         *
-         * By default, all traffic from apps is forwarded through the VPN interface and it is not
-         * possible for apps to side-step the VPN. If this method is called, apps may use methods
-         * such as {@link ConnectivityManager#bindProcessToNetwork} to instead send/receive
-         * directly over the underlying network or any other network they have permissions for.
-         *
-         * @return this {@link Builder} object to facilitate chaining of method calls.
-         */
-        @NonNull
-        public Builder allowBypass() {
-            mConfig.allowBypass = true;
-            return this;
-        }
-
-        /**
-         * Sets the VPN interface's file descriptor to be in blocking/non-blocking mode.
-         *
-         * By default, the file descriptor returned by {@link #establish} is non-blocking.
-         *
-         * @param blocking True to put the descriptor into blocking mode; false for non-blocking.
-         *
-         * @return this {@link Builder} object to facilitate chaining method calls.
-         */
-        @NonNull
-        public Builder setBlocking(boolean blocking) {
-            mConfig.blocking = blocking;
-            return this;
-        }
-
-        /**
-         * Sets the underlying networks used by the VPN for its upstream connections.
-         *
-         * @see VpnService#setUnderlyingNetworks
-         *
-         * @param networks An array of networks the VPN uses to tunnel traffic to/from its servers.
-         *
-         * @return this {@link Builder} object to facilitate chaining method calls.
-         */
-        @NonNull
-        public Builder setUnderlyingNetworks(@Nullable Network[] networks) {
-            mConfig.underlyingNetworks = networks != null ? networks.clone() : null;
-            return this;
-        }
-
-        /**
-         * Marks the VPN network as metered. A VPN network is classified as metered when the user is
-         * sensitive to heavy data usage due to monetary costs and/or data limitations. In such
-         * cases, you should set this to {@code true} so that apps on the system can avoid doing
-         * large data transfers. Otherwise, set this to {@code false}. Doing so would cause VPN
-         * network to inherit its meteredness from its underlying networks.
-         *
-         * <p>VPN apps targeting {@link android.os.Build.VERSION_CODES#Q} or above will be
-         * considered metered by default.
-         *
-         * @param isMetered {@code true} if VPN network should be treated as metered regardless of
-         *     underlying network meteredness
-         * @return this {@link Builder} object to facilitate chaining method calls
-         * @see #setUnderlyingNetworks(Network[])
-         * @see ConnectivityManager#isActiveNetworkMetered()
-         */
-        @NonNull
-        public Builder setMetered(boolean isMetered) {
-            mConfig.isMetered = isMetered;
-            return this;
-        }
-
-        /**
-         * Create a VPN interface using the parameters supplied to this
-         * builder. The interface works on IP packets, and a file descriptor
-         * is returned for the application to access them. Each read
-         * retrieves an outgoing packet which was routed to the interface.
-         * Each write injects an incoming packet just like it was received
-         * from the interface. The file descriptor is put into non-blocking
-         * mode by default to avoid blocking Java threads. To use the file
-         * descriptor completely in native space, see
-         * {@link ParcelFileDescriptor#detachFd()}. The application MUST
-         * close the file descriptor when the VPN connection is terminated.
-         * The VPN interface will be removed and the network will be
-         * restored by the system automatically.
-         *
-         * <p>To avoid conflicts, there can be only one active VPN interface
-         * at the same time. Usually network parameters are never changed
-         * during the lifetime of a VPN connection. It is also common for an
-         * application to create a new file descriptor after closing the
-         * previous one. However, it is rare but not impossible to have two
-         * interfaces while performing a seamless handover. In this case, the
-         * old interface will be deactivated when the new one is created
-         * successfully. Both file descriptors are valid but now outgoing
-         * packets will be routed to the new interface. Therefore, after
-         * draining the old file descriptor, the application MUST close it
-         * and start using the new file descriptor. If the new interface
-         * cannot be created, the existing interface and its file descriptor
-         * remain untouched.
-         *
-         * <p>An exception will be thrown if the interface cannot be created
-         * for any reason. However, this method returns {@code null} if the
-         * application is not prepared or is revoked. This helps solve
-         * possible race conditions between other VPN applications.
-         *
-         * @return {@link ParcelFileDescriptor} of the VPN interface, or
-         *         {@code null} if the application is not prepared.
-         * @throws IllegalArgumentException if a parameter is not accepted
-         *         by the operating system.
-         * @throws IllegalStateException if a parameter cannot be applied
-         *         by the operating system.
-         * @throws SecurityException if the service is not properly declared
-         *         in {@code AndroidManifest.xml}.
-         * @see VpnService
-         */
-        @Nullable
-        public ParcelFileDescriptor establish() {
-            mConfig.addresses = mAddresses;
-            mConfig.routes = mRoutes;
-
-            try {
-                return getService().establishVpn(mConfig);
-            } catch (RemoteException e) {
-                throw new IllegalStateException(e);
-            }
-        }
-    }
-}
diff --git a/service/Android.bp b/service/Android.bp
index 8fc3181..ed1716f 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -25,7 +25,6 @@
     ],
     srcs: [
         "jni/com_android_server_TestNetworkService.cpp",
-        "jni/com_android_server_connectivity_Vpn.cpp",
         "jni/onload.cpp",
     ],
     shared_libs: [
diff --git a/service/jni/com_android_server_connectivity_Vpn.cpp b/service/jni/com_android_server_connectivity_Vpn.cpp
deleted file mode 100644
index ea5e718..0000000
--- a/service/jni/com_android_server_connectivity_Vpn.cpp
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_NDEBUG 0
-
-#define LOG_TAG "VpnJni"
-
-#include <arpa/inet.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <linux/if.h>
-#include <linux/if_tun.h>
-#include <linux/route.h>
-#include <linux/ipv6_route.h>
-#include <netinet/in.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <log/log.h>
-#include <android/log.h>
-
-#include "netutils/ifc.h"
-
-#include "jni.h"
-#include <nativehelper/JNIHelp.h>
-
-namespace android
-{
-
-static int inet4 = -1;
-static int inet6 = -1;
-
-static inline in_addr_t *as_in_addr(sockaddr *sa) {
-    return &((sockaddr_in *)sa)->sin_addr.s_addr;
-}
-
-//------------------------------------------------------------------------------
-
-#define SYSTEM_ERROR (-1)
-#define BAD_ARGUMENT (-2)
-
-static int create_interface(int mtu)
-{
-    int tun = open("/dev/tun", O_RDWR | O_NONBLOCK | O_CLOEXEC);
-
-    ifreq ifr4;
-    memset(&ifr4, 0, sizeof(ifr4));
-
-    // Allocate interface.
-    ifr4.ifr_flags = IFF_TUN | IFF_NO_PI;
-    if (ioctl(tun, TUNSETIFF, &ifr4)) {
-        ALOGE("Cannot allocate TUN: %s", strerror(errno));
-        goto error;
-    }
-
-    // Activate interface.
-    ifr4.ifr_flags = IFF_UP;
-    if (ioctl(inet4, SIOCSIFFLAGS, &ifr4)) {
-        ALOGE("Cannot activate %s: %s", ifr4.ifr_name, strerror(errno));
-        goto error;
-    }
-
-    // Set MTU if it is specified.
-    ifr4.ifr_mtu = mtu;
-    if (mtu > 0 && ioctl(inet4, SIOCSIFMTU, &ifr4)) {
-        ALOGE("Cannot set MTU on %s: %s", ifr4.ifr_name, strerror(errno));
-        goto error;
-    }
-
-    return tun;
-
-error:
-    close(tun);
-    return SYSTEM_ERROR;
-}
-
-static int get_interface_name(char *name, int tun)
-{
-    ifreq ifr4;
-    if (ioctl(tun, TUNGETIFF, &ifr4)) {
-        ALOGE("Cannot get interface name: %s", strerror(errno));
-        return SYSTEM_ERROR;
-    }
-    strncpy(name, ifr4.ifr_name, IFNAMSIZ);
-    return 0;
-}
-
-static int get_interface_index(const char *name)
-{
-    ifreq ifr4;
-    strncpy(ifr4.ifr_name, name, IFNAMSIZ);
-    if (ioctl(inet4, SIOGIFINDEX, &ifr4)) {
-        ALOGE("Cannot get index of %s: %s", name, strerror(errno));
-        return SYSTEM_ERROR;
-    }
-    return ifr4.ifr_ifindex;
-}
-
-static int set_addresses(const char *name, const char *addresses)
-{
-    int index = get_interface_index(name);
-    if (index < 0) {
-        return index;
-    }
-
-    ifreq ifr4;
-    memset(&ifr4, 0, sizeof(ifr4));
-    strncpy(ifr4.ifr_name, name, IFNAMSIZ);
-    ifr4.ifr_addr.sa_family = AF_INET;
-    ifr4.ifr_netmask.sa_family = AF_INET;
-
-    in6_ifreq ifr6;
-    memset(&ifr6, 0, sizeof(ifr6));
-    ifr6.ifr6_ifindex = index;
-
-    char address[65];
-    int prefix;
-    int chars;
-    int count = 0;
-
-    while (sscanf(addresses, " %64[^/]/%d %n", address, &prefix, &chars) == 2) {
-        addresses += chars;
-
-        if (strchr(address, ':')) {
-            // Add an IPv6 address.
-            if (inet_pton(AF_INET6, address, &ifr6.ifr6_addr) != 1 ||
-                    prefix < 0 || prefix > 128) {
-                count = BAD_ARGUMENT;
-                break;
-            }
-
-            ifr6.ifr6_prefixlen = prefix;
-            if (ioctl(inet6, SIOCSIFADDR, &ifr6)) {
-                count = (errno == EINVAL) ? BAD_ARGUMENT : SYSTEM_ERROR;
-                break;
-            }
-        } else {
-            // Add an IPv4 address.
-            if (inet_pton(AF_INET, address, as_in_addr(&ifr4.ifr_addr)) != 1 ||
-                    prefix < 0 || prefix > 32) {
-                count = BAD_ARGUMENT;
-                break;
-            }
-
-            if (count) {
-                snprintf(ifr4.ifr_name, sizeof(ifr4.ifr_name), "%s:%d", name, count);
-            }
-            if (ioctl(inet4, SIOCSIFADDR, &ifr4)) {
-                count = (errno == EINVAL) ? BAD_ARGUMENT : SYSTEM_ERROR;
-                break;
-            }
-
-            in_addr_t mask = prefix ? (~0 << (32 - prefix)) : 0;
-            *as_in_addr(&ifr4.ifr_netmask) = htonl(mask);
-            if (ioctl(inet4, SIOCSIFNETMASK, &ifr4)) {
-                count = (errno == EINVAL) ? BAD_ARGUMENT : SYSTEM_ERROR;
-                break;
-            }
-        }
-        ALOGD("Address added on %s: %s/%d", name, address, prefix);
-        ++count;
-    }
-
-    if (count == BAD_ARGUMENT) {
-        ALOGE("Invalid address: %s/%d", address, prefix);
-    } else if (count == SYSTEM_ERROR) {
-        ALOGE("Cannot add address: %s/%d: %s", address, prefix, strerror(errno));
-    } else if (*addresses) {
-        ALOGE("Invalid address: %s", addresses);
-        count = BAD_ARGUMENT;
-    }
-
-    return count;
-}
-
-static int reset_interface(const char *name)
-{
-    ifreq ifr4;
-    strncpy(ifr4.ifr_name, name, IFNAMSIZ);
-    ifr4.ifr_flags = 0;
-
-    if (ioctl(inet4, SIOCSIFFLAGS, &ifr4) && errno != ENODEV) {
-        ALOGE("Cannot reset %s: %s", name, strerror(errno));
-        return SYSTEM_ERROR;
-    }
-    return 0;
-}
-
-static int check_interface(const char *name)
-{
-    ifreq ifr4;
-    strncpy(ifr4.ifr_name, name, IFNAMSIZ);
-    ifr4.ifr_flags = 0;
-
-    if (ioctl(inet4, SIOCGIFFLAGS, &ifr4) && errno != ENODEV) {
-        ALOGE("Cannot check %s: %s", name, strerror(errno));
-    }
-    return ifr4.ifr_flags;
-}
-
-static bool modifyAddress(JNIEnv *env, jobject thiz, jstring jName, jstring jAddress,
-                          jint jPrefixLength, bool add)
-{
-    int error = SYSTEM_ERROR;
-    const char *name = jName ? env->GetStringUTFChars(jName, NULL) : NULL;
-    const char *address = jAddress ? env->GetStringUTFChars(jAddress, NULL) : NULL;
-
-    if (!name) {
-        jniThrowNullPointerException(env, "name");
-    } else if (!address) {
-        jniThrowNullPointerException(env, "address");
-    } else {
-        if (add) {
-            if ((error = ifc_add_address(name, address, jPrefixLength)) != 0) {
-                ALOGE("Cannot add address %s/%d on interface %s (%s)", address, jPrefixLength, name,
-                      strerror(-error));
-            }
-        } else {
-            if ((error = ifc_del_address(name, address, jPrefixLength)) != 0) {
-                ALOGE("Cannot del address %s/%d on interface %s (%s)", address, jPrefixLength, name,
-                      strerror(-error));
-            }
-        }
-    }
-
-    if (name) {
-        env->ReleaseStringUTFChars(jName, name);
-    }
-    if (address) {
-        env->ReleaseStringUTFChars(jAddress, address);
-    }
-    return !error;
-}
-
-//------------------------------------------------------------------------------
-
-static void throwException(JNIEnv *env, int error, const char *message)
-{
-    if (error == SYSTEM_ERROR) {
-        jniThrowException(env, "java/lang/IllegalStateException", message);
-    } else {
-        jniThrowException(env, "java/lang/IllegalArgumentException", message);
-    }
-}
-
-static jint create(JNIEnv *env, jobject /* thiz */, jint mtu)
-{
-    int tun = create_interface(mtu);
-    if (tun < 0) {
-        throwException(env, tun, "Cannot create interface");
-        return -1;
-    }
-    return tun;
-}
-
-static jstring getName(JNIEnv *env, jobject /* thiz */, jint tun)
-{
-    char name[IFNAMSIZ];
-    if (get_interface_name(name, tun) < 0) {
-        throwException(env, SYSTEM_ERROR, "Cannot get interface name");
-        return NULL;
-    }
-    return env->NewStringUTF(name);
-}
-
-static jint setAddresses(JNIEnv *env, jobject /* thiz */, jstring jName,
-        jstring jAddresses)
-{
-    const char *name = NULL;
-    const char *addresses = NULL;
-    int count = -1;
-
-    name = jName ? env->GetStringUTFChars(jName, NULL) : NULL;
-    if (!name) {
-        jniThrowNullPointerException(env, "name");
-        goto error;
-    }
-    addresses = jAddresses ? env->GetStringUTFChars(jAddresses, NULL) : NULL;
-    if (!addresses) {
-        jniThrowNullPointerException(env, "addresses");
-        goto error;
-    }
-    count = set_addresses(name, addresses);
-    if (count < 0) {
-        throwException(env, count, "Cannot set address");
-        count = -1;
-    }
-
-error:
-    if (name) {
-        env->ReleaseStringUTFChars(jName, name);
-    }
-    if (addresses) {
-        env->ReleaseStringUTFChars(jAddresses, addresses);
-    }
-    return count;
-}
-
-static void reset(JNIEnv *env, jobject /* thiz */, jstring jName)
-{
-    const char *name = jName ? env->GetStringUTFChars(jName, NULL) : NULL;
-    if (!name) {
-        jniThrowNullPointerException(env, "name");
-        return;
-    }
-    if (reset_interface(name) < 0) {
-        throwException(env, SYSTEM_ERROR, "Cannot reset interface");
-    }
-    env->ReleaseStringUTFChars(jName, name);
-}
-
-static jint check(JNIEnv *env, jobject /* thiz */, jstring jName)
-{
-    const char *name = jName ? env->GetStringUTFChars(jName, NULL) : NULL;
-    if (!name) {
-        jniThrowNullPointerException(env, "name");
-        return 0;
-    }
-    int flags = check_interface(name);
-    env->ReleaseStringUTFChars(jName, name);
-    return flags;
-}
-
-static bool addAddress(JNIEnv *env, jobject thiz, jstring jName, jstring jAddress,
-                       jint jPrefixLength)
-{
-    return modifyAddress(env, thiz, jName, jAddress, jPrefixLength, true);
-}
-
-static bool delAddress(JNIEnv *env, jobject thiz, jstring jName, jstring jAddress,
-                       jint jPrefixLength)
-{
-    return modifyAddress(env, thiz, jName, jAddress, jPrefixLength, false);
-}
-
-//------------------------------------------------------------------------------
-
-static const JNINativeMethod gMethods[] = {
-    {"jniCreate", "(I)I", (void *)create},
-    {"jniGetName", "(I)Ljava/lang/String;", (void *)getName},
-    {"jniSetAddresses", "(Ljava/lang/String;Ljava/lang/String;)I", (void *)setAddresses},
-    {"jniReset", "(Ljava/lang/String;)V", (void *)reset},
-    {"jniCheck", "(Ljava/lang/String;)I", (void *)check},
-    {"jniAddAddress", "(Ljava/lang/String;Ljava/lang/String;I)Z", (void *)addAddress},
-    {"jniDelAddress", "(Ljava/lang/String;Ljava/lang/String;I)Z", (void *)delAddress},
-};
-
-int register_android_server_connectivity_Vpn(JNIEnv *env)
-{
-    if (inet4 == -1) {
-        inet4 = socket(AF_INET, SOCK_DGRAM, 0);
-    }
-    if (inet6 == -1) {
-        inet6 = socket(AF_INET6, SOCK_DGRAM, 0);
-    }
-    return jniRegisterNativeMethods(env, "com/android/server/connectivity/Vpn",
-            gMethods, NELEM(gMethods));
-}
-
-};
diff --git a/service/jni/onload.cpp b/service/jni/onload.cpp
index 3afcb0e..0012879 100644
--- a/service/jni/onload.cpp
+++ b/service/jni/onload.cpp
@@ -19,7 +19,6 @@
 
 namespace android {
 
-int register_android_server_connectivity_Vpn(JNIEnv* env);
 int register_android_server_TestNetworkService(JNIEnv* env);
 
 extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
@@ -29,12 +28,11 @@
         return JNI_ERR;
     }
 
-    if (register_android_server_connectivity_Vpn(env) < 0
-        || register_android_server_TestNetworkService(env) < 0) {
+    if (register_android_server_TestNetworkService(env) < 0) {
         return JNI_ERR;
     }
 
     return JNI_VERSION_1_6;
 }
 
-};
\ No newline at end of file
+};
