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

Commit cb668a3f authored by Yan Yan's avatar Yan Yan Committed by Automerger Merge Worker
Browse files

Merge "Make VPN more testable and update NC during network change" am:...

Merge "Make VPN more testable and update NC during network change" am: 9ff5caa8 am: 4cdb7025 am: 7f1520f6

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2115938



Change-Id: Ia9d59fee62a3dab39a05fc423c8e319755a16c2a
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents fbd462e6 7f1520f6
Loading
Loading
Loading
Loading
+131 −29
Original line number Diff line number Diff line
@@ -252,8 +252,7 @@ public class Vpn {
    @VisibleForTesting
    protected VpnConfig mConfig;
    private final NetworkProvider mNetworkProvider;
    @VisibleForTesting
    protected NetworkAgent mNetworkAgent;
    @VisibleForTesting protected VpnNetworkAgentWrapper mNetworkAgent;
    private final Looper mLooper;
    @VisibleForTesting
    protected NetworkCapabilities mNetworkCapabilities;
@@ -498,6 +497,30 @@ public class Vpn {
                return IKEV2_VPN_RETRY_DELAYS_SEC[retryCount];
            }
        }

        /** Get single threaded executor for IKEv2 VPN */
        public ScheduledThreadPoolExecutor getScheduledThreadPoolExecutor() {
            return new ScheduledThreadPoolExecutor(1);
        }

        /** Get a VpnNetworkAgentWrapper instance */
        public VpnNetworkAgentWrapper getVpnNetworkAgentWrapper(
                @NonNull Context context,
                @NonNull Looper looper,
                @NonNull String logTag,
                @NonNull NetworkCapabilities nc,
                @NonNull LinkProperties lp,
                @NonNull NetworkScore score,
                @NonNull NetworkAgentConfig config,
                @Nullable NetworkProvider provider) {
            return new VpnNetworkAgentWrapper(
                    new NetworkAgent(context, looper, logTag, nc, lp, score, config, provider) {
                        @Override
                        public void onNetworkUnwanted() {
                            // We are user controlled, not driven by NetworkRequest.
                        }
                    });
        }
    }

    public Vpn(Looper looper, Context context, INetworkManagementService netService, INetd netd,
@@ -1329,7 +1352,7 @@ public class Vpn {
    @VisibleForTesting
    @Nullable
    public synchronized Network getNetwork() {
        final NetworkAgent agent = mNetworkAgent;
        final VpnNetworkAgentWrapper agent = mNetworkAgent;
        if (null == agent) return null;
        final Network network = agent.getNetwork();
        if (null == network) return null;
@@ -1409,7 +1432,8 @@ public class Vpn {
     * registering a new NetworkAgent. This is not always possible if the new VPN configuration
     * has certain changes, in which case this method would just return {@code false}.
     */
    private boolean updateLinkPropertiesInPlaceIfPossible(NetworkAgent agent, VpnConfig oldConfig) {
    private boolean updateLinkPropertiesInPlaceIfPossible(
            VpnNetworkAgentWrapper agent, VpnConfig oldConfig) {
        // NetworkAgentConfig cannot be updated without registering a new NetworkAgent.
        if (oldConfig.allowBypass != mConfig.allowBypass) {
            Log.i(TAG, "Handover not possible due to changes to allowBypass");
@@ -1474,15 +1498,11 @@ public class Vpn {
                ? Arrays.asList(mConfig.underlyingNetworks) : null);

        mNetworkCapabilities = capsBuilder.build();
        mNetworkAgent = new NetworkAgent(mContext, mLooper, NETWORKTYPE /* logtag */,
        mNetworkAgent = mDeps.getVpnNetworkAgentWrapper(
                mContext, mLooper, NETWORKTYPE /* logtag */,
                mNetworkCapabilities, lp,
                new NetworkScore.Builder().setLegacyInt(VPN_DEFAULT_SCORE).build(),
                networkAgentConfig, mNetworkProvider) {
            @Override
            public void onNetworkUnwanted() {
                // We are user controlled, not driven by NetworkRequest.
            }
        };
                networkAgentConfig, mNetworkProvider);
        final long token = Binder.clearCallingIdentity();
        try {
            mNetworkAgent.register();
@@ -1506,7 +1526,7 @@ public class Vpn {
        }
    }

    private void agentDisconnect(NetworkAgent networkAgent) {
    private void agentDisconnect(VpnNetworkAgentWrapper networkAgent) {
        if (networkAgent != null) {
            networkAgent.unregister();
        }
@@ -1562,7 +1582,7 @@ public class Vpn {
        VpnConfig oldConfig = mConfig;
        String oldInterface = mInterface;
        Connection oldConnection = mConnection;
        NetworkAgent oldNetworkAgent = mNetworkAgent;
        VpnNetworkAgentWrapper oldNetworkAgent = mNetworkAgent;
        Set<Range<Integer>> oldUsers = mNetworkCapabilities.getUids();

        // Configure the interface. Abort if any of these steps fails.
@@ -2692,8 +2712,7 @@ public class Vpn {
         * of the mutable Ikev2VpnRunner fields. The Ikev2VpnRunner is built mostly lock-free by
         * virtue of everything being serialized on this executor.
         */
        @NonNull
        private final ScheduledThreadPoolExecutor mExecutor = new ScheduledThreadPoolExecutor(1);
        @NonNull private final ScheduledThreadPoolExecutor mExecutor;

        @Nullable private ScheduledFuture<?> mScheduledHandleNetworkLostTimeout;
        @Nullable private ScheduledFuture<?> mScheduledHandleRetryIkeSessionTimeout;
@@ -2714,7 +2733,7 @@ public class Vpn {
        @Nullable private LinkProperties mUnderlyingLinkProperties;
        private final String mSessionKey;

        @Nullable private IkeSession mSession;
        @Nullable private IkeSessionWrapper mSession;
        @Nullable private IkeSessionConnectionInfo mIkeConnectionInfo;

        // mMobikeEnabled can only be updated after IKE AUTH is finished.
@@ -2728,9 +2747,11 @@ public class Vpn {
         */
        private int mRetryCount = 0;

        IkeV2VpnRunner(@NonNull Ikev2VpnProfile profile) {
        IkeV2VpnRunner(
                @NonNull Ikev2VpnProfile profile, @NonNull ScheduledThreadPoolExecutor executor) {
            super(TAG);
            mProfile = profile;
            mExecutor = executor;
            mIpSecManager = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE);
            mNetworkCallback = new VpnIkev2Utils.Ikev2VpnNetworkCallback(TAG, this, mExecutor);
            mSessionKey = UUID.randomUUID().toString();
@@ -2743,7 +2764,7 @@ public class Vpn {

            // To avoid hitting RejectedExecutionException upon shutdown of the mExecutor */
            mExecutor.setRejectedExecutionHandler(
                    (r, executor) -> {
                    (r, exe) -> {
                        Log.d(TAG, "Runnable " + r + " rejected by the mExecutor");
                    });
        }
@@ -2865,7 +2886,7 @@ public class Vpn {
                // mActiveNetwork might have been updated after the setup was triggered.
                final Network network = mIkeConnectionInfo.getNetwork();

                final NetworkAgent networkAgent;
                final VpnNetworkAgentWrapper networkAgent;
                final LinkProperties lp;

                synchronized (Vpn.this) {
@@ -2884,7 +2905,6 @@ public class Vpn {
                    mConfig.dnsServers.addAll(dnsAddrStrings);

                    mConfig.underlyingNetworks = new Network[] {network};

                    mConfig.disallowedApplications = getAppExclusionList(mPackage);

                    networkAgent = mNetworkAgent;
@@ -2900,6 +2920,10 @@ public class Vpn {
                    } else {
                        // Underlying networks also set in agentConnect()
                        networkAgent.setUnderlyingNetworks(Collections.singletonList(network));
                        mNetworkCapabilities =
                                new NetworkCapabilities.Builder(mNetworkCapabilities)
                                        .setUnderlyingNetworks(Collections.singletonList(network))
                                        .build();
                    }

                    lp = makeLinkProperties(); // Accesses VPN instance fields; must be locked
@@ -4015,7 +4039,9 @@ public class Vpn {
                case VpnProfile.TYPE_IKEV2_IPSEC_RSA:
                case VpnProfile.TYPE_IKEV2_FROM_IKE_TUN_CONN_PARAMS:
                    mVpnRunner =
                            new IkeV2VpnRunner(Ikev2VpnProfile.fromVpnProfile(profile));
                            new IkeV2VpnRunner(
                                    Ikev2VpnProfile.fromVpnProfile(profile),
                                    mDeps.getScheduledThreadPoolExecutor());
                    mVpnRunner.start();
                    break;
                default:
@@ -4185,6 +4211,81 @@ public class Vpn {
        return isCurrentIkev2VpnLocked(packageName) ? makeVpnProfileStateLocked() : null;
    }

    /**
     * Proxy to allow testing
     *
     * @hide
     */
    @VisibleForTesting
    public static class VpnNetworkAgentWrapper {
        private final NetworkAgent mImpl;

        /** Create an VpnNetworkAgentWrapper */
        public VpnNetworkAgentWrapper(@NonNull NetworkAgent networkAgent) {
            mImpl = networkAgent;
        }

        /** Inform ConnectivityService that this agent has now connected */
        public void markConnected() {
            mImpl.markConnected();
        }

        /** Register this network agent with ConnectivityService */
        public void register() {
            mImpl.register();
        }

        /** Unregister this network agent */
        public void unregister() {
            mImpl.unregister();
        }

        /** Update the LinkProperties */
        public void sendLinkProperties(@NonNull LinkProperties lp) {
            mImpl.sendLinkProperties(lp);
        }

        /** Update the NetworkCapabilities */
        public void sendNetworkCapabilities(@NonNull NetworkCapabilities nc) {
            mImpl.sendNetworkCapabilities(nc);
        }

        /** Set the underlying networks */
        public void setUnderlyingNetworks(@NonNull List<Network> networks) {
            mImpl.setUnderlyingNetworks(networks);
        }

        /**  The Network associated with this agent */
        public Network getNetwork() {
            return mImpl.getNetwork();
        }
    }

    /**
     * Proxy to allow testing
     *
     * @hide
     */
    @VisibleForTesting
    public static class IkeSessionWrapper {
        private final IkeSession mImpl;

        /** Create an IkeSessionWrapper */
        public IkeSessionWrapper(IkeSession session) {
            mImpl = session;
        }

        /** Update the underlying network of the IKE Session */
        public void setNetwork(@NonNull Network network) {
            mImpl.setNetwork(network);
        }

        /** Forcibly terminate the IKE Session */
        public void kill() {
            mImpl.kill();
        }
    }

    /**
     * Proxy to allow testing
     *
@@ -4193,20 +4294,21 @@ public class Vpn {
    @VisibleForTesting
    public static class Ikev2SessionCreator {
        /** Creates a IKE session */
        public IkeSession createIkeSession(
        public IkeSessionWrapper createIkeSession(
                @NonNull Context context,
                @NonNull IkeSessionParams ikeSessionParams,
                @NonNull ChildSessionParams firstChildSessionParams,
                @NonNull Executor userCbExecutor,
                @NonNull IkeSessionCallback ikeSessionCallback,
                @NonNull ChildSessionCallback firstChildSessionCallback) {
            return new IkeSession(
            return new IkeSessionWrapper(
                    new IkeSession(
                            context,
                            ikeSessionParams,
                            firstChildSessionParams,
                            userCbExecutor,
                            ikeSessionCallback,
                    firstChildSessionCallback);
                            firstChildSessionCallback));
        }
    }