diff --git a/core/api/current.txt b/core/api/current.txt index 0e6f6497ab7f1..87cd058c81335 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -25606,7 +25606,8 @@ package android.net { public class VpnManager { method public void deleteProvisionedVpnProfile(); method @Nullable public android.content.Intent provisionVpnProfile(@NonNull android.net.PlatformVpnProfile); - method public void startProvisionedVpnProfile(); + method @Deprecated public void startProvisionedVpnProfile(); + method @NonNull public String startProvisionedVpnProfileSession(); method public void stopProvisionedVpnProfile(); } diff --git a/core/java/android/net/IVpnManager.aidl b/core/java/android/net/IVpnManager.aidl index 271efe41a9ef3..070efa363cc01 100644 --- a/core/java/android/net/IVpnManager.aidl +++ b/core/java/android/net/IVpnManager.aidl @@ -38,7 +38,7 @@ interface IVpnManager { /** VpnManager APIs */ boolean provisionVpnProfile(in VpnProfile profile, String packageName); void deleteVpnProfile(String packageName); - void startVpnProfile(String packageName); + String startVpnProfile(String packageName); void stopVpnProfile(String packageName); /** Always-on VPN APIs */ diff --git a/core/java/android/net/VpnManager.java b/core/java/android/net/VpnManager.java index 319382691925f..91327917f2d7e 100644 --- a/core/java/android/net/VpnManager.java +++ b/core/java/android/net/VpnManager.java @@ -317,17 +317,32 @@ public class VpnManager { /** * Request the startup of a previously provisioned VPN. * + * @return A unique key corresponding to this session. * @throws SecurityException exception if user or device settings prevent this VPN from being - * setup, or if user consent has not been granted + * setup, or if user consent has not been granted */ - public void startProvisionedVpnProfile() { + @NonNull + public String startProvisionedVpnProfileSession() { try { - mService.startVpnProfile(mContext.getOpPackageName()); + return mService.startVpnProfile(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 + * @deprecated This method is replaced by startProvisionedVpnProfileSession which returns a + * session key for the caller to diagnose the errors. + */ + @Deprecated + public void startProvisionedVpnProfile() { + startProvisionedVpnProfileSession(); + } + /** Tear down the VPN provided by the calling app (if any) */ public void stopProvisionedVpnProfile() { try { diff --git a/services/core/java/com/android/server/VpnManagerService.java b/services/core/java/com/android/server/VpnManagerService.java index b48e21e4e2c6a..7b8cce54c8a70 100644 --- a/services/core/java/com/android/server/VpnManagerService.java +++ b/services/core/java/com/android/server/VpnManagerService.java @@ -340,17 +340,18 @@ public class VpnManagerService extends IVpnManager.Stub { *
This is designed to serve the VpnManager only; settings-based VPN profiles are managed * exclusively by the Settings app, and passed into the platform at startup time. * + * @return A unique key corresponding to this session. * @throws IllegalArgumentException if no profile was found for the given package name. * @hide */ @Override - public void startVpnProfile(@NonNull String packageName) { + public String startVpnProfile(@NonNull String packageName) { final int callingUid = Binder.getCallingUid(); verifyCallingUidAndPackage(packageName, callingUid); final int user = UserHandle.getUserId(callingUid); synchronized (mVpns) { throwIfLockdownEnabled(); - mVpns.get(user).startVpnProfile(packageName); + return mVpns.get(user).startVpnProfile(packageName); } } diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index 9a9c3ea05d190..ce4a79c0576d9 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -151,6 +151,7 @@ import java.util.Objects; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; +import java.util.UUID; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; @@ -203,6 +204,7 @@ public class Vpn { private final NetworkInfo mNetworkInfo; private int mLegacyState; @VisibleForTesting protected String mPackage; + private String mSessionKey; private int mOwnerUID; private boolean mIsPackageTargetingAtLeastQ; @VisibleForTesting @@ -2503,6 +2505,7 @@ public class Vpn { mProfile = profile; mIpSecManager = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE); mNetworkCallback = new VpnIkev2Utils.Ikev2VpnNetworkCallback(TAG, this); + mSessionKey = UUID.randomUUID().toString(); } @Override @@ -2824,6 +2827,7 @@ public class Vpn { */ private void disconnectVpnRunner() { mActiveNetwork = null; + mSessionKey = null; mIsRunning = false; resetIkeState(); @@ -3314,7 +3318,7 @@ public class Vpn { * * @param packageName the package name of the app provisioning this profile */ - public synchronized void startVpnProfile(@NonNull String packageName) { + public synchronized String startVpnProfile(@NonNull String packageName) { requireNonNull(packageName, "No package name provided"); enforceNotRestrictedUser(); @@ -3332,6 +3336,7 @@ public class Vpn { } startVpnProfilePrivileged(profile, packageName); + return mSessionKey; } finally { Binder.restoreCallingIdentity(token); }