Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 50b44435 authored by Benedict Wong's avatar Benedict Wong
Browse files

Add VpnManger API surface

This change adds the VpnManager, which will be used by apps to install
profiles for all platform VPN types (currently only IKEv2).

Bug: 143325939
Test: Compiles, FrameworksNetTests passing.
Change-Id: I57f854d0a5b18358f3541c24ca0cd8aed03fd7a1
parent feb69c13
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -9883,6 +9883,7 @@ package android.content {
    field public static final String USB_SERVICE = "usb";
    field public static final String USER_SERVICE = "user";
    field public static final String VIBRATOR_SERVICE = "vibrator";
    field public static final String VPN_MANAGEMENT_SERVICE = "vpn_management";
    field public static final String WALLPAPER_SERVICE = "wallpaper";
    field public static final String WIFI_AWARE_SERVICE = "wifiaware";
    field public static final String WIFI_P2P_SERVICE = "wifip2p";
@@ -29529,6 +29530,13 @@ package android.net {
    method public String sanitize(String);
  }
  public class VpnManager {
    method public void deleteProvisionedVpnProfile();
    method @Nullable public android.content.Intent provisionVpnProfile(@NonNull android.net.PlatformVpnProfile);
    method public void startProvisionedVpnProfile();
    method public void stopProvisionedVpnProfile();
  }
  public class VpnService extends android.app.Service {
    ctor public VpnService();
    method public final boolean isAlwaysOn();
+10 −0
Original line number Diff line number Diff line
@@ -113,6 +113,7 @@ import android.net.NetworkScoreManager;
import android.net.NetworkWatchlistManager;
import android.net.TestNetworkManager;
import android.net.TetheringManager;
import android.net.VpnManager;
import android.net.lowpan.ILowpanManager;
import android.net.lowpan.LowpanManager;
import android.net.nsd.INsdManager;
@@ -370,6 +371,15 @@ final class SystemServiceRegistry {
                return new IpSecManager(ctx, service);
            }});

        registerService(Context.VPN_MANAGEMENT_SERVICE, VpnManager.class,
                new CachedServiceFetcher<VpnManager>() {
            @Override
            public VpnManager createService(ContextImpl ctx) throws ServiceNotFoundException {
                IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
                IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
                return new VpnManager(ctx, service);
            }});

        registerService(Context.CONNECTIVITY_DIAGNOSTICS_SERVICE,
                ConnectivityDiagnosticsManager.class,
                new CachedServiceFetcher<ConnectivityDiagnosticsManager>() {
+9 −0
Original line number Diff line number Diff line
@@ -3296,6 +3296,7 @@ public abstract class Context {
            CONNECTIVITY_SERVICE,
            //@hide: IP_MEMORY_STORE_SERVICE,
            IPSEC_SERVICE,
            VPN_MANAGEMENT_SERVICE,
            TEST_NETWORK_SERVICE,
            //@hide: UPDATE_LOCK_SERVICE,
            //@hide: NETWORKMANAGEMENT_SERVICE,
@@ -3879,6 +3880,14 @@ public abstract class Context {
     */
    public static final String IPSEC_SERVICE = "ipsec";

    /**
     * Use with {@link #getSystemService(String)} to retrieve a {@link android.net.VpnManager} to
     * manage profiles for the platform built-in VPN.
     *
     * @see #getSystemService(String)
     */
    public static final String VPN_MANAGEMENT_SERVICE = "vpn_management";

    /**
     * Use with {@link #getSystemService(String)} to retrieve a {@link
     * android.net.ConnectivityDiagnosticsManager} for performing network connectivity diagnostics
+88 −0
Original line number Diff line number Diff line
/*
 * 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.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.content.Intent;

/**
 * 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 {
    @NonNull private final Context mContext;
    @NonNull private final IConnectivityManager mService;

    /**
     * Create an instance of the VpnManger 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 IConnectivityManager service) {
        mContext = checkNotNull(ctx, "missing Context");
        mService = checkNotNull(service, "missing IConnectivityManager");
    }

    /**
     * Install a VpnProfile configuration keyed on the calling app's package name.
     *
     * @param profile the PlatformVpnProfile provided by this package. Will override any previous
     *     PlatformVpnProfile stored for this package.
     * @return an intent to request user consent if needed (null otherwise).
     */
    @Nullable
    public Intent provisionVpnProfile(@NonNull PlatformVpnProfile profile) {
        throw new UnsupportedOperationException("Not yet implemented");
    }

    /** Delete the VPN profile configuration that was provisioned by the calling app */
    public void deleteProvisionedVpnProfile() {
        throw new UnsupportedOperationException("Not yet implemented");
    }

    /**
     * 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() {
        throw new UnsupportedOperationException("Not yet implemented");
    }

    /** Tear down the VPN provided by the calling app (if any) */
    public void stopProvisionedVpnProfile() {
        throw new UnsupportedOperationException("Not yet implemented");
    }
}
+83 −0
Original line number Diff line number Diff line
/*
 * 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 org.mockito.Mockito.mock;

import android.test.mock.MockContext;

import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

/** Unit tests for {@link VpnManager}. */
@SmallTest
@RunWith(AndroidJUnit4.class)
public class VpnManagerTest {
    private static final String VPN_PROFILE_KEY = "KEY";

    private IConnectivityManager mMockCs;
    private VpnManager mVpnManager;
    private final MockContext mMockContext =
            new MockContext() {
                @Override
                public String getOpPackageName() {
                    return "fooPackage";
                }
            };

    @Before
    public void setUp() throws Exception {
        mMockCs = mock(IConnectivityManager.class);
        mVpnManager = new VpnManager(mMockContext, mMockCs);
    }

    @Test
    public void testProvisionVpnProfile() throws Exception {
        try {
            mVpnManager.provisionVpnProfile(mock(PlatformVpnProfile.class));
        } catch (UnsupportedOperationException expected) {
        }
    }

    @Test
    public void testDeleteProvisionedVpnProfile() throws Exception {
        try {
            mVpnManager.deleteProvisionedVpnProfile();
        } catch (UnsupportedOperationException expected) {
        }
    }

    @Test
    public void testStartProvisionedVpnProfile() throws Exception {
        try {
            mVpnManager.startProvisionedVpnProfile();
        } catch (UnsupportedOperationException expected) {
        }
    }

    @Test
    public void testStopProvisionedVpnProfile() throws Exception {
        try {
            mVpnManager.stopProvisionedVpnProfile();
        } catch (UnsupportedOperationException expected) {
        }
    }
}