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

Commit 492e2392 authored by chiachangwang's avatar chiachangwang Committed by lucaslin
Browse files

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 03f0d124)
Merged-In: I83e1e1edf6c3a6653d87216afcd397f296f59cf2
parent f96e5ad5
Loading
Loading
Loading
Loading
+21 −14
Original line number Diff line number Diff line
@@ -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 */);
        }
    }