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

Commit a6093047 authored by Chiachang Wang's avatar Chiachang Wang
Browse files

Fix idle timer rule leakage

Idle timer rule is not cleared as expected if there is a
default network replacement.

Bug:37080406
Test: 1.run frameworks-net
      2.check iptables rule with default network replacement

Change-Id: I6bd29d79e4ca3e8de4b867c4fcb5f81d02ba6de4
parent c457d8c9
Loading
Loading
Loading
Loading
+15 −2
Original line number Diff line number Diff line
@@ -1879,6 +1879,18 @@ public class ConnectivityService extends IConnectivityManager.Stub
        }
    }

    /**
     * Update data activity tracking when network state is updated.
     */
    private void updateDataActivityTracking(NetworkAgentInfo newNetwork,
            NetworkAgentInfo oldNetwork) {
        if (newNetwork != null) {
            setupDataActivityTracking(newNetwork);
        }
        if (oldNetwork != null) {
            removeDataActivityTracking(oldNetwork);
        }
    }
    /**
     * Reads the network specific MTU size from resources.
     * and set it on it's iface.
@@ -2561,7 +2573,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
        }
        nai.clearLingerState();
        if (nai.isSatisfyingRequest(mDefaultRequest.requestId)) {
            removeDataActivityTracking(nai);
            updateDataActivityTracking(null /* newNetwork */, nai);
            notifyLockdownVpn(nai);
            ensureNetworkTransitionWakelock(nai.name());
        }
@@ -5091,7 +5103,7 @@ public class ConnectivityService extends IConnectivityManager.Stub

    private void makeDefault(NetworkAgentInfo newNetwork) {
        if (DBG) log("Switching to new default network: " + newNetwork);
        setupDataActivityTracking(newNetwork);

        try {
            mNetd.setDefaultNetId(newNetwork.network.netId);
        } catch (Exception e) {
@@ -5266,6 +5278,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
            }
        }
        if (isNewDefault) {
            updateDataActivityTracking(newNetwork, oldDefaultNetwork);
            // Notify system services that this network is up.
            makeDefault(newNetwork);
            // Log 0 -> X and Y -> X default network transitions, where X is the new default.
+74 −0
Original line number Diff line number Diff line
@@ -4532,4 +4532,78 @@ public class ConnectivityServiceTest {
        mCellNetworkAgent.disconnect();
        mCm.unregisterNetworkCallback(networkCallback);
    }

    @Test
    public void testDataActivityTracking() throws RemoteException {
        final TestNetworkCallback networkCallback = new TestNetworkCallback();
        final NetworkRequest networkRequest = new NetworkRequest.Builder()
                .addCapability(NET_CAPABILITY_INTERNET)
                .build();
        mCm.registerNetworkCallback(networkRequest, networkCallback);

        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
        final LinkProperties cellLp = new LinkProperties();
        cellLp.setInterfaceName(MOBILE_IFNAME);
        mCellNetworkAgent.sendLinkProperties(cellLp);
        reset(mNetworkManagementService);
        mCellNetworkAgent.connect(true);
        networkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
        verify(mNetworkManagementService, times(1)).addIdleTimer(eq(MOBILE_IFNAME), anyInt(),
                eq(ConnectivityManager.TYPE_MOBILE));

        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
        final LinkProperties wifiLp = new LinkProperties();
        wifiLp.setInterfaceName(WIFI_IFNAME);
        mWiFiNetworkAgent.sendLinkProperties(wifiLp);

        // Network switch
        reset(mNetworkManagementService);
        mWiFiNetworkAgent.connect(true);
        networkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
        networkCallback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
        networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
        verify(mNetworkManagementService, times(1)).addIdleTimer(eq(WIFI_IFNAME), anyInt(),
                eq(ConnectivityManager.TYPE_WIFI));
        verify(mNetworkManagementService, times(1)).removeIdleTimer(eq(MOBILE_IFNAME));

        // Disconnect wifi and switch back to cell
        reset(mNetworkManagementService);
        mWiFiNetworkAgent.disconnect();
        networkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
        assertNoCallbacks(networkCallback);
        verify(mNetworkManagementService, times(1)).removeIdleTimer(eq(WIFI_IFNAME));
        verify(mNetworkManagementService, times(1)).addIdleTimer(eq(MOBILE_IFNAME), anyInt(),
                eq(ConnectivityManager.TYPE_MOBILE));

        // reconnect wifi
        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
        wifiLp.setInterfaceName(WIFI_IFNAME);
        mWiFiNetworkAgent.sendLinkProperties(wifiLp);
        mWiFiNetworkAgent.connect(true);
        networkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
        networkCallback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
        networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);

        // Disconnect cell
        reset(mNetworkManagementService);
        mCellNetworkAgent.disconnect();
        networkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
        // LOST callback is triggered earlier than removing idle timer. Broadcast should also be
        // sent as network being switched. Ensure rule removal for cell will not be triggered
        // unexpectedly before network being removed.
        waitForIdle();
        verify(mNetworkManagementService, times(0)).removeIdleTimer(eq(MOBILE_IFNAME));
        verify(mNetworkManagementService, times(1)).removeNetwork(
                eq(mCellNetworkAgent.getNetwork().netId));

        // Disconnect wifi
        ConditionVariable cv = waitForConnectivityBroadcasts(1);
        reset(mNetworkManagementService);
        mWiFiNetworkAgent.disconnect();
        waitFor(cv);
        verify(mNetworkManagementService, times(1)).removeIdleTimer(eq(WIFI_IFNAME));

        // Clean up
        mCm.unregisterNetworkCallback(networkCallback);
    }
}