[NS06] Implement the don't-reap mechanism

This exposes a mechanism for network providers to tell
the network stack that a given network must be kept up
for some specific reason. This is meant to be easier
for them than to have to file a request, in particular
because there is no guaranteed way to make sure the
request will be best matched by any given network.

Test: new test for this
Bug: 167544279
Merged-In: I3c2563d4ae4e3715d0c6270344ba8f7ef067872f
Merged-In: I238a3ee5ee9262477a23b897e4141769dd1505d1
Change-Id: I238a3ee5ee9262477a23b897e4141769dd1505d1
  (cherry-picked from ag/13929760)
This commit is contained in:
Chalard Jean
2021-03-08 22:29:27 +09:00
committed by Junyu Lai
parent 5c3bb5b1ce
commit 947acd4275
8 changed files with 171 additions and 18 deletions

View File

@@ -104,6 +104,7 @@ import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE;
import static android.net.NetworkScore.KEEP_CONNECTED_FOR_HANDOVER;
import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID;
import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK;
import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY;
@@ -10226,6 +10227,83 @@ public class ConnectivityServiceTest {
}
}
@Test
public void testKeepConnected() throws Exception {
setAlwaysOnNetworks(false);
registerDefaultNetworkCallbacks();
final TestNetworkCallback allNetworksCb = new TestNetworkCallback();
final NetworkRequest allNetworksRequest = new NetworkRequest.Builder().clearCapabilities()
.build();
mCm.registerNetworkCallback(allNetworksRequest, allNetworksCb);
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
mCellNetworkAgent.connect(true /* validated */);
mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
allNetworksCb.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
mWiFiNetworkAgent.connect(true /* validated */);
mDefaultNetworkCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent);
// While the default callback doesn't see the network before it's validated, the listen
// sees the network come up and validate later
allNetworksCb.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
allNetworksCb.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
allNetworksCb.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
allNetworksCb.expectCallback(CallbackEntry.LOST, mCellNetworkAgent,
TEST_LINGER_DELAY_MS * 2);
// The cell network has disconnected (see LOST above) because it was outscored and
// had no requests (see setAlwaysOnNetworks(false) above)
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
final NetworkScore score = new NetworkScore.Builder().setLegacyInt(30).build();
mCellNetworkAgent.setScore(score);
mCellNetworkAgent.connect(false /* validated */);
// The cell network gets torn down right away.
allNetworksCb.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
allNetworksCb.expectCallback(CallbackEntry.LOST, mCellNetworkAgent,
TEST_NASCENT_DELAY_MS * 2);
allNetworksCb.assertNoCallback();
// Now create a cell network with KEEP_CONNECTED_FOR_HANDOVER and make sure it's
// not disconnected immediately when outscored.
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
final NetworkScore scoreKeepup = new NetworkScore.Builder().setLegacyInt(30)
.setKeepConnectedReason(KEEP_CONNECTED_FOR_HANDOVER).build();
mCellNetworkAgent.setScore(scoreKeepup);
mCellNetworkAgent.connect(true /* validated */);
allNetworksCb.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
mDefaultNetworkCallback.assertNoCallback();
mWiFiNetworkAgent.disconnect();
allNetworksCb.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
mDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
// Reconnect a WiFi network and make sure the cell network is still not torn down.
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
mWiFiNetworkAgent.connect(true /* validated */);
allNetworksCb.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent);
mDefaultNetworkCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent);
// Now remove the reason to keep connected and make sure the network lingers and is
// torn down.
mCellNetworkAgent.setScore(new NetworkScore.Builder().setLegacyInt(30).build());
allNetworksCb.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent,
TEST_NASCENT_DELAY_MS * 2);
allNetworksCb.expectCallback(CallbackEntry.LOST, mCellNetworkAgent,
TEST_LINGER_DELAY_MS * 2);
mDefaultNetworkCallback.assertNoCallback();
mCm.unregisterNetworkCallback(allNetworksCb);
// mDefaultNetworkCallback will be unregistered by tearDown()
}
private class QosCallbackMockHelper {
@NonNull public final QosFilter mFilter;
@NonNull public final IQosCallback mCallback;

View File

@@ -18,6 +18,7 @@ package com.android.server.connectivity
import android.net.NetworkAgentConfig
import android.net.NetworkCapabilities
import android.net.NetworkScore.KEEP_CONNECTED_NONE
import android.text.TextUtils
import android.util.ArraySet
import androidx.test.filters.SmallTest
@@ -60,11 +61,11 @@ class FullScoreTest {
@Test
fun testGetLegacyInt() {
val ns = FullScore(50, 0L /* policy */)
val ns = FullScore(50, 0L /* policy */, KEEP_CONNECTED_NONE)
assertEquals(10, ns.legacyInt) // -40 penalty for not being validated
assertEquals(50, ns.legacyIntAsValidated)
val vpnNs = FullScore(101, 0L /* policy */).withPolicies(vpn = true)
val vpnNs = FullScore(101, 0L /* policy */, KEEP_CONNECTED_NONE).withPolicies(vpn = true)
assertEquals(101, vpnNs.legacyInt) // VPNs are not subject to unvalidation penalty
assertEquals(101, vpnNs.legacyIntAsValidated)
assertEquals(101, vpnNs.withPolicies(validated = true).legacyInt)
@@ -83,7 +84,7 @@ class FullScoreTest {
@Test
fun testToString() {
val string = FullScore(10, 0L /* policy */)
val string = FullScore(10, 0L /* policy */, KEEP_CONNECTED_NONE)
.withPolicies(vpn = true, acceptUnvalidated = true).toString()
assertTrue(string.contains("Score(10"), string)
assertTrue(string.contains("ACCEPT_UNVALIDATED"), string)
@@ -107,7 +108,7 @@ class FullScoreTest {
@Test
fun testHasPolicy() {
val ns = FullScore(50, 0L /* policy */)
val ns = FullScore(50, 0L /* policy */, KEEP_CONNECTED_NONE)
assertFalse(ns.hasPolicy(POLICY_IS_VALIDATED))
assertFalse(ns.hasPolicy(POLICY_IS_VPN))
assertFalse(ns.hasPolicy(POLICY_EVER_USER_SELECTED))

View File

@@ -19,6 +19,7 @@ package com.android.server.connectivity
import android.net.INetworkOfferCallback
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import android.net.NetworkScore.KEEP_CONNECTED_NONE
import androidx.test.filters.SmallTest
import androidx.test.runner.AndroidJUnit4
import org.junit.Test
@@ -38,7 +39,7 @@ class NetworkOfferTest {
@Test
fun testOfferNeededUnneeded() {
val score = FullScore(50, POLICY_NONE)
val score = FullScore(50, POLICY_NONE, KEEP_CONNECTED_NONE)
val offer = NetworkOffer(score, NetworkCapabilities.Builder().build(), mockCallback,
1 /* providerId */)
val request1 = mock(NetworkRequest::class.java)