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

Commit af0de1a2 authored by Junyu Lai's avatar Junyu Lai Committed by Gerrit Code Review
Browse files

Merge "Add tests for the network blocked status change"

parents f709e754 f9729757
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -934,7 +934,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
        registerPrivateDnsSettingsCallbacks();
    }

    private Tethering makeTethering() {
    @VisibleForTesting
    protected Tethering makeTethering() {
        // TODO: Move other elements into @Overridden getters.
        final TetheringDependencies deps = new TetheringDependencies() {
            @Override
+80 −0
Original line number Diff line number Diff line
@@ -26,13 +26,21 @@ import static android.net.NetworkPolicy.WARNING_DISABLED;
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.TextUtils;
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.Period;
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 @@ public class NetworkPolicyManagerServiceTest {
                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)
+2 −2
Original line number Diff line number Diff line
@@ -219,7 +219,7 @@ public class ConnectivityManagerTest {
        // 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 @@ public class ConnectivityManagerTest {
        // 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);
+164 −8
Original line number Diff line number Diff line
@@ -51,6 +51,10 @@ 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.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.PacketKeepalive;
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.MockableSystemProperties;
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 @@ public class ConnectivityServiceTest {
    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);

@@ -933,6 +941,11 @@ public class ConnectivityServiceTest {
            return mSystemProperties;
        }

        @Override
        protected Tethering makeTethering() {
            return mock(Tethering.class);
        }

        @Override
        protected int reserveNetId() {
            while (true) {
@@ -1023,6 +1036,20 @@ public class ConnectivityServiceTest {
        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 @@ public class ConnectivityServiceTest {
        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 @@ public class ConnectivityServiceTest {
        RESUMED,
        LOSING,
        LOST,
        UNAVAILABLE
        UNAVAILABLE,
        BLOCKED_STATUS
    }

    private static class CallbackInfo {
@@ -1522,6 +1556,11 @@ public class ConnectivityServiceTest {
            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 @@ public class ConnectivityServiceTest {
        // - 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 @@ public class ConnectivityServiceTest {
        //        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 @@ public class ConnectivityServiceTest {
                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 @@ public class ConnectivityServiceTest {
            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 @@ public class ConnectivityServiceTest {
                    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 @@ public class ConnectivityServiceTest {

        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 @@ public class ConnectivityServiceTest {

        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 @@ public class ConnectivityServiceTest {
        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 @@ public class ConnectivityServiceTest {
                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 @@ public class ConnectivityServiceTest {
                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 @@ public class ConnectivityServiceTest {
        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.
     */