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

Commit 7369d8d1 authored by Lorenzo Colitti's avatar Lorenzo Colitti
Browse files

Add detailed test coverage for lingering.

Bug: 23113288
Change-Id: I65784f3589378d97f3c824e600f21f361be8741e
parent 6ee0a92c
Loading
Loading
Loading
Loading
+159 −6
Original line number Original line Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.server;
package com.android.server;


import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
import static android.net.ConnectivityManager.TYPE_ETHERNET;
import static android.net.ConnectivityManager.TYPE_MOBILE;
import static android.net.ConnectivityManager.TYPE_MOBILE;
import static android.net.ConnectivityManager.TYPE_WIFI;
import static android.net.ConnectivityManager.TYPE_WIFI;
import static android.net.ConnectivityManager.getNetworkTypeName;
import static android.net.ConnectivityManager.getNetworkTypeName;
@@ -101,6 +102,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
    private WrappedConnectivityManager mCm;
    private WrappedConnectivityManager mCm;
    private MockNetworkAgent mWiFiNetworkAgent;
    private MockNetworkAgent mWiFiNetworkAgent;
    private MockNetworkAgent mCellNetworkAgent;
    private MockNetworkAgent mCellNetworkAgent;
    private MockNetworkAgent mEthernetNetworkAgent;


    // This class exists to test bindProcessToNetwork and getBoundNetworkForProcess. These methods
    // This class exists to test bindProcessToNetwork and getBoundNetworkForProcess. These methods
    // do not go through ConnectivityService but talk to netd directly, so they don't automatically
    // do not go through ConnectivityService but talk to netd directly, so they don't automatically
@@ -244,6 +246,9 @@ public class ConnectivityServiceTest extends AndroidTestCase {
            mNetworkCapabilities = new NetworkCapabilities();
            mNetworkCapabilities = new NetworkCapabilities();
            mNetworkCapabilities.addTransportType(transport);
            mNetworkCapabilities.addTransportType(transport);
            switch (transport) {
            switch (transport) {
                case TRANSPORT_ETHERNET:
                    mScore = 70;
                    break;
                case TRANSPORT_WIFI:
                case TRANSPORT_WIFI:
                    mScore = 60;
                    mScore = 60;
                    break;
                    break;
@@ -305,6 +310,11 @@ public class ConnectivityServiceTest extends AndroidTestCase {
            mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
            mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
        }
        }


        public void removeCapability(int capability) {
            mNetworkCapabilities.removeCapability(capability);
            mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
        }

        public void setSignalStrength(int signalStrength) {
        public void setSignalStrength(int signalStrength) {
            mNetworkCapabilities.setSignalStrength(signalStrength);
            mNetworkCapabilities.setSignalStrength(signalStrength);
            mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
            mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
@@ -704,6 +714,8 @@ public class ConnectivityServiceTest extends AndroidTestCase {


    private int transportToLegacyType(int transport) {
    private int transportToLegacyType(int transport) {
        switch (transport) {
        switch (transport) {
            case TRANSPORT_ETHERNET:
                return TYPE_ETHERNET;
            case TRANSPORT_WIFI:
            case TRANSPORT_WIFI:
                return TYPE_WIFI;
                return TYPE_WIFI;
            case TRANSPORT_CELLULAR:
            case TRANSPORT_CELLULAR:
@@ -1064,15 +1076,12 @@ public class ConnectivityServiceTest extends AndroidTestCase {
            CallbackInfo expected = new CallbackInfo(
            CallbackInfo expected = new CallbackInfo(
                    state,
                    state,
                    (mockAgent != null) ? mockAgent.getNetwork() : null);
                    (mockAgent != null) ? mockAgent.getNetwork() : null);
            CallbackInfo actual;
            try {
            try {
                actual = mCallbacks.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS);
                assertEquals("Unexpected callback:",
                        expected, mCallbacks.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS));
            } catch (InterruptedException e) {
            } catch (InterruptedException e) {
                fail("Did not receive expected " + expected + " after " + TIMEOUT_MS + "ms");
                fail("Did not receive expected " + expected + " after " + TIMEOUT_MS + "ms");
                actual = null;  // Or the compiler says it might be uninitialized.
            }
            }

            assertEquals("Unexpected callback:", expected, actual);
        }
        }


        void assertNoCallback() {
        void assertNoCallback() {
@@ -1179,6 +1188,150 @@ public class ConnectivityServiceTest extends AndroidTestCase {
        assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
        assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
    }
    }


    @SmallTest
    public void testMultipleLingering() {
        NetworkRequest request = new NetworkRequest.Builder()
                .clearCapabilities().addCapability(NET_CAPABILITY_NOT_METERED)
                .build();
        TestNetworkCallback callback = new TestNetworkCallback();
        mCm.registerNetworkCallback(request, callback);

        TestNetworkCallback defaultCallback = new TestNetworkCallback();
        mCm.registerDefaultNetworkCallback(defaultCallback);

        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
        mEthernetNetworkAgent = new MockNetworkAgent(TRANSPORT_ETHERNET);

        mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
        mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
        mEthernetNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);

        mCellNetworkAgent.connect(true);
        callback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
        defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
        assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());

        mWiFiNetworkAgent.connect(true);
        // We get AVAILABLE on wifi when wifi connects and satisfies our unmetered request.
        // We then get LOSING when wifi validates and cell is outscored.
        callback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
        callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
        defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
        assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());

        mEthernetNetworkAgent.connect(true);
        callback.expectCallback(CallbackState.AVAILABLE, mEthernetNetworkAgent);
        callback.expectCallback(CallbackState.LOSING, mWiFiNetworkAgent);
        defaultCallback.expectCallback(CallbackState.AVAILABLE, mEthernetNetworkAgent);
        assertEquals(mEthernetNetworkAgent.getNetwork(), mCm.getActiveNetwork());

        mEthernetNetworkAgent.disconnect();
        callback.expectCallback(CallbackState.LOST, mEthernetNetworkAgent);
        defaultCallback.expectCallback(CallbackState.LOST, mEthernetNetworkAgent);
        defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);

        for (int i = 0; i < 4; i++) {
            MockNetworkAgent oldNetwork, newNetwork;
            if (i % 2 == 0) {
                mWiFiNetworkAgent.adjustScore(-15);
                oldNetwork = mWiFiNetworkAgent;
                newNetwork = mCellNetworkAgent;
            } else {
                mWiFiNetworkAgent.adjustScore(15);
                oldNetwork = mCellNetworkAgent;
                newNetwork = mWiFiNetworkAgent;

            }
            callback.expectCallback(CallbackState.LOSING, oldNetwork);
            defaultCallback.expectCallback(CallbackState.AVAILABLE, newNetwork);
            assertEquals(newNetwork.getNetwork(), mCm.getActiveNetwork());
        }
        assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());

        // Verify that if a network no longer satisfies a request, we send LOST and not LOSING, even
        // if the network is still up.
        mWiFiNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED);
        callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);

        // Wifi no longer satisfies our listen, which is for an unmetered network.
        // But because its score is 55, it's still up (and the default network).
        defaultCallback.assertNoCallback();
        assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());

        // Disconnect our test networks.
        mWiFiNetworkAgent.disconnect();
        defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
        defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
        mCellNetworkAgent.disconnect();
        defaultCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);

        mCm.unregisterNetworkCallback(callback);
        mService.waitForIdle();

        // Check that a network is only lingered or torn down if it would not satisfy a request even
        // if it validated.
        request = new NetworkRequest.Builder().clearCapabilities().build();
        callback = new TestNetworkCallback();

        mCm.registerNetworkCallback(request, callback);

        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
        mCellNetworkAgent.connect(false);   // Score: 10
        callback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
        defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
        assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());

        // Bring up wifi with a score of 20.
        // Cell stays up because it would satisfy the default request if it validated.
        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
        mWiFiNetworkAgent.connect(false);   // Score: 20
        callback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
        defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
        assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());

        mWiFiNetworkAgent.disconnect();
        callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
        defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
        defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
        assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());

        // Bring up wifi with a score of 70.
        // Cell is lingered because it would not satisfy any reques, even if it validated.
        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
        mWiFiNetworkAgent.adjustScore(50);
        mWiFiNetworkAgent.connect(false);   // Score: 70
        callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
        callback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
        defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
        assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());

        // Tear down wifi.
        mWiFiNetworkAgent.disconnect();
        callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
        defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
        defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
        assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());

        // Bring up wifi, then validate it. In this case we do not linger cell. What happens is that
        // when wifi connects, we don't linger because cell could potentially become the default
        // network if it validated. Then, when wifi validates, we re-evaluate cell, see it has no
        // requests, and tear it down because it's unneeded.
        // TODO: can we linger in this case?
        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
        mWiFiNetworkAgent.connect(true);
        callback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
        callback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
        defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
        assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());

        mWiFiNetworkAgent.disconnect();
        callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);

        mCm.unregisterNetworkCallback(callback);
        mCm.unregisterNetworkCallback(defaultCallback);
    }

    private void tryNetworkFactoryRequests(int capability) throws Exception {
    private void tryNetworkFactoryRequests(int capability) throws Exception {
        // Verify NOT_RESTRICTED is set appropriately
        // Verify NOT_RESTRICTED is set appropriately
        final NetworkCapabilities nc = new NetworkRequest.Builder().addCapability(capability)
        final NetworkCapabilities nc = new NetworkRequest.Builder().addCapability(capability)