diff options
| -rw-r--r-- | services/core/java/com/android/server/connectivity/NetworkAgentInfo.java | 11 | ||||
| -rw-r--r-- | tests/net/java/com/android/server/ConnectivityServiceTest.java | 66 |
2 files changed, 69 insertions, 8 deletions
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java index 14b234d833c2..505480ea537e 100644 --- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java +++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java @@ -384,12 +384,15 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> { /** * Returns whether the network is a background network. A network is a background network if it - * is satisfying no foreground requests and at least one background request. (If it did not have - * a background request, it would be a speculative network that is only being kept up because - * it might satisfy a request if it validated). + * does not have the NET_CAPABILITY_FOREGROUND capability, which implies it is satisfying no + * foreground request, is not lingering (i.e. kept for a while after being outscored), and is + * not a speculative network (i.e. kept pending validation when validation would have it + * outscore another foreground network). That implies it is being kept up by some background + * request (otherwise it would be torn down), maybe the mobile always-on request. */ public boolean isBackgroundNetwork() { - return !isVPN() && numForegroundNetworkRequests() == 0 && mNumBackgroundNetworkRequests > 0; + return !isVPN() && numForegroundNetworkRequests() == 0 && mNumBackgroundNetworkRequests > 0 + && !isLingering(); } /** diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 24639e9e3f76..39daeabac37f 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -50,6 +50,7 @@ import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE; import static com.android.internal.util.TestUtils.waitForIdleHandler; +import static com.android.internal.util.TestUtils.waitForIdleLooper; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -85,6 +86,7 @@ import android.net.ConnectivityManager.NetworkCallback; import android.net.ConnectivityManager.PacketKeepalive; import android.net.ConnectivityManager.PacketKeepaliveCallback; import android.net.ConnectivityManager.TooManyRequestsException; +import android.net.ConnectivityThread; import android.net.INetworkPolicyManager; import android.net.INetworkStatsService; import android.net.IpPrefix; @@ -279,6 +281,7 @@ public class ConnectivityServiceTest { waitForIdle(mWiFiNetworkAgent, timeoutMs); waitForIdle(mEthernetNetworkAgent, timeoutMs); waitForIdleHandler(mService.mHandlerThread, timeoutMs); + waitForIdleLooper(ConnectivityThread.getInstanceLooper(), timeoutMs); } public void waitForIdle(MockNetworkAgent agent, long timeoutMs) { @@ -1438,9 +1441,9 @@ public class ConnectivityServiceTest { expectCallback(CallbackState.SUSPENDED, agent, timeoutMs); } if (expectValidated) { - expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, agent); + expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, agent, timeoutMs); } else { - expectCapabilitiesWithout(NET_CAPABILITY_VALIDATED, agent); + expectCapabilitiesWithout(NET_CAPABILITY_VALIDATED, agent, timeoutMs); } expectCallback(CallbackState.LINK_PROPERTIES, agent, timeoutMs); } @@ -1479,14 +1482,24 @@ public class ConnectivityServiceTest { } NetworkCapabilities expectCapabilitiesWith(int capability, MockNetworkAgent agent) { - CallbackInfo cbi = expectCallback(CallbackState.NETWORK_CAPABILITIES, agent); + return expectCapabilitiesWith(capability, agent, TIMEOUT_MS); + } + + NetworkCapabilities expectCapabilitiesWith(int capability, MockNetworkAgent agent, + int timeoutMs) { + CallbackInfo cbi = expectCallback(CallbackState.NETWORK_CAPABILITIES, agent, timeoutMs); NetworkCapabilities nc = (NetworkCapabilities) cbi.arg; assertTrue(nc.hasCapability(capability)); return nc; } NetworkCapabilities expectCapabilitiesWithout(int capability, MockNetworkAgent agent) { - CallbackInfo cbi = expectCallback(CallbackState.NETWORK_CAPABILITIES, agent); + return expectCapabilitiesWithout(capability, agent, TIMEOUT_MS); + } + + NetworkCapabilities expectCapabilitiesWithout(int capability, MockNetworkAgent agent, + int timeoutMs) { + CallbackInfo cbi = expectCallback(CallbackState.NETWORK_CAPABILITIES, agent, timeoutMs); NetworkCapabilities nc = (NetworkCapabilities) cbi.arg; assertFalse(nc.hasCapability(capability)); return nc; @@ -1831,6 +1844,51 @@ public class ConnectivityServiceTest { } @Test + public void testNetworkGoesIntoBackgroundAfterLinger() { + setMobileDataAlwaysOn(true); + NetworkRequest request = new NetworkRequest.Builder() + .clearCapabilities() + .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); + + mCellNetworkAgent.connect(true); + callback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); + defaultCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); + + // Wifi comes up and cell lingers. + mWiFiNetworkAgent.connect(true); + defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent); + callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent); + callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent); + callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent); + + // File a request for cellular, then release it. + NetworkRequest cellRequest = new NetworkRequest.Builder() + .addTransportType(TRANSPORT_CELLULAR).build(); + NetworkCallback noopCallback = new NetworkCallback(); + mCm.requestNetwork(cellRequest, noopCallback); + mCm.unregisterNetworkCallback(noopCallback); + callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent); + + // Let linger run its course. + callback.assertNoCallback(); + final int lingerTimeoutMs = TEST_LINGER_DELAY_MS + TEST_LINGER_DELAY_MS / 4; + callback.expectCapabilitiesWithout(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent, + lingerTimeoutMs); + + // Clean up. + mCm.unregisterNetworkCallback(defaultCallback); + mCm.unregisterNetworkCallback(callback); + } + + @Test public void testExplicitlySelected() { NetworkRequest request = new NetworkRequest.Builder() .clearCapabilities().addCapability(NET_CAPABILITY_INTERNET) |