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

Commit 6ee0a92c authored by Lorenzo Colitti's avatar Lorenzo Colitti
Browse files

Add more test coverage for requests and callbacks.

1. Support multiple callbacks in TestNetworkCallback. This is
   necessary to test situations where multiple callbacks are
   generated by the same event (e.g., CALLBACK_LOSING on cell
   with CALLBACK_AVAILABLE on wifi when wifi connects), which is
   necessary to test callback order. So far this has not been
   covered because all callback testing was using per-network
   callbacks.
2. Add a benchmark test for registering NetworkRequests and for
   sending onAvailable and onLosing callbacks.

Bug: 23113288
Change-Id: Ib69373358ad766ab1bd989e864a5a51ef762c73c
parent 9e0450a4
Loading
Loading
Loading
Loading
+164 −63
Original line number Original line Diff line number Diff line
@@ -79,6 +79,7 @@ import com.android.server.net.NetworkPinner;


import java.net.InetAddress;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Objects;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeUnit;
@@ -694,6 +695,13 @@ public class ConnectivityServiceTest extends AndroidTestCase {
        mCm.bindProcessToNetwork(null);
        mCm.bindProcessToNetwork(null);
    }
    }


    public void tearDown() throws Exception {
        if (mCellNetworkAgent != null) { mCellNetworkAgent.disconnect(); }
        if (mWiFiNetworkAgent != null) { mWiFiNetworkAgent.disconnect(); }
        mCellNetworkAgent = mWiFiNetworkAgent = null;
        super.tearDown();
    }

    private int transportToLegacyType(int transport) {
    private int transportToLegacyType(int transport) {
        switch (transport) {
        switch (transport) {
            case TRANSPORT_WIFI:
            case TRANSPORT_WIFI:
@@ -911,8 +919,6 @@ public class ConnectivityServiceTest extends AndroidTestCase {
        mWiFiNetworkAgent.adjustScore(11);
        mWiFiNetworkAgent.adjustScore(11);
        waitFor(cv);
        waitFor(cv);
        verifyActiveNetwork(TRANSPORT_WIFI);
        verifyActiveNetwork(TRANSPORT_WIFI);
        mCellNetworkAgent.disconnect();
        mWiFiNetworkAgent.disconnect();
    }
    }


    @LargeTest
    @LargeTest
@@ -984,8 +990,6 @@ public class ConnectivityServiceTest extends AndroidTestCase {
        assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
        assertFalse(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
                NET_CAPABILITY_VALIDATED));
                NET_CAPABILITY_VALIDATED));
        verifyActiveNetwork(TRANSPORT_WIFI);
        verifyActiveNetwork(TRANSPORT_WIFI);
        mCellNetworkAgent.disconnect();
        mWiFiNetworkAgent.disconnect();
    }
    }


    @LargeTest
    @LargeTest
@@ -1012,8 +1016,6 @@ public class ConnectivityServiceTest extends AndroidTestCase {
        assertFalse(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability(
        assertFalse(mCm.getNetworkCapabilities(mCellNetworkAgent.getNetwork()).hasCapability(
                NET_CAPABILITY_VALIDATED));
                NET_CAPABILITY_VALIDATED));
        verifyActiveNetwork(TRANSPORT_WIFI);
        verifyActiveNetwork(TRANSPORT_WIFI);
        mCellNetworkAgent.disconnect();
        mWiFiNetworkAgent.disconnect();
    }
    }


    enum CallbackState {
    enum CallbackState {
@@ -1029,59 +1031,77 @@ public class ConnectivityServiceTest extends AndroidTestCase {
     * received. assertNoCallback may be called at any time.
     * received. assertNoCallback may be called at any time.
     */
     */
    private class TestNetworkCallback extends NetworkCallback {
    private class TestNetworkCallback extends NetworkCallback {
        private final ConditionVariable mConditionVariable = new ConditionVariable();
        private class CallbackInfo {
        private CallbackState mLastCallback = CallbackState.NONE;
            public final CallbackState state;
        private Network mLastNetwork;
            public final Network network;
            public CallbackInfo(CallbackState s, Network n) { state = s; network = n; }
            public String toString() { return String.format("%s (%s)", state, network); }
            public boolean equals(Object o) {
                if (!(o instanceof CallbackInfo)) return false;
                CallbackInfo other = (CallbackInfo) o;
                return state == other.state && Objects.equals(network, other.network);
            }
        }
        private final LinkedBlockingQueue<CallbackInfo> mCallbacks = new LinkedBlockingQueue<>();

        private void setLastCallback(CallbackState state, Network network) {
            mCallbacks.offer(new CallbackInfo(state, network));
        }


        public void onAvailable(Network network) {
        public void onAvailable(Network network) {
            assertEquals(CallbackState.NONE, mLastCallback);
            setLastCallback(CallbackState.AVAILABLE, network);
            mLastCallback = CallbackState.AVAILABLE;
            mLastNetwork = network;
            mConditionVariable.open();
        }
        }


        public void onLosing(Network network, int maxMsToLive) {
        public void onLosing(Network network, int maxMsToLive) {
            assertEquals(CallbackState.NONE, mLastCallback);
            setLastCallback(CallbackState.LOSING, network);
            mLastCallback = CallbackState.LOSING;
            mLastNetwork = network;
            mConditionVariable.open();
        }
        }


        public void onLost(Network network) {
        public void onLost(Network network) {
            assertEquals(CallbackState.NONE, mLastCallback);
            setLastCallback(CallbackState.LOST, network);
            mLastCallback = CallbackState.LOST;
            mLastNetwork = network;
            mConditionVariable.open();
        }

        void expectCallback(CallbackState state) {
            expectCallback(state, null);
        }
        }


        void expectCallback(CallbackState state, MockNetworkAgent mockAgent) {
        void expectCallback(CallbackState state, MockNetworkAgent mockAgent) {
            waitFor(mConditionVariable);
            CallbackInfo expected = new CallbackInfo(
            assertEquals(state, mLastCallback);
                    state,
            if (mockAgent != null) {
                    (mockAgent != null) ? mockAgent.getNetwork() : null);
                assertEquals(mockAgent.getNetwork(), mLastNetwork);
            CallbackInfo actual;
            try {
                actual = mCallbacks.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS);
            } catch (InterruptedException e) {
                fail("Did not receive expected " + expected + " after " + TIMEOUT_MS + "ms");
                actual = null;  // Or the compiler says it might be uninitialized.
            }
            }
            mLastCallback = CallbackState.NONE;

            mLastNetwork = null;
            assertEquals("Unexpected callback:", expected, actual);
            mConditionVariable.close();
        }
        }


        void assertNoCallback() {
        void assertNoCallback() {
            assertEquals(CallbackState.NONE, mLastCallback);
            mService.waitForIdle();
            CallbackInfo c = mCallbacks.peek();
            assertNull("Unexpected callback: " + c, c);
        }
    }

    // Can't be part of TestNetworkCallback because "cannot be declared static; static methods can
    // only be declared in a static or top level type".
    static void assertNoCallbacks(TestNetworkCallback ... callbacks) {
        for (TestNetworkCallback c : callbacks) {
            c.assertNoCallback();
        }
        }
    }
    }


    @LargeTest
    @LargeTest
    public void testStateChangeNetworkCallbacks() throws Exception {
    public void testStateChangeNetworkCallbacks() throws Exception {
        final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback();
        final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback();
        final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback();
        final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
        final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
        final NetworkRequest genericRequest = new NetworkRequest.Builder()
                .clearCapabilities().build();
        final NetworkRequest wifiRequest = new NetworkRequest.Builder()
        final NetworkRequest wifiRequest = new NetworkRequest.Builder()
                .addTransportType(TRANSPORT_WIFI).build();
                .addTransportType(TRANSPORT_WIFI).build();
        final NetworkRequest cellRequest = new NetworkRequest.Builder()
        final NetworkRequest cellRequest = new NetworkRequest.Builder()
                .addTransportType(TRANSPORT_CELLULAR).build();
                .addTransportType(TRANSPORT_CELLULAR).build();
        mCm.registerNetworkCallback(genericRequest, genericNetworkCallback);
        mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback);
        mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback);
        mCm.registerNetworkCallback(cellRequest, cellNetworkCallback);
        mCm.registerNetworkCallback(cellRequest, cellNetworkCallback);


@@ -1089,65 +1109,74 @@ public class ConnectivityServiceTest extends AndroidTestCase {
        ConditionVariable cv = waitForConnectivityBroadcasts(1);
        ConditionVariable cv = waitForConnectivityBroadcasts(1);
        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
        mCellNetworkAgent.connect(false);
        mCellNetworkAgent.connect(false);
        cellNetworkCallback.expectCallback(CallbackState.AVAILABLE);
        genericNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
        wifiNetworkCallback.assertNoCallback();
        cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
        assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
        assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
        waitFor(cv);
        waitFor(cv);
        assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);


        // This should not trigger spurious onAvailable() callbacks, b/21762680.
        // This should not trigger spurious onAvailable() callbacks, b/21762680.
        mCellNetworkAgent.adjustScore(-1);
        mCellNetworkAgent.adjustScore(-1);
        mService.waitForIdle();
        mService.waitForIdle();
        wifiNetworkCallback.assertNoCallback();
        assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
        cellNetworkCallback.assertNoCallback();
        assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
        assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());


        cv = waitForConnectivityBroadcasts(2);
        cv = waitForConnectivityBroadcasts(2);
        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
        mWiFiNetworkAgent.connect(false);
        mWiFiNetworkAgent.connect(false);
        wifiNetworkCallback.expectCallback(CallbackState.AVAILABLE);
        genericNetworkCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
        cellNetworkCallback.assertNoCallback();
        wifiNetworkCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
        assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
        assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
        waitFor(cv);
        waitFor(cv);
        assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);


        cv = waitForConnectivityBroadcasts(2);
        cv = waitForConnectivityBroadcasts(2);
        mWiFiNetworkAgent.disconnect();
        mWiFiNetworkAgent.disconnect();
        wifiNetworkCallback.expectCallback(CallbackState.LOST);
        genericNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
        wifiNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
        cellNetworkCallback.assertNoCallback();
        cellNetworkCallback.assertNoCallback();
        waitFor(cv);
        waitFor(cv);
        assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);


        cv = waitForConnectivityBroadcasts(1);
        cv = waitForConnectivityBroadcasts(1);
        mCellNetworkAgent.disconnect();
        mCellNetworkAgent.disconnect();
        cellNetworkCallback.expectCallback(CallbackState.LOST);
        genericNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
        wifiNetworkCallback.assertNoCallback();
        cellNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
        waitFor(cv);
        waitFor(cv);
        assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);


        // Test validated networks
        // Test validated networks
        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
        mCellNetworkAgent.connect(true);
        mCellNetworkAgent.connect(true);
        cellNetworkCallback.expectCallback(CallbackState.AVAILABLE);
        genericNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
        wifiNetworkCallback.assertNoCallback();
        cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
        assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
        assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
        assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);


        // This should not trigger spurious onAvailable() callbacks, b/21762680.
        // This should not trigger spurious onAvailable() callbacks, b/21762680.
        mCellNetworkAgent.adjustScore(-1);
        mCellNetworkAgent.adjustScore(-1);
        mService.waitForIdle();
        mService.waitForIdle();
        wifiNetworkCallback.assertNoCallback();
        assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
        cellNetworkCallback.assertNoCallback();
        assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
        assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());


        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
        mWiFiNetworkAgent.connect(true);
        mWiFiNetworkAgent.connect(true);
        wifiNetworkCallback.expectCallback(CallbackState.AVAILABLE);
        genericNetworkCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
        cellNetworkCallback.expectCallback(CallbackState.LOSING);
        genericNetworkCallback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
        wifiNetworkCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
        cellNetworkCallback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
        assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
        assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
        assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);


        mWiFiNetworkAgent.disconnect();
        mWiFiNetworkAgent.disconnect();
        wifiNetworkCallback.expectCallback(CallbackState.LOST);
        genericNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
        cellNetworkCallback.assertNoCallback();
        wifiNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
        assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);


        mCellNetworkAgent.disconnect();
        mCellNetworkAgent.disconnect();
        cellNetworkCallback.expectCallback(CallbackState.LOST);
        genericNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
        wifiNetworkCallback.assertNoCallback();
        cellNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
        assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
    }
    }


    private void tryNetworkFactoryRequests(int capability) throws Exception {
    private void tryNetworkFactoryRequests(int capability) throws Exception {
@@ -1314,7 +1343,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
        mCellNetworkAgent.addCapability(NET_CAPABILITY_MMS);
        mCellNetworkAgent.addCapability(NET_CAPABILITY_MMS);
        mCellNetworkAgent.connectWithoutInternet();
        mCellNetworkAgent.connectWithoutInternet();
        networkCallback.expectCallback(CallbackState.AVAILABLE);
        networkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
        verifyActiveNetwork(TRANSPORT_WIFI);
        verifyActiveNetwork(TRANSPORT_WIFI);
        // Test releasing NetworkRequest disconnects cellular with MMS
        // Test releasing NetworkRequest disconnects cellular with MMS
        cv = mCellNetworkAgent.getDisconnectedCV();
        cv = mCellNetworkAgent.getDisconnectedCV();
@@ -1340,7 +1369,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
        MockNetworkAgent mmsNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
        MockNetworkAgent mmsNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
        mmsNetworkAgent.addCapability(NET_CAPABILITY_MMS);
        mmsNetworkAgent.addCapability(NET_CAPABILITY_MMS);
        mmsNetworkAgent.connectWithoutInternet();
        mmsNetworkAgent.connectWithoutInternet();
        networkCallback.expectCallback(CallbackState.AVAILABLE);
        networkCallback.expectCallback(CallbackState.AVAILABLE, mmsNetworkAgent);
        verifyActiveNetwork(TRANSPORT_CELLULAR);
        verifyActiveNetwork(TRANSPORT_CELLULAR);
        // Test releasing MMS NetworkRequest does not disconnect main cellular NetworkAgent
        // Test releasing MMS NetworkRequest does not disconnect main cellular NetworkAgent
        cv = mmsNetworkAgent.getDisconnectedCV();
        cv = mmsNetworkAgent.getDisconnectedCV();
@@ -1366,36 +1395,36 @@ public class ConnectivityServiceTest extends AndroidTestCase {
        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
        String firstRedirectUrl = "http://example.com/firstPath";
        String firstRedirectUrl = "http://example.com/firstPath";
        mWiFiNetworkAgent.connectWithCaptivePortal(firstRedirectUrl);
        mWiFiNetworkAgent.connectWithCaptivePortal(firstRedirectUrl);
        captivePortalCallback.expectCallback(CallbackState.AVAILABLE);
        captivePortalCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
        assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), firstRedirectUrl);
        assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), firstRedirectUrl);


        // Take down network.
        // Take down network.
        // Expect onLost callback.
        // Expect onLost callback.
        mWiFiNetworkAgent.disconnect();
        mWiFiNetworkAgent.disconnect();
        captivePortalCallback.expectCallback(CallbackState.LOST);
        captivePortalCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);


        // Bring up a network with a captive portal.
        // Bring up a network with a captive portal.
        // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL.
        // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL.
        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
        String secondRedirectUrl = "http://example.com/secondPath";
        String secondRedirectUrl = "http://example.com/secondPath";
        mWiFiNetworkAgent.connectWithCaptivePortal(secondRedirectUrl);
        mWiFiNetworkAgent.connectWithCaptivePortal(secondRedirectUrl);
        captivePortalCallback.expectCallback(CallbackState.AVAILABLE);
        captivePortalCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
        assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), secondRedirectUrl);
        assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), secondRedirectUrl);


        // Make captive portal disappear then revalidate.
        // Make captive portal disappear then revalidate.
        // Expect onLost callback because network no longer provides NET_CAPABILITY_CAPTIVE_PORTAL.
        // Expect onLost callback because network no longer provides NET_CAPABILITY_CAPTIVE_PORTAL.
        mWiFiNetworkAgent.getWrappedNetworkMonitor().gen204ProbeResult = 204;
        mWiFiNetworkAgent.getWrappedNetworkMonitor().gen204ProbeResult = 204;
        mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
        mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
        captivePortalCallback.expectCallback(CallbackState.LOST);
        captivePortalCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);


        // Expect NET_CAPABILITY_VALIDATED onAvailable callback.
        // Expect NET_CAPABILITY_VALIDATED onAvailable callback.
        validatedCallback.expectCallback(CallbackState.AVAILABLE);
        validatedCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);


        // Break network connectivity.
        // Break network connectivity.
        // Expect NET_CAPABILITY_VALIDATED onLost callback.
        // Expect NET_CAPABILITY_VALIDATED onLost callback.
        mWiFiNetworkAgent.getWrappedNetworkMonitor().gen204ProbeResult = 500;
        mWiFiNetworkAgent.getWrappedNetworkMonitor().gen204ProbeResult = 500;
        mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), false);
        mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), false);
        validatedCallback.expectCallback(CallbackState.LOST);
        validatedCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
    }
    }


    @SmallTest
    @SmallTest
@@ -1410,7 +1439,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
            // do nothing - should get here
            // do nothing - should get here
        }
        }


        assertTrue("NetworkReqeuest builder with MATCH_ALL_REQUESTS_NETWORK_SPECIFIER",
        assertTrue("NetworkRequest builder with MATCH_ALL_REQUESTS_NETWORK_SPECIFIER",
                execptionCalled);
                execptionCalled);


        try {
        try {
@@ -1477,6 +1506,78 @@ public class ConnectivityServiceTest extends AndroidTestCase {
        defaultNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
        defaultNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
    }
    }


    @SmallTest
    public void testRequestBenchmark() throws Exception {
        // Benchmarks connecting and switching performance in the presence of a large number of
        // NetworkRequests.
        // 1. File NUM_REQUESTS requests.
        // 2. Have a network connect. Wait for NUM_REQUESTS onAvailable callbacks to fire.
        // 3. Have a new network connect and outscore the previous. Wait for NUM_REQUESTS onLosing
        //    and NUM_REQUESTS onAvailable callbacks to fire.
        // See how long it took.
        final int NUM_REQUESTS = 90;
        final NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build();
        final NetworkCallback[] callbacks = new NetworkCallback[NUM_REQUESTS];
        final CountDownLatch availableLatch = new CountDownLatch(NUM_REQUESTS);
        final CountDownLatch losingLatch = new CountDownLatch(NUM_REQUESTS);

        final int REGISTER_TIME_LIMIT_MS = 100;
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < NUM_REQUESTS; i++) {
            callbacks[i] = new NetworkCallback() {
                @Override public void onAvailable(Network n) { availableLatch.countDown(); }
                @Override public void onLosing(Network n, int t) { losingLatch.countDown(); }
            };
            mCm.registerNetworkCallback(request, callbacks[i]);
        }
        long timeTaken = System.currentTimeMillis() - startTime;
        String msg = String.format("Register %d callbacks: %dms, acceptable %dms",
                NUM_REQUESTS, timeTaken, REGISTER_TIME_LIMIT_MS);
        Log.d(TAG, msg);
        assertTrue(msg, timeTaken < REGISTER_TIME_LIMIT_MS);

        final int CONNECT_TIME_LIMIT_MS = 30;
        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
        // Don't request that the network validate, because otherwise connect() will block until
        // the network gets NET_CAPABILITY_VALIDATED, after all the callbacks below have fired,
        // and we won't actually measure anything.
        mCellNetworkAgent.connect(false);
        startTime = System.currentTimeMillis();
        if (!availableLatch.await(CONNECT_TIME_LIMIT_MS, TimeUnit.MILLISECONDS)) {
            fail(String.format("Only dispatched %d/%d onAvailable callbacks in %dms",
                    NUM_REQUESTS - availableLatch.getCount(), NUM_REQUESTS,
                    CONNECT_TIME_LIMIT_MS));
        }
        timeTaken = System.currentTimeMillis() - startTime;
        Log.d(TAG, String.format("Connect, %d callbacks: %dms, acceptable %dms",
                NUM_REQUESTS, timeTaken, CONNECT_TIME_LIMIT_MS));

        final int SWITCH_TIME_LIMIT_MS = 30;
        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
        // Give wifi a high enough score that we'll linger cell when wifi comes up.
        mWiFiNetworkAgent.adjustScore(40);
        mWiFiNetworkAgent.connect(false);
        startTime = System.currentTimeMillis();
        if (!losingLatch.await(SWITCH_TIME_LIMIT_MS, TimeUnit.MILLISECONDS)) {
            fail(String.format("Only dispatched %d/%d onLosing callbacks in %dms",
                    NUM_REQUESTS - losingLatch.getCount(), NUM_REQUESTS, SWITCH_TIME_LIMIT_MS));
        }
        timeTaken = System.currentTimeMillis() - startTime;
        Log.d(TAG, String.format("Linger, %d callbacks: %dms, acceptable %dms",
                NUM_REQUESTS, timeTaken, SWITCH_TIME_LIMIT_MS));

        final int UNREGISTER_TIME_LIMIT_MS = 10;
        startTime = System.currentTimeMillis();
        for (int i = 0; i < NUM_REQUESTS; i++) {
            mCm.unregisterNetworkCallback(callbacks[i]);
        }
        timeTaken = System.currentTimeMillis() - startTime;
        msg = String.format("Unregister %d callbacks: %dms, acceptable %dms",
                NUM_REQUESTS, timeTaken, UNREGISTER_TIME_LIMIT_MS);
        Log.d(TAG, msg);
        assertTrue(msg, timeTaken < UNREGISTER_TIME_LIMIT_MS);
    }

    @SmallTest
    @SmallTest
    public void testMobileDataAlwaysOn() throws Exception {
    public void testMobileDataAlwaysOn() throws Exception {
        final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
        final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
@@ -1520,7 +1621,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
        testFactory.expectAddRequests(2);  // Because the cell request changes score twice.
        testFactory.expectAddRequests(2);  // Because the cell request changes score twice.
        mCellNetworkAgent.connect(true);
        mCellNetworkAgent.connect(true);
        cellNetworkCallback.expectCallback(CallbackState.AVAILABLE);
        cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
        testFactory.waitForNetworkRequests(2);
        testFactory.waitForNetworkRequests(2);
        assertFalse(testFactory.getMyStartRequested());  // Because the cell network outscores us.
        assertFalse(testFactory.getMyStartRequested());  // Because the cell network outscores us.


@@ -1536,7 +1637,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
        testFactory.waitForNetworkRequests(1);
        testFactory.waitForNetworkRequests(1);


        // ...  and cell data to be torn down.
        // ...  and cell data to be torn down.
        cellNetworkCallback.expectCallback(CallbackState.LOST);
        cellNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
        assertEquals(1, mCm.getAllNetworks().length);
        assertEquals(1, mCm.getAllNetworks().length);


        testFactory.unregister();
        testFactory.unregister();