From 492e239299153a725a967cc37fe8d67a1a49dad5 Mon Sep 17 00:00:00 2001 From: chiachangwang Date: Wed, 29 Jun 2022 03:08:15 +0000 Subject: [PATCH] Stop VPN profiles by exiting VpnRunner instead of prepareInternal Change to call the VpnRunner.exit to stop vpn profile instead of using prepareInternal to leave the package intact. This aligns with the way that VpnServices are disconnected so that the package and other related information will not be reset unexpectedly. In current design, Vpn will examine if the current prepared package matches to prevent an existing always-on VPN from being dethroned by other apps when the VPN always-on is enabled. However, when the VPN is disabled using stopVpnProfile, the current package name will be updated to [LEGACY VPN]. The current package will no longer be the same with the VPN package. This resulted in the rejection of the VPN app to start the VPN using VpnManager.startVpnProfile again. Test: atest FrameworksNetTests Test: manually test with VPN app to reconnect VPN when always-on is enabled. Bug: 235322391 Change-Id: I83e1e1edf6c3a6653d87216afcd397f296f59cf2 (cherry picked from commit 03f0d12480b72780e67cce33473e8c55befc2669) Merged-In: I83e1e1edf6c3a6653d87216afcd397f296f59cf2 --- .../com/android/server/connectivity/Vpn.java | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index 98238ccd93c32..8470c07606654 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -1178,20 +1178,9 @@ public class Vpn { cleanupVpnStateLocked(); } else if (mVpnRunner != null) { if (!VpnConfig.LEGACY_VPN.equals(mPackage)) { - mAppOpsManager.finishOp( - AppOpsManager.OPSTR_ESTABLISH_VPN_MANAGER, mOwnerUID, mPackage, null); - // The underlying network, NetworkCapabilities and LinkProperties are not - // necessary to send to VPN app since the purpose of this event is to notify - // VPN app that VPN is deactivated by the user. - // TODO(b/230548427): Remove SDK check once VPN related stuff are decoupled from - // ConnectivityServiceTest. - if (SdkLevel.isAtLeastT()) { - sendEventToVpnManagerApp(VpnManager.CATEGORY_EVENT_DEACTIVATED_BY_USER, - -1 /* errorClass */, -1 /* errorCode*/, mPackage, - getSessionKeyLocked(), makeVpnProfileStateLocked(), - null /* underlyingNetwork */, null /* nc */, null /* lp */); - } + notifyVpnManagerVpnStopped(mPackage, mOwnerUID); } + // cleanupVpnStateLocked() is called from mVpnRunner.exit() mVpnRunner.exit(); } @@ -4090,7 +4079,25 @@ public class Vpn { // To stop the VPN profile, the caller must be the current prepared package and must be // running an Ikev2VpnProfile. if (isCurrentIkev2VpnLocked(packageName)) { - prepareInternal(VpnConfig.LEGACY_VPN); + notifyVpnManagerVpnStopped(packageName, mOwnerUID); + + mVpnRunner.exit(); + } + } + + private synchronized void notifyVpnManagerVpnStopped(String packageName, int ownerUID) { + mAppOpsManager.finishOp( + AppOpsManager.OPSTR_ESTABLISH_VPN_MANAGER, ownerUID, packageName, null); + // The underlying network, NetworkCapabilities and LinkProperties are not + // necessary to send to VPN app since the purpose of this event is to notify + // VPN app that VPN is deactivated by the user. + // TODO(b/230548427): Remove SDK check once VPN related stuff are decoupled from + // ConnectivityServiceTest. + if (SdkLevel.isAtLeastT()) { + sendEventToVpnManagerApp(VpnManager.CATEGORY_EVENT_DEACTIVATED_BY_USER, + -1 /* errorClass */, -1 /* errorCode*/, packageName, + getSessionKeyLocked(), makeVpnProfileStateLocked(), + null /* underlyingNetwork */, null /* nc */, null /* lp */); } }