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

Commit 451566c1 authored by Chiachang Wang's avatar Chiachang Wang Committed by Automerger Merge Worker
Browse files

Merge "Perform MOBIKE when data stall is suspected" am: 97db2423 am: bf20b85b am: 5442cfed

parents 8d44d530 5442cfed
Loading
Loading
Loading
Loading
+59 −14
Original line number Original line Diff line number Diff line
@@ -21,6 +21,7 @@ import static android.Manifest.permission.CONTROL_VPN;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
import static android.net.RouteInfo.RTN_THROW;
import static android.net.RouteInfo.RTN_THROW;
import static android.net.RouteInfo.RTN_UNREACHABLE;
import static android.net.RouteInfo.RTN_UNREACHABLE;
import static android.net.VpnManager.NOTIFICATION_CHANNEL_VPN;
import static android.net.VpnManager.NOTIFICATION_CHANNEL_VPN;
@@ -51,6 +52,7 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.UserInfo;
import android.content.pm.UserInfo;
import android.net.ConnectivityDiagnosticsManager;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager;
import android.net.DnsResolver;
import android.net.DnsResolver;
import android.net.INetd;
import android.net.INetd;
@@ -234,6 +236,7 @@ public class Vpn {
    private final Context mContext;
    private final Context mContext;
    private final ConnectivityManager mConnectivityManager;
    private final ConnectivityManager mConnectivityManager;
    private final AppOpsManager mAppOpsManager;
    private final AppOpsManager mAppOpsManager;
    private final ConnectivityDiagnosticsManager mConnectivityDiagnosticsManager;
    // The context is for specific user which is created from mUserId
    // The context is for specific user which is created from mUserId
    private final Context mUserIdContext;
    private final Context mUserIdContext;
    @VisibleForTesting final Dependencies mDeps;
    @VisibleForTesting final Dependencies mDeps;
@@ -549,6 +552,8 @@ public class Vpn {
        mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
        mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
        mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
        mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
        mUserIdContext = context.createContextAsUser(UserHandle.of(userId), 0 /* flags */);
        mUserIdContext = context.createContextAsUser(UserHandle.of(userId), 0 /* flags */);
        mConnectivityDiagnosticsManager =
                mContext.getSystemService(ConnectivityDiagnosticsManager.class);
        mDeps = deps;
        mDeps = deps;
        mNms = netService;
        mNms = netService;
        mNetd = netd;
        mNetd = netd;
@@ -2739,6 +2744,7 @@ public class Vpn {


        @Nullable private IkeSessionWrapper mSession;
        @Nullable private IkeSessionWrapper mSession;
        @Nullable private IkeSessionConnectionInfo mIkeConnectionInfo;
        @Nullable private IkeSessionConnectionInfo mIkeConnectionInfo;
        @Nullable private VpnConnectivityDiagnosticsCallback mDiagnosticsCallback;


        // mMobikeEnabled can only be updated after IKE AUTH is finished.
        // mMobikeEnabled can only be updated after IKE AUTH is finished.
        private boolean mMobikeEnabled = false;
        private boolean mMobikeEnabled = false;
@@ -2797,6 +2803,15 @@ public class Vpn {
                mConnectivityManager.registerSystemDefaultNetworkCallback(mNetworkCallback,
                mConnectivityManager.registerSystemDefaultNetworkCallback(mNetworkCallback,
                        new Handler(mLooper));
                        new Handler(mLooper));
            }
            }

            // DiagnosticsCallback may return more than one alive VPNs, but VPN will filter based on
            // Network object.
            final NetworkRequest diagRequest = new NetworkRequest.Builder()
                    .addTransportType(TRANSPORT_VPN)
                    .removeCapability(NET_CAPABILITY_NOT_VPN).build();
            mDiagnosticsCallback = new VpnConnectivityDiagnosticsCallback();
            mConnectivityDiagnosticsManager.registerConnectivityDiagnosticsCallback(
                    diagRequest, mExecutor, mDiagnosticsCallback);
        }
        }


        private boolean isActiveNetwork(@Nullable Network network) {
        private boolean isActiveNetwork(@Nullable Network network) {
@@ -3066,22 +3081,28 @@ public class Vpn {
                return;
                return;
            }
            }


            try {
            if (maybeMigrateIkeSession(underlyingNetwork)) return;
                if (mSession != null && mMobikeEnabled) {

            startIkeSession(underlyingNetwork);
        }

        boolean maybeMigrateIkeSession(@NonNull Network underlyingNetwork) {
            if (mSession == null || !mMobikeEnabled) return false;

            // IKE session can schedule a migration event only when IKE AUTH is finished
            // IKE session can schedule a migration event only when IKE AUTH is finished
            // and mMobikeEnabled is true.
            // and mMobikeEnabled is true.
                    Log.d(
            Log.d(TAG, "Migrate IKE Session with token "
                            TAG,
                            "Migrate IKE Session with token "
                    + mCurrentToken
                    + mCurrentToken
                    + " to network "
                    + " to network "
                    + underlyingNetwork);
                    + underlyingNetwork);
            mSession.setNetwork(underlyingNetwork);
            mSession.setNetwork(underlyingNetwork);
                    return;
            return true;
        }
        }


        private void startIkeSession(@NonNull Network underlyingNetwork) {
            Log.d(TAG, "Start new IKE session on network " + underlyingNetwork);
            Log.d(TAG, "Start new IKE session on network " + underlyingNetwork);


            try {
                // Clear mInterface to prevent Ikev2VpnRunner being cleared when
                // Clear mInterface to prevent Ikev2VpnRunner being cleared when
                // interfaceRemoved() is called.
                // interfaceRemoved() is called.
                synchronized (Vpn.this) {
                synchronized (Vpn.this) {
@@ -3169,6 +3190,28 @@ public class Vpn {
            mUnderlyingLinkProperties = lp;
            mUnderlyingLinkProperties = lp;
        }
        }


        class VpnConnectivityDiagnosticsCallback
                extends ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback {
            // The callback runs in the executor thread.
            @Override
            public void onDataStallSuspected(
                    ConnectivityDiagnosticsManager.DataStallReport report) {
                synchronized (Vpn.this) {
                    // Ignore stale runner.
                    if (mVpnRunner != Vpn.IkeV2VpnRunner.this) return;

                    // Handle the report only for current VPN network.
                    if (mNetworkAgent != null
                            && mNetworkAgent.getNetwork().equals(report.getNetwork())) {
                        Log.d(TAG, "Data stall suspected");

                        // Trigger MOBIKE.
                        maybeMigrateIkeSession(mActiveNetwork);
                    }
                }
            }
        }

        /**
        /**
         * Handles loss of the default underlying network
         * Handles loss of the default underlying network
         *
         *
@@ -3463,6 +3506,8 @@ public class Vpn {
            resetIkeState();
            resetIkeState();


            mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
            mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
            mConnectivityDiagnosticsManager.unregisterConnectivityDiagnosticsCallback(
                    mDiagnosticsCallback);


            mExecutor.shutdown();
            mExecutor.shutdown();
        }
        }