diff options
| author | 2019-11-01 16:46:28 -0700 | |
|---|---|---|
| committer | 2020-01-22 19:24:24 -0800 | |
| commit | 50b444359e95d5325d4c7da536893c45e529d28b (patch) | |
| tree | 7ebc8f15548435d0e318008dec02f24010fe1afb | |
| parent | feb69c13efe9037240e1defd051b49ad7d4b919a (diff) | |
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
| -rw-r--r-- | api/current.txt | 8 | ||||
| -rw-r--r-- | core/java/android/app/SystemServiceRegistry.java | 10 | ||||
| -rw-r--r-- | core/java/android/content/Context.java | 9 | ||||
| -rw-r--r-- | core/java/android/net/VpnManager.java | 88 | ||||
| -rw-r--r-- | tests/net/java/android/net/VpnManagerTest.java | 83 |
5 files changed, 198 insertions, 0 deletions
diff --git a/api/current.txt b/api/current.txt index 28754260fdd8..f275d44f3a44 100644 --- a/api/current.txt +++ b/api/current.txt @@ -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(); diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index 8e12a221b5f7..81f6d28db9fe 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -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>() { diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 725fd0531911..472d9567e2ad 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -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, @@ -3880,6 +3881,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 * as well as receiving network connectivity information from the system. diff --git a/core/java/android/net/VpnManager.java b/core/java/android/net/VpnManager.java new file mode 100644 index 000000000000..f95807a14f00 --- /dev/null +++ b/core/java/android/net/VpnManager.java @@ -0,0 +1,88 @@ +/* + * 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"); + } +} diff --git a/tests/net/java/android/net/VpnManagerTest.java b/tests/net/java/android/net/VpnManagerTest.java new file mode 100644 index 000000000000..655c4d118592 --- /dev/null +++ b/tests/net/java/android/net/VpnManagerTest.java @@ -0,0 +1,83 @@ +/* + * 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) { + } + } +} |