diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index e8a87c7ca5..9c98efa202 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -116,7 +116,7 @@ import java.util.function.BooleanSupplier; * Tests for {@link ConnectivityService}. * * Build, install and run with: - * runtest frameworks-services -c com.android.server.ConnectivityServiceTest + * runtest frameworks-net -c com.android.server.ConnectivityServiceTest */ public class ConnectivityServiceTest extends AndroidTestCase { private static final String TAG = "ConnectivityServiceTest"; @@ -224,13 +224,32 @@ public class ConnectivityServiceTest extends AndroidTestCase { } } + public void waitForIdle(int timeoutMs) { + waitForIdleHandler(mService.mHandlerThread, timeoutMs); + waitForIdle(mCellNetworkAgent, timeoutMs); + waitForIdle(mWiFiNetworkAgent, timeoutMs); + waitForIdle(mEthernetNetworkAgent, timeoutMs); + waitForIdleHandler(mService.mHandlerThread, timeoutMs); + } + + public void waitForIdle(MockNetworkAgent agent, int timeoutMs) { + if (agent == null) { + return; + } + waitForIdleHandler(agent.mHandlerThread, timeoutMs); + } + + private void waitForIdle() { + waitForIdle(TIMEOUT_MS); + } + @SmallTest public void testWaitForIdle() { final int attempts = 50; // Causes the test to take about 200ms on bullhead-eng. // Tests that waitForIdle returns immediately if the service is already idle. for (int i = 0; i < attempts; i++) { - mService.waitForIdle(); + waitForIdle(); } // Bring up a network that we can use to send messages to ConnectivityService. @@ -244,7 +263,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { // Tests that calling waitForIdle waits for messages to be processed. for (int i = 0; i < attempts; i++) { mWiFiNetworkAgent.setSignalStrength(i); - mService.waitForIdle(); + waitForIdle(); assertEquals(i, mCm.getNetworkCapabilities(n).getSignalStrength()); } } @@ -345,18 +364,10 @@ public class ConnectivityServiceTest extends AndroidTestCase { }; // Waits for the NetworkAgent to be registered, which includes the creation of the // NetworkMonitor. - mService.waitForIdle(); + waitForIdle(); mWrappedNetworkMonitor = mService.getLastCreatedWrappedNetworkMonitor(); } - public void waitForIdle(int timeoutMs) { - waitForIdleHandler(mHandlerThread, timeoutMs); - } - - public void waitForIdle() { - waitForIdle(TIMEOUT_MS); - } - public void adjustScore(int change) { mScore += change; mNetworkAgent.sendNetworkScore(mScore); @@ -806,13 +817,22 @@ public class ConnectivityServiceTest extends AndroidTestCase { public void tearDown() throws Exception { setMobileDataAlwaysOn(false); - if (mCellNetworkAgent != null) { mCellNetworkAgent.disconnect(); } - if (mWiFiNetworkAgent != null) { mWiFiNetworkAgent.disconnect(); } - mCellNetworkAgent = mWiFiNetworkAgent = null; + if (mCellNetworkAgent != null) { + mCellNetworkAgent.disconnect(); + mCellNetworkAgent = null; + } + if (mWiFiNetworkAgent != null) { + mWiFiNetworkAgent.disconnect(); + mWiFiNetworkAgent = null; + } + if (mEthernetNetworkAgent != null) { + mEthernetNetworkAgent.disconnect(); + mEthernetNetworkAgent = null; + } super.tearDown(); } - private int transportToLegacyType(int transport) { + private static int transportToLegacyType(int transport) { switch (transport) { case TRANSPORT_ETHERNET: return TYPE_ETHERNET; @@ -844,7 +864,8 @@ public class ConnectivityServiceTest extends AndroidTestCase { } // Test getNetworkInfo(Network) assertNotNull(mCm.getNetworkInfo(mCm.getActiveNetwork())); - assertEquals(transportToLegacyType(transport), mCm.getNetworkInfo(mCm.getActiveNetwork()).getType()); + assertEquals(transportToLegacyType(transport), + mCm.getNetworkInfo(mCm.getActiveNetwork()).getType()); // Test getNetworkCapabilities(Network) assertNotNull(mCm.getNetworkCapabilities(mCm.getActiveNetwork())); assertTrue(mCm.getNetworkCapabilities(mCm.getActiveNetwork()).hasTransport(transport)); @@ -915,7 +936,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { mCm.getAllNetworks()[1].equals(mCellNetworkAgent.getNetwork())); // Test cellular linger timeout. waitFor(mCellNetworkAgent.getDisconnectedCV()); - mService.waitForIdle(); + waitForIdle(); assertEquals(1, mCm.getAllNetworks().length); verifyActiveNetwork(TRANSPORT_WIFI); assertEquals(1, mCm.getAllNetworks().length); @@ -938,11 +959,11 @@ public class ConnectivityServiceTest extends AndroidTestCase { // Test bringing up unvalidated cellular mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); mCellNetworkAgent.connect(false); - mService.waitForIdle(); + waitForIdle(); verifyActiveNetwork(TRANSPORT_WIFI); // Test cellular disconnect. mCellNetworkAgent.disconnect(); - mService.waitForIdle(); + waitForIdle(); verifyActiveNetwork(TRANSPORT_WIFI); // Test bringing up validated cellular mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); @@ -1294,7 +1315,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { } void assertNoCallback() { - mService.waitForIdle(); + waitForIdle(); CallbackInfo c = mCallbacks.peek(); assertNull("Unexpected callback: " + c, c); } @@ -1335,7 +1356,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { // This should not trigger spurious onAvailable() callbacks, b/21762680. mCellNetworkAgent.adjustScore(-1); - mService.waitForIdle(); + waitForIdle(); assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); @@ -1373,7 +1394,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { // This should not trigger spurious onAvailable() callbacks, b/21762680. mCellNetworkAgent.adjustScore(-1); - mService.waitForIdle(); + waitForIdle(); assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback); assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); @@ -1485,7 +1506,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { defaultCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent); mCm.unregisterNetworkCallback(callback); - mService.waitForIdle(); + waitForIdle(); // Check that a network is only lingered or torn down if it would not satisfy a request even // if it validated. @@ -1846,26 +1867,30 @@ public class ConnectivityServiceTest extends AndroidTestCase { ConditionVariable cv = mCellNetworkAgent.getDisconnectedCV(); mCellNetworkAgent.connectWithoutInternet(); waitFor(cv); - mService.waitForIdle(); + waitForIdle(); assertEquals(0, mCm.getAllNetworks().length); verifyNoNetwork(); + // Test bringing up validated WiFi. mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); cv = waitForConnectivityBroadcasts(1); mWiFiNetworkAgent.connect(true); waitFor(cv); verifyActiveNetwork(TRANSPORT_WIFI); + // Register MMS NetworkRequest NetworkRequest.Builder builder = new NetworkRequest.Builder(); builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS); final TestNetworkCallback networkCallback = new TestNetworkCallback(); mCm.requestNetwork(builder.build(), networkCallback); + // Test bringing up unvalidated cellular with MMS mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); mCellNetworkAgent.addCapability(NET_CAPABILITY_MMS); mCellNetworkAgent.connectWithoutInternet(); networkCallback.expectAvailableCallbacks(mCellNetworkAgent); verifyActiveNetwork(TRANSPORT_WIFI); + // Test releasing NetworkRequest disconnects cellular with MMS cv = mCellNetworkAgent.getDisconnectedCV(); mCm.unregisterNetworkCallback(networkCallback); @@ -1881,17 +1906,20 @@ public class ConnectivityServiceTest extends AndroidTestCase { mCellNetworkAgent.connect(false); waitFor(cv); verifyActiveNetwork(TRANSPORT_CELLULAR); + // Register MMS NetworkRequest NetworkRequest.Builder builder = new NetworkRequest.Builder(); builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS); final TestNetworkCallback networkCallback = new TestNetworkCallback(); mCm.requestNetwork(builder.build(), networkCallback); + // Test bringing up MMS cellular network MockNetworkAgent mmsNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); mmsNetworkAgent.addCapability(NET_CAPABILITY_MMS); mmsNetworkAgent.connectWithoutInternet(); networkCallback.expectAvailableCallbacks(mmsNetworkAgent); verifyActiveNetwork(TRANSPORT_CELLULAR); + // Test releasing MMS NetworkRequest does not disconnect main cellular NetworkAgent cv = mmsNetworkAgent.getDisconnectedCV(); mCm.unregisterNetworkCallback(networkCallback); @@ -2298,7 +2326,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { ContentResolver cr = mServiceContext.getContentResolver(); Settings.Global.putInt(cr, Settings.Global.MOBILE_DATA_ALWAYS_ON, enable ? 1 : 0); mService.updateMobileDataAlwaysOn(); - mService.waitForIdle(); + waitForIdle(); } private boolean isForegroundNetwork(MockNetworkAgent network) { @@ -2340,7 +2368,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { assertTrue(isForegroundNetwork(mWiFiNetworkAgent)); // When lingering is complete, cell is still there but is now in the background. - mService.waitForIdle(); + waitForIdle(); int timeoutMs = TEST_LINGER_DELAY_MS + TEST_LINGER_DELAY_MS / 4; fgCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent, timeoutMs); // Expect a network capabilities update sans FOREGROUND. @@ -2396,6 +2424,11 @@ public class ConnectivityServiceTest extends AndroidTestCase { // and NUM_REQUESTS onAvailable callbacks to fire. // See how long it took. final int NUM_REQUESTS = 90; + final int REGISTER_TIME_LIMIT_MS = 180; + final int CONNECT_TIME_LIMIT_MS = 50; + final int SWITCH_TIME_LIMIT_MS = 50; + final int UNREGISTER_TIME_LIMIT_MS = 20; + final NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build(); final NetworkCallback[] callbacks = new NetworkCallback[NUM_REQUESTS]; final CountDownLatch availableLatch = new CountDownLatch(NUM_REQUESTS); @@ -2408,14 +2441,12 @@ public class ConnectivityServiceTest extends AndroidTestCase { }; } - final int REGISTER_TIME_LIMIT_MS = 180; assertTimeLimit("Registering callbacks", REGISTER_TIME_LIMIT_MS, () -> { for (NetworkCallback cb : callbacks) { mCm.registerNetworkCallback(request, cb); } }); - final int CONNECT_TIME_LIMIT_MS = 40; 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, @@ -2423,31 +2454,29 @@ public class ConnectivityServiceTest extends AndroidTestCase { mCellNetworkAgent.connect(false); long onAvailableDispatchingDuration = durationOf(() -> { - if (!awaitLatch(availableLatch, CONNECT_TIME_LIMIT_MS)) { - fail(String.format("Only dispatched %d/%d onAvailable callbacks in %dms", - NUM_REQUESTS - availableLatch.getCount(), NUM_REQUESTS, - CONNECT_TIME_LIMIT_MS)); - } + awaitLatch(availableLatch, 10 * CONNECT_TIME_LIMIT_MS); }); - Log.d(TAG, String.format("Connect, %d callbacks: %dms, acceptable %dms", - NUM_REQUESTS, onAvailableDispatchingDuration, CONNECT_TIME_LIMIT_MS)); + Log.d(TAG, String.format("Dispatched %d of %d onAvailable callbacks in %dms", + NUM_REQUESTS - availableLatch.getCount(), NUM_REQUESTS, + onAvailableDispatchingDuration)); + assertTrue(String.format("Dispatching %d onAvailable callbacks in %dms, expected %dms", + NUM_REQUESTS, onAvailableDispatchingDuration, CONNECT_TIME_LIMIT_MS), + onAvailableDispatchingDuration <= CONNECT_TIME_LIMIT_MS); - final int SWITCH_TIME_LIMIT_MS = 40; - mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); // Give wifi a high enough score that we'll linger cell when wifi comes up. + mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); mWiFiNetworkAgent.adjustScore(40); mWiFiNetworkAgent.connect(false); long onLostDispatchingDuration = durationOf(() -> { - if (!awaitLatch(losingLatch, SWITCH_TIME_LIMIT_MS)) { - fail(String.format("Only dispatched %d/%d onLosing callbacks in %dms", - NUM_REQUESTS - losingLatch.getCount(), NUM_REQUESTS, SWITCH_TIME_LIMIT_MS)); - } + awaitLatch(losingLatch, 10 * SWITCH_TIME_LIMIT_MS); }); - Log.d(TAG, String.format("Linger, %d callbacks: %dms, acceptable %dms", - NUM_REQUESTS, onLostDispatchingDuration, SWITCH_TIME_LIMIT_MS)); + Log.d(TAG, String.format("Dispatched %d of %d onLosing callbacks in %dms", + NUM_REQUESTS - losingLatch.getCount(), NUM_REQUESTS, onLostDispatchingDuration)); + assertTrue(String.format("Dispatching %d onLosing callbacks in %dms, expected %dms", + NUM_REQUESTS, onLostDispatchingDuration, SWITCH_TIME_LIMIT_MS), + onLostDispatchingDuration <= SWITCH_TIME_LIMIT_MS); - final int UNREGISTER_TIME_LIMIT_MS = 10; assertTimeLimit("Unregistering callbacks", UNREGISTER_TIME_LIMIT_MS, () -> { for (NetworkCallback cb : callbacks) { mCm.unregisterNetworkCallback(cb); @@ -2470,9 +2499,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { private boolean awaitLatch(CountDownLatch l, long timeoutMs) { try { - if (l.await(timeoutMs, TimeUnit.MILLISECONDS)) { - return true; - } + return l.await(timeoutMs, TimeUnit.MILLISECONDS); } catch (InterruptedException e) {} return false; } @@ -2524,7 +2551,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { assertFalse(testFactory.getMyStartRequested()); // Because the cell network outscores us. // Check that cell data stays up. - mService.waitForIdle(); + waitForIdle(); verifyActiveNetwork(TRANSPORT_WIFI); assertEquals(2, mCm.getAllNetworks().length); @@ -2553,7 +2580,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { for (int i = 0; i < values.length; i++) { Settings.Global.putInt(cr, settingName, 1); tracker.reevaluate(); - mService.waitForIdle(); + waitForIdle(); String msg = String.format("config=false, setting=%s", values[i]); assertTrue(mService.avoidBadWifi()); assertFalse(msg, tracker.shouldNotifyWifiUnvalidated()); @@ -2563,19 +2590,19 @@ public class ConnectivityServiceTest extends AndroidTestCase { Settings.Global.putInt(cr, settingName, 0); tracker.reevaluate(); - mService.waitForIdle(); + waitForIdle(); assertFalse(mService.avoidBadWifi()); assertFalse(tracker.shouldNotifyWifiUnvalidated()); Settings.Global.putInt(cr, settingName, 1); tracker.reevaluate(); - mService.waitForIdle(); + waitForIdle(); assertTrue(mService.avoidBadWifi()); assertFalse(tracker.shouldNotifyWifiUnvalidated()); Settings.Global.putString(cr, settingName, null); tracker.reevaluate(); - mService.waitForIdle(); + waitForIdle(); assertFalse(mService.avoidBadWifi()); assertTrue(tracker.shouldNotifyWifiUnvalidated()); } @@ -2718,7 +2745,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { tracker.configMeteredMultipathPreference = config; Settings.Global.putString(cr, settingName, setting); tracker.reevaluate(); - mService.waitForIdle(); + waitForIdle(); final int expected = (setting != null) ? Integer.parseInt(setting) : config; String msg = String.format("config=%d, setting=%s", config, setting); @@ -2906,7 +2933,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { waitFor(cv); verifyActiveNetwork(TRANSPORT_WIFI); mWiFiNetworkAgent.sendLinkProperties(lp); - mService.waitForIdle(); + waitForIdle(); return mWiFiNetworkAgent.getNetwork(); } @@ -2985,7 +3012,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { callback.expectError(PacketKeepalive.ERROR_INVALID_NETWORK); // ... and that stopping it after that has no adverse effects. - mService.waitForIdle(); + waitForIdle(); final Network myNetAlias = myNet; assertNull(mCm.getNetworkCapabilities(myNetAlias)); ka.stop(); @@ -3000,7 +3027,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { ka.stop(); mWiFiNetworkAgent.disconnect(); waitFor(mWiFiNetworkAgent.getDisconnectedCV()); - mService.waitForIdle(); + waitForIdle(); callback.expectStopped(); // Reconnect. @@ -3201,7 +3228,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { mCm.unregisterNetworkCallback(pendingIntent); } pendingIntents.clear(); - mService.waitForIdle(5000); + waitForIdle(5000); // Test that the limit is not hit when MAX_REQUESTS requests are added and removed. for (int i = 0; i < MAX_REQUESTS; i++) { @@ -3209,20 +3236,20 @@ public class ConnectivityServiceTest extends AndroidTestCase { mCm.requestNetwork(networkRequest, networkCallback); mCm.unregisterNetworkCallback(networkCallback); } - mService.waitForIdle(); + waitForIdle(); for (int i = 0; i < MAX_REQUESTS; i++) { NetworkCallback networkCallback = new NetworkCallback(); mCm.registerNetworkCallback(networkRequest, networkCallback); mCm.unregisterNetworkCallback(networkCallback); } - mService.waitForIdle(); + waitForIdle(); for (int i = 0; i < MAX_REQUESTS; i++) { PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent("b" + i), 0); mCm.requestNetwork(networkRequest, pendingIntent); mCm.unregisterNetworkCallback(pendingIntent); } - mService.waitForIdle(); + waitForIdle(); for (int i = 0; i < MAX_REQUESTS; i++) { PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent("c" + i), 0);