Merge "Add tests for the network blocked status change"
am: af0de1a2e9
Change-Id: I0f3f93807d9089239f572c487d791acd7a324a2e
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 4ce9016..1c8d99a 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -934,7 +934,8 @@
registerPrivateDnsSettingsCallbacks();
}
- private Tethering makeTethering() {
+ @VisibleForTesting
+ protected Tethering makeTethering() {
// TODO: Move other elements into @Overridden getters.
final TetheringDependencies deps = new TetheringDependencies() {
@Override
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index 17babe9..39b6391 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -26,13 +26,21 @@
import static android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND;
import static android.net.NetworkPolicyManager.POLICY_NONE;
import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
+import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
+import static android.net.NetworkPolicyManager.RULE_ALLOW_METERED;
+import static android.net.NetworkPolicyManager.RULE_NONE;
+import static android.net.NetworkPolicyManager.RULE_REJECT_ALL;
+import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
+import static android.net.NetworkPolicyManager.RULE_TEMPORARY_ALLOW_METERED;
import static android.net.NetworkPolicyManager.uidPoliciesToString;
+import static android.net.NetworkPolicyManager.uidRulesToString;
import static android.net.NetworkStats.IFACE_ALL;
import static android.net.NetworkStats.SET_ALL;
import static android.net.NetworkStats.TAG_ALL;
import static android.net.NetworkTemplate.buildTemplateMobileAll;
import static android.net.NetworkTemplate.buildTemplateWifi;
import static android.net.TrafficStats.MB_IN_BYTES;
+import static android.os.Process.SYSTEM_UID;
import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
import static android.telephony.CarrierConfigManager.DATA_CYCLE_THRESHOLD_DISABLED;
import static android.telephony.CarrierConfigManager.DATA_CYCLE_USE_PLATFORM_DEFAULT;
@@ -125,6 +133,7 @@
import android.text.format.Time;
import android.util.DataUnit;
import android.util.Log;
+import android.util.Pair;
import android.util.Range;
import android.util.RecurrenceRule;
@@ -169,6 +178,7 @@
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Iterator;
@@ -1642,6 +1652,76 @@
true);
}
+ /**
+ * Exhaustively test isUidNetworkingBlocked to output the expected results based on external
+ * conditions.
+ */
+ @Test
+ public void testIsUidNetworkingBlocked() {
+ final ArrayList<Pair<Boolean, Integer>> expectedBlockedStates = new ArrayList<>();
+
+ // Metered network. Data saver on.
+ expectedBlockedStates.add(new Pair<>(true, RULE_NONE));
+ expectedBlockedStates.add(new Pair<>(false, RULE_ALLOW_METERED));
+ expectedBlockedStates.add(new Pair<>(false, RULE_TEMPORARY_ALLOW_METERED));
+ expectedBlockedStates.add(new Pair<>(true, RULE_REJECT_METERED));
+ expectedBlockedStates.add(new Pair<>(true, RULE_ALLOW_ALL));
+ expectedBlockedStates.add(new Pair<>(true, RULE_REJECT_ALL));
+ verifyNetworkBlockedState(
+ true /* metered */, true /* backgroundRestricted */, expectedBlockedStates);
+ expectedBlockedStates.clear();
+
+ // Metered network. Data saver off.
+ expectedBlockedStates.add(new Pair<>(false, RULE_NONE));
+ expectedBlockedStates.add(new Pair<>(false, RULE_ALLOW_METERED));
+ expectedBlockedStates.add(new Pair<>(false, RULE_TEMPORARY_ALLOW_METERED));
+ expectedBlockedStates.add(new Pair<>(true, RULE_REJECT_METERED));
+ expectedBlockedStates.add(new Pair<>(false, RULE_ALLOW_ALL));
+ expectedBlockedStates.add(new Pair<>(true, RULE_REJECT_ALL));
+ verifyNetworkBlockedState(
+ true /* metered */, false /* backgroundRestricted */, expectedBlockedStates);
+ expectedBlockedStates.clear();
+
+ // Non-metered network. Data saver on.
+ expectedBlockedStates.add(new Pair<>(false, RULE_NONE));
+ expectedBlockedStates.add(new Pair<>(false, RULE_ALLOW_METERED));
+ expectedBlockedStates.add(new Pair<>(false, RULE_TEMPORARY_ALLOW_METERED));
+ expectedBlockedStates.add(new Pair<>(false, RULE_REJECT_METERED));
+ expectedBlockedStates.add(new Pair<>(false, RULE_ALLOW_ALL));
+ expectedBlockedStates.add(new Pair<>(true, RULE_REJECT_ALL));
+ verifyNetworkBlockedState(
+ false /* metered */, true /* backgroundRestricted */, expectedBlockedStates);
+
+ // Non-metered network. Data saver off. The result is the same as previous case since
+ // the network is blocked only for RULE_REJECT_ALL regardless of data saver.
+ verifyNetworkBlockedState(
+ false /* metered */, false /* backgroundRestricted */, expectedBlockedStates);
+ expectedBlockedStates.clear();
+ }
+
+ private void verifyNetworkBlockedState(boolean metered, boolean backgroundRestricted,
+ ArrayList<Pair<Boolean, Integer>> expectedBlockedStateForRules) {
+ final NetworkPolicyManagerInternal npmi = LocalServices
+ .getService(NetworkPolicyManagerInternal.class);
+
+ for (Pair<Boolean, Integer> pair : expectedBlockedStateForRules) {
+ final boolean expectedResult = pair.first;
+ final int rule = pair.second;
+ assertEquals(formatBlockedStateError(UID_A, rule, metered, backgroundRestricted),
+ expectedResult,
+ npmi.isUidNetworkingBlocked(UID_A, rule, metered, backgroundRestricted));
+ assertFalse(formatBlockedStateError(SYSTEM_UID, rule, metered, backgroundRestricted),
+ npmi.isUidNetworkingBlocked(SYSTEM_UID, rule, metered, backgroundRestricted));
+ }
+ }
+
+ private String formatBlockedStateError(int uid, int rule, boolean metered,
+ boolean backgroundRestricted) {
+ return String.format(
+ "Unexpected BlockedState: (uid=%d, rule=%s, metered=%b, backgroundRestricted=%b)",
+ uid, uidRulesToString(rule), metered, backgroundRestricted);
+ }
+
private SubscriptionPlan buildMonthlyDataPlan(ZonedDateTime start, long limitBytes) {
return SubscriptionPlan.Builder
.createRecurringMonthly(start)
diff --git a/tests/net/java/android/net/ConnectivityManagerTest.java b/tests/net/java/android/net/ConnectivityManagerTest.java
index 03a617c..6174c6c 100644
--- a/tests/net/java/android/net/ConnectivityManagerTest.java
+++ b/tests/net/java/android/net/ConnectivityManagerTest.java
@@ -219,7 +219,7 @@
// callback triggers
captor.getValue().send(makeMessage(request, ConnectivityManager.CALLBACK_AVAILABLE));
verify(callback, timeout(500).times(1)).onAvailable(any(Network.class),
- any(NetworkCapabilities.class), any(LinkProperties.class));
+ any(NetworkCapabilities.class), any(LinkProperties.class), anyBoolean());
// unregister callback
manager.unregisterNetworkCallback(callback);
@@ -247,7 +247,7 @@
// callback triggers
captor.getValue().send(makeMessage(req1, ConnectivityManager.CALLBACK_AVAILABLE));
verify(callback, timeout(100).times(1)).onAvailable(any(Network.class),
- any(NetworkCapabilities.class), any(LinkProperties.class));
+ any(NetworkCapabilities.class), any(LinkProperties.class), anyBoolean());
// unregister callback
manager.unregisterNetworkCallback(callback);
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 1c77fcc..17bcea0 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -51,6 +51,10 @@
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.NetworkPolicyManager.RULE_ALLOW_METERED;
+import static android.net.NetworkPolicyManager.RULE_NONE;
+import static android.net.NetworkPolicyManager.RULE_REJECT_ALL;
+import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
import static com.android.internal.util.TestUtils.waitForIdleHandler;
import static com.android.internal.util.TestUtils.waitForIdleLooper;
@@ -92,6 +96,7 @@
import android.net.ConnectivityManager.PacketKeepaliveCallback;
import android.net.ConnectivityManager.TooManyRequestsException;
import android.net.ConnectivityThread;
+import android.net.INetworkPolicyListener;
import android.net.INetworkPolicyManager;
import android.net.INetworkStatsService;
import android.net.InterfaceConfiguration;
@@ -148,6 +153,7 @@
import com.android.server.connectivity.Nat464Xlat;
import com.android.server.connectivity.NetworkAgentInfo;
import com.android.server.connectivity.NetworkMonitor;
+import com.android.server.connectivity.Tethering;
import com.android.server.connectivity.Vpn;
import com.android.server.net.NetworkPinner;
import com.android.server.net.NetworkPolicyManagerInternal;
@@ -215,11 +221,13 @@
private MockNetworkAgent mEthernetNetworkAgent;
private MockVpn mMockVpn;
private Context mContext;
+ private INetworkPolicyListener mPolicyListener;
@Mock IpConnectivityMetrics.Logger mMetricsService;
@Mock DefaultNetworkMetrics mDefaultNetworkMetrics;
@Mock INetworkManagementService mNetworkManagementService;
@Mock INetworkStatsService mStatsService;
+ @Mock INetworkPolicyManager mNpm;
private ArgumentCaptor<String[]> mStringArrayCaptor = ArgumentCaptor.forClass(String[].class);
@@ -934,6 +942,11 @@
}
@Override
+ protected Tethering makeTethering() {
+ return mock(Tethering.class);
+ }
+
+ @Override
protected int reserveNetId() {
while (true) {
final int netId = super.reserveNetId();
@@ -1023,6 +1036,20 @@
public void waitForIdle() {
waitForIdle(TIMEOUT_MS);
}
+
+ public void setUidRulesChanged(int uidRules) {
+ try {
+ mPolicyListener.onUidRulesChanged(Process.myUid(), uidRules);
+ } catch (RemoteException ignored) {
+ }
+ }
+
+ public void setRestrictBackgroundChanged(boolean restrictBackground) {
+ try {
+ mPolicyListener.onRestrictBackgroundChanged(restrictBackground);
+ } catch (RemoteException ignored) {
+ }
+ }
}
/**
@@ -1055,12 +1082,18 @@
LocalServices.removeServiceForTest(NetworkPolicyManagerInternal.class);
LocalServices.addService(
NetworkPolicyManagerInternal.class, mock(NetworkPolicyManagerInternal.class));
+
mService = new WrappedConnectivityService(mServiceContext,
mNetworkManagementService,
mStatsService,
- mock(INetworkPolicyManager.class),
+ mNpm,
mock(IpConnectivityLog.class));
+ final ArgumentCaptor<INetworkPolicyListener> policyListenerCaptor =
+ ArgumentCaptor.forClass(INetworkPolicyListener.class);
+ verify(mNpm).registerListener(policyListenerCaptor.capture());
+ mPolicyListener = policyListenerCaptor.getValue();
+
// Create local CM before sending system ready so that we can answer
// getSystemService() correctly.
mCm = new WrappedConnectivityManager(InstrumentationRegistry.getContext(), mService);
@@ -1441,7 +1474,8 @@
RESUMED,
LOSING,
LOST,
- UNAVAILABLE
+ UNAVAILABLE,
+ BLOCKED_STATUS
}
private static class CallbackInfo {
@@ -1522,6 +1556,11 @@
setLastCallback(CallbackState.LOST, network, null);
}
+ @Override
+ public void onBlockedStatusChanged(Network network, boolean blocked) {
+ setLastCallback(CallbackState.BLOCKED_STATUS, network, blocked);
+ }
+
public Network getLastAvailableNetwork() {
return mLastAvailableNetwork;
}
@@ -1582,6 +1621,7 @@
// - onSuspended, iff the network was suspended when the callbacks fire.
// - onCapabilitiesChanged.
// - onLinkPropertiesChanged.
+ // - onBlockedStatusChanged.
//
// @param agent the network to expect the callbacks on.
// @param expectSuspended whether to expect a SUSPENDED callback.
@@ -1589,7 +1629,7 @@
// onCapabilitiesChanged callback.
// @param timeoutMs how long to wait for the callbacks.
void expectAvailableCallbacks(MockNetworkAgent agent, boolean expectSuspended,
- boolean expectValidated, int timeoutMs) {
+ boolean expectValidated, boolean expectBlocked, int timeoutMs) {
expectCallback(CallbackState.AVAILABLE, agent, timeoutMs);
if (expectSuspended) {
expectCallback(CallbackState.SUSPENDED, agent, timeoutMs);
@@ -1600,19 +1640,28 @@
expectCapabilitiesWithout(NET_CAPABILITY_VALIDATED, agent, timeoutMs);
}
expectCallback(CallbackState.LINK_PROPERTIES, agent, timeoutMs);
+ expectBlockedStatusCallback(expectBlocked, agent);
}
// Expects the available callbacks (validated), plus onSuspended.
void expectAvailableAndSuspendedCallbacks(MockNetworkAgent agent, boolean expectValidated) {
- expectAvailableCallbacks(agent, true, expectValidated, TEST_CALLBACK_TIMEOUT_MS);
+ expectAvailableCallbacks(agent, true, expectValidated, false, TEST_CALLBACK_TIMEOUT_MS);
}
void expectAvailableCallbacksValidated(MockNetworkAgent agent) {
- expectAvailableCallbacks(agent, false, true, TEST_CALLBACK_TIMEOUT_MS);
+ expectAvailableCallbacks(agent, false, true, false, TEST_CALLBACK_TIMEOUT_MS);
+ }
+
+ void expectAvailableCallbacksValidatedAndBlocked(MockNetworkAgent agent) {
+ expectAvailableCallbacks(agent, false, true, true, TEST_CALLBACK_TIMEOUT_MS);
}
void expectAvailableCallbacksUnvalidated(MockNetworkAgent agent) {
- expectAvailableCallbacks(agent, false, false, TEST_CALLBACK_TIMEOUT_MS);
+ expectAvailableCallbacks(agent, false, false, false, TEST_CALLBACK_TIMEOUT_MS);
+ }
+
+ void expectAvailableCallbacksUnvalidatedAndBlocked(MockNetworkAgent agent) {
+ expectAvailableCallbacks(agent, false, false, true, TEST_CALLBACK_TIMEOUT_MS);
}
// Expects the available callbacks (where the onCapabilitiesChanged must contain the
@@ -1623,6 +1672,9 @@
expectCallback(CallbackState.AVAILABLE, agent, TEST_CALLBACK_TIMEOUT_MS);
NetworkCapabilities nc1 = expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, agent);
expectCallback(CallbackState.LINK_PROPERTIES, agent, TEST_CALLBACK_TIMEOUT_MS);
+ // Implicitly check the network is allowed to use.
+ // TODO: should we need to consider if network is in blocked status in this case?
+ expectBlockedStatusCallback(false, agent);
NetworkCapabilities nc2 = expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, agent);
assertEquals(nc1, nc2);
}
@@ -1665,6 +1717,12 @@
fn.test((NetworkCapabilities) cbi.arg));
}
+ void expectBlockedStatusCallback(boolean expectBlocked, MockNetworkAgent agent) {
+ CallbackInfo cbi = expectCallback(CallbackState.BLOCKED_STATUS, agent);
+ boolean actualBlocked = (boolean) cbi.arg;
+ assertEquals(expectBlocked, actualBlocked);
+ }
+
void assertNoCallback() {
waitForIdle();
CallbackInfo c = mCallbacks.peek();
@@ -3223,7 +3281,7 @@
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
mWiFiNetworkAgent.connect(false);
- networkCallback.expectAvailableCallbacks(mWiFiNetworkAgent, false, false,
+ networkCallback.expectAvailableCallbacks(mWiFiNetworkAgent, false, false, false,
TEST_CALLBACK_TIMEOUT_MS);
// pass timeout and validate that UNAVAILABLE is not called
@@ -3243,7 +3301,7 @@
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
mWiFiNetworkAgent.connect(false);
- networkCallback.expectAvailableCallbacks(mWiFiNetworkAgent, false, false,
+ networkCallback.expectAvailableCallbacks(mWiFiNetworkAgent, false, false, false,
TEST_CALLBACK_TIMEOUT_MS);
mWiFiNetworkAgent.disconnect();
networkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
@@ -3802,6 +3860,7 @@
networkCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES, networkAgent);
CallbackInfo cbi = networkCallback.expectCallback(CallbackState.LINK_PROPERTIES,
networkAgent);
+ networkCallback.expectCallback(CallbackState.BLOCKED_STATUS, networkAgent);
networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, networkAgent);
networkCallback.assertNoCallback();
checkDirectlyConnectedRoutes(cbi.arg, Arrays.asList(myIpv4Address),
@@ -4010,6 +4069,7 @@
mCellNetworkAgent);
CallbackInfo cbi = cellNetworkCallback.expectCallback(
CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
+ cellNetworkCallback.expectCallback(CallbackState.BLOCKED_STATUS, mCellNetworkAgent);
cellNetworkCallback.assertNoCallback();
assertFalse(((LinkProperties)cbi.arg).isPrivateDnsActive());
assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName());
@@ -4068,6 +4128,7 @@
mCellNetworkAgent);
CallbackInfo cbi = cellNetworkCallback.expectCallback(
CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
+ cellNetworkCallback.expectCallback(CallbackState.BLOCKED_STATUS, mCellNetworkAgent);
cellNetworkCallback.assertNoCallback();
assertFalse(((LinkProperties)cbi.arg).isPrivateDnsActive());
assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName());
@@ -4444,6 +4505,101 @@
mMockVpn.disconnect();
}
+ @Test
+ public void testNetworkBlockedStatus() {
+ final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
+ final NetworkRequest cellRequest = new NetworkRequest.Builder()
+ .addTransportType(TRANSPORT_CELLULAR)
+ .build();
+ mCm.registerNetworkCallback(cellRequest, cellNetworkCallback);
+
+ mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
+ mCellNetworkAgent.connect(true);
+ cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+
+ mService.setUidRulesChanged(RULE_REJECT_ALL);
+ cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
+
+ // ConnectivityService should cache it not to invoke the callback again.
+ mService.setUidRulesChanged(RULE_REJECT_METERED);
+ cellNetworkCallback.assertNoCallback();
+
+ mService.setUidRulesChanged(RULE_NONE);
+ cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
+
+ mService.setUidRulesChanged(RULE_REJECT_METERED);
+ cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
+
+ // Restrict the network based on UID rule and NOT_METERED capability change.
+ mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
+ cellNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_METERED, mCellNetworkAgent);
+ cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
+ mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED);
+ cellNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_METERED,
+ mCellNetworkAgent);
+ cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
+ mService.setUidRulesChanged(RULE_ALLOW_METERED);
+ cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
+
+ mService.setUidRulesChanged(RULE_NONE);
+ cellNetworkCallback.assertNoCallback();
+
+ // Restrict the network based on BackgroundRestricted.
+ mService.setRestrictBackgroundChanged(true);
+ cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
+ mService.setRestrictBackgroundChanged(true);
+ cellNetworkCallback.assertNoCallback();
+ mService.setRestrictBackgroundChanged(false);
+ cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
+ cellNetworkCallback.assertNoCallback();
+
+ mCm.unregisterNetworkCallback(cellNetworkCallback);
+ }
+
+ @Test
+ public void testNetworkBlockedStatusBeforeAndAfterConnect() {
+ final TestNetworkCallback defaultCallback = new TestNetworkCallback();
+ mCm.registerDefaultNetworkCallback(defaultCallback);
+
+ // No Networkcallbacks invoked before any network is active.
+ mService.setUidRulesChanged(RULE_REJECT_ALL);
+ mService.setUidRulesChanged(RULE_NONE);
+ mService.setUidRulesChanged(RULE_REJECT_METERED);
+ defaultCallback.assertNoCallback();
+
+ mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
+ mCellNetworkAgent.connect(true);
+ defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent);
+ defaultCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mCellNetworkAgent);
+
+ // Allow to use the network after switching to NOT_METERED network.
+ mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
+ mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
+ mWiFiNetworkAgent.connect(true);
+ defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent);
+
+ // Switch to METERED network. Restrict the use of the network.
+ mWiFiNetworkAgent.disconnect();
+ defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+ defaultCallback.expectAvailableCallbacksValidatedAndBlocked(mCellNetworkAgent);
+
+ // Network becomes NOT_METERED.
+ mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
+ defaultCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_METERED, mCellNetworkAgent);
+ defaultCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
+
+ // Verify there's no Networkcallbacks invoked after data saver on/off.
+ mService.setRestrictBackgroundChanged(true);
+ mService.setRestrictBackgroundChanged(false);
+ defaultCallback.assertNoCallback();
+
+ mCellNetworkAgent.disconnect();
+ defaultCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
+ defaultCallback.assertNoCallback();
+
+ mCm.unregisterNetworkCallback(defaultCallback);
+ }
+
/**
* Make simulated InterfaceConfig for Nat464Xlat to query clat lower layer info.
*/