Loading tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java 0 → 100644 +366 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.vcn; import static com.android.server.vcn.VcnTestUtils.setupSystemService; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.any; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import android.content.Context; import android.net.ConnectivityManager; import android.net.LinkProperties; import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkRequest; import android.net.TelephonyNetworkSpecifier; import android.os.ParcelUuid; import android.os.test.TestLooper; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import com.android.server.vcn.UnderlyingNetworkTracker.NetworkBringupCallback; import com.android.server.vcn.UnderlyingNetworkTracker.RouteSelectionCallback; import com.android.server.vcn.UnderlyingNetworkTracker.UnderlyingNetworkRecord; import com.android.server.vcn.UnderlyingNetworkTracker.UnderlyingNetworkTrackerCallback; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.UUID; public class UnderlyingNetworkTrackerTest { private static final ParcelUuid SUB_GROUP = new ParcelUuid(new UUID(0, 0)); private static final int INITIAL_SUB_ID_1 = 1; private static final int INITIAL_SUB_ID_2 = 2; private static final NetworkCapabilities INITIAL_NETWORK_CAPABILITIES = new NetworkCapabilities.Builder() .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED) .build(); private static final NetworkCapabilities SUSPENDED_NETWORK_CAPABILITIES = new NetworkCapabilities.Builder(INITIAL_NETWORK_CAPABILITIES) .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED) .build(); private static final NetworkCapabilities UPDATED_NETWORK_CAPABILITIES = new NetworkCapabilities.Builder() .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) .build(); private static final LinkProperties INITIAL_LINK_PROPERTIES = getLinkPropertiesWithName("initial_iface"); private static final LinkProperties UPDATED_LINK_PROPERTIES = getLinkPropertiesWithName("updated_iface"); @Mock private Context mContext; @Mock private VcnNetworkProvider mVcnNetworkProvider; @Mock private ConnectivityManager mConnectivityManager; @Mock private SubscriptionManager mSubscriptionManager; @Mock private UnderlyingNetworkTrackerCallback mNetworkTrackerCb; @Mock private Network mNetwork; @Captor private ArgumentCaptor<RouteSelectionCallback> mRouteSelectionCallbackCaptor; private TestLooper mTestLooper; private VcnContext mVcnContext; private UnderlyingNetworkTracker mUnderlyingNetworkTracker; @Before public void setUp() { MockitoAnnotations.initMocks(this); mTestLooper = new TestLooper(); mVcnContext = spy(new VcnContext(mContext, mTestLooper.getLooper(), mVcnNetworkProvider)); doNothing().when(mVcnContext).ensureRunningOnLooperThread(); setupSystemService( mContext, mConnectivityManager, Context.CONNECTIVITY_SERVICE, ConnectivityManager.class); setupSystemService( mContext, mSubscriptionManager, Context.TELEPHONY_SUBSCRIPTION_SERVICE, SubscriptionManager.class); List<SubscriptionInfo> initialSubInfos = Arrays.asList( getSubscriptionInfoForSubId(INITIAL_SUB_ID_1), getSubscriptionInfoForSubId(INITIAL_SUB_ID_2)); when(mSubscriptionManager.getSubscriptionsInGroup(eq(SUB_GROUP))) .thenReturn(initialSubInfos); mUnderlyingNetworkTracker = new UnderlyingNetworkTracker( mVcnContext, SUB_GROUP, Collections.singleton(NetworkCapabilities.NET_CAPABILITY_INTERNET), mNetworkTrackerCb); } private static LinkProperties getLinkPropertiesWithName(String iface) { LinkProperties linkProperties = new LinkProperties(); linkProperties.setInterfaceName(iface); return linkProperties; } private SubscriptionInfo getSubscriptionInfoForSubId(int subId) { SubscriptionInfo subInfo = mock(SubscriptionInfo.class); when(subInfo.getSubscriptionId()).thenReturn(subId); return subInfo; } @Test public void testNetworkCallbacksRegisteredOnStartup() { // verify NetworkCallbacks registered when instantiated verify(mConnectivityManager) .requestBackgroundNetwork( eq(getWifiRequest()), any(), any(NetworkBringupCallback.class)); verify(mConnectivityManager) .requestBackgroundNetwork( eq(getCellRequestForSubId(INITIAL_SUB_ID_1)), any(), any(NetworkBringupCallback.class)); verify(mConnectivityManager) .requestBackgroundNetwork( eq(getCellRequestForSubId(INITIAL_SUB_ID_2)), any(), any(NetworkBringupCallback.class)); verify(mConnectivityManager) .requestBackgroundNetwork( eq(getRouteSelectionRequest()), any(), any(RouteSelectionCallback.class)); verify(mSubscriptionManager).getSubscriptionsInGroup(eq(SUB_GROUP)); } private NetworkRequest getWifiRequest() { return getExpectedRequestBase() .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) .build(); } private NetworkRequest getCellRequestForSubId(int subId) { return getExpectedRequestBase() .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) .setNetworkSpecifier(new TelephonyNetworkSpecifier(subId)) .build(); } private NetworkRequest getRouteSelectionRequest() { return getExpectedRequestBase().build(); } private NetworkRequest.Builder getExpectedRequestBase() { return new NetworkRequest.Builder() .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED) .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED) .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED) .addUnwantedCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED); } @Test public void testTeardown() { mUnderlyingNetworkTracker.teardown(); // Expect 3 NetworkBringupCallbacks to be unregistered: 1 for WiFi and 2 for Cellular (1x // for each subId) verify(mConnectivityManager, times(3)) .unregisterNetworkCallback(any(NetworkBringupCallback.class)); verify(mConnectivityManager).unregisterNetworkCallback(any(RouteSelectionCallback.class)); } @Test public void testUnderlyingNetworkRecordEquals() { UnderlyingNetworkRecord recordA = new UnderlyingNetworkRecord( mNetwork, INITIAL_NETWORK_CAPABILITIES, INITIAL_LINK_PROPERTIES, false /* isBlocked */); UnderlyingNetworkRecord recordB = new UnderlyingNetworkRecord( mNetwork, INITIAL_NETWORK_CAPABILITIES, INITIAL_LINK_PROPERTIES, false /* isBlocked */); UnderlyingNetworkRecord recordC = new UnderlyingNetworkRecord( mNetwork, UPDATED_NETWORK_CAPABILITIES, UPDATED_LINK_PROPERTIES, false /* isBlocked */); assertEquals(recordA, recordB); assertNotEquals(recordA, recordC); } @Test public void testRecordTrackerCallbackNotifiedForNetworkChange() { verifyRegistrationOnAvailableAndGetCallback(); } private RouteSelectionCallback verifyRegistrationOnAvailableAndGetCallback() { return verifyRegistrationOnAvailableAndGetCallback(INITIAL_NETWORK_CAPABILITIES); } private RouteSelectionCallback verifyRegistrationOnAvailableAndGetCallback( NetworkCapabilities networkCapabilities) { verify(mConnectivityManager) .requestBackgroundNetwork( eq(getRouteSelectionRequest()), any(), mRouteSelectionCallbackCaptor.capture()); RouteSelectionCallback cb = mRouteSelectionCallbackCaptor.getValue(); cb.onAvailable(mNetwork); cb.onCapabilitiesChanged(mNetwork, networkCapabilities); cb.onLinkPropertiesChanged(mNetwork, INITIAL_LINK_PROPERTIES); cb.onBlockedStatusChanged(mNetwork, false /* isFalse */); UnderlyingNetworkRecord expectedRecord = new UnderlyingNetworkRecord( mNetwork, networkCapabilities, INITIAL_LINK_PROPERTIES, false /* isBlocked */); verify(mNetworkTrackerCb).onSelectedUnderlyingNetworkChanged(eq(expectedRecord)); return cb; } @Test public void testRecordTrackerCallbackNotifiedForNetworkCapabilitiesChange() { RouteSelectionCallback cb = verifyRegistrationOnAvailableAndGetCallback(); cb.onCapabilitiesChanged(mNetwork, UPDATED_NETWORK_CAPABILITIES); UnderlyingNetworkRecord expectedRecord = new UnderlyingNetworkRecord( mNetwork, UPDATED_NETWORK_CAPABILITIES, INITIAL_LINK_PROPERTIES, false /* isBlocked */); verify(mNetworkTrackerCb).onSelectedUnderlyingNetworkChanged(eq(expectedRecord)); } @Test public void testRecordTrackerCallbackNotifiedForLinkPropertiesChange() { RouteSelectionCallback cb = verifyRegistrationOnAvailableAndGetCallback(); cb.onLinkPropertiesChanged(mNetwork, UPDATED_LINK_PROPERTIES); UnderlyingNetworkRecord expectedRecord = new UnderlyingNetworkRecord( mNetwork, INITIAL_NETWORK_CAPABILITIES, UPDATED_LINK_PROPERTIES, false /* isBlocked */); verify(mNetworkTrackerCb).onSelectedUnderlyingNetworkChanged(eq(expectedRecord)); } @Test public void testRecordTrackerCallbackNotifiedForNetworkSuspended() { RouteSelectionCallback cb = verifyRegistrationOnAvailableAndGetCallback(); cb.onNetworkSuspended(mNetwork); UnderlyingNetworkRecord expectedRecord = new UnderlyingNetworkRecord( mNetwork, SUSPENDED_NETWORK_CAPABILITIES, INITIAL_LINK_PROPERTIES, false /* isBlocked */); verify(mNetworkTrackerCb).onSelectedUnderlyingNetworkChanged(eq(expectedRecord)); } @Test public void testRecordTrackerCallbackNotifiedForNetworkResumed() { RouteSelectionCallback cb = verifyRegistrationOnAvailableAndGetCallback(SUSPENDED_NETWORK_CAPABILITIES); cb.onNetworkResumed(mNetwork); UnderlyingNetworkRecord expectedRecord = new UnderlyingNetworkRecord( mNetwork, INITIAL_NETWORK_CAPABILITIES, INITIAL_LINK_PROPERTIES, false /* isBlocked */); verify(mNetworkTrackerCb).onSelectedUnderlyingNetworkChanged(eq(expectedRecord)); } @Test public void testRecordTrackerCallbackNotifiedForBlocked() { RouteSelectionCallback cb = verifyRegistrationOnAvailableAndGetCallback(); cb.onBlockedStatusChanged(mNetwork, true /* isBlocked */); UnderlyingNetworkRecord expectedRecord = new UnderlyingNetworkRecord( mNetwork, INITIAL_NETWORK_CAPABILITIES, INITIAL_LINK_PROPERTIES, true /* isBlocked */); verify(mNetworkTrackerCb).onSelectedUnderlyingNetworkChanged(eq(expectedRecord)); } @Test public void testRecordTrackerCallbackNotifiedForNetworkLoss() { RouteSelectionCallback cb = verifyRegistrationOnAvailableAndGetCallback(); cb.onLost(mNetwork); verify(mNetworkTrackerCb).onSelectedUnderlyingNetworkChanged(null); } @Test public void testRecordTrackerCallbackIgnoresDuplicateRecord() { RouteSelectionCallback cb = verifyRegistrationOnAvailableAndGetCallback(); cb.onCapabilitiesChanged(mNetwork, INITIAL_NETWORK_CAPABILITIES); // Verify no more calls to the UnderlyingNetworkTrackerCallback when the // UnderlyingNetworkRecord does not actually change verifyNoMoreInteractions(mNetworkTrackerCb); } } Loading
tests/vcn/java/com/android/server/vcn/UnderlyingNetworkTrackerTest.java 0 → 100644 +366 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.vcn; import static com.android.server.vcn.VcnTestUtils.setupSystemService; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.any; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import android.content.Context; import android.net.ConnectivityManager; import android.net.LinkProperties; import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkRequest; import android.net.TelephonyNetworkSpecifier; import android.os.ParcelUuid; import android.os.test.TestLooper; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import com.android.server.vcn.UnderlyingNetworkTracker.NetworkBringupCallback; import com.android.server.vcn.UnderlyingNetworkTracker.RouteSelectionCallback; import com.android.server.vcn.UnderlyingNetworkTracker.UnderlyingNetworkRecord; import com.android.server.vcn.UnderlyingNetworkTracker.UnderlyingNetworkTrackerCallback; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.UUID; public class UnderlyingNetworkTrackerTest { private static final ParcelUuid SUB_GROUP = new ParcelUuid(new UUID(0, 0)); private static final int INITIAL_SUB_ID_1 = 1; private static final int INITIAL_SUB_ID_2 = 2; private static final NetworkCapabilities INITIAL_NETWORK_CAPABILITIES = new NetworkCapabilities.Builder() .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED) .build(); private static final NetworkCapabilities SUSPENDED_NETWORK_CAPABILITIES = new NetworkCapabilities.Builder(INITIAL_NETWORK_CAPABILITIES) .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED) .build(); private static final NetworkCapabilities UPDATED_NETWORK_CAPABILITIES = new NetworkCapabilities.Builder() .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) .build(); private static final LinkProperties INITIAL_LINK_PROPERTIES = getLinkPropertiesWithName("initial_iface"); private static final LinkProperties UPDATED_LINK_PROPERTIES = getLinkPropertiesWithName("updated_iface"); @Mock private Context mContext; @Mock private VcnNetworkProvider mVcnNetworkProvider; @Mock private ConnectivityManager mConnectivityManager; @Mock private SubscriptionManager mSubscriptionManager; @Mock private UnderlyingNetworkTrackerCallback mNetworkTrackerCb; @Mock private Network mNetwork; @Captor private ArgumentCaptor<RouteSelectionCallback> mRouteSelectionCallbackCaptor; private TestLooper mTestLooper; private VcnContext mVcnContext; private UnderlyingNetworkTracker mUnderlyingNetworkTracker; @Before public void setUp() { MockitoAnnotations.initMocks(this); mTestLooper = new TestLooper(); mVcnContext = spy(new VcnContext(mContext, mTestLooper.getLooper(), mVcnNetworkProvider)); doNothing().when(mVcnContext).ensureRunningOnLooperThread(); setupSystemService( mContext, mConnectivityManager, Context.CONNECTIVITY_SERVICE, ConnectivityManager.class); setupSystemService( mContext, mSubscriptionManager, Context.TELEPHONY_SUBSCRIPTION_SERVICE, SubscriptionManager.class); List<SubscriptionInfo> initialSubInfos = Arrays.asList( getSubscriptionInfoForSubId(INITIAL_SUB_ID_1), getSubscriptionInfoForSubId(INITIAL_SUB_ID_2)); when(mSubscriptionManager.getSubscriptionsInGroup(eq(SUB_GROUP))) .thenReturn(initialSubInfos); mUnderlyingNetworkTracker = new UnderlyingNetworkTracker( mVcnContext, SUB_GROUP, Collections.singleton(NetworkCapabilities.NET_CAPABILITY_INTERNET), mNetworkTrackerCb); } private static LinkProperties getLinkPropertiesWithName(String iface) { LinkProperties linkProperties = new LinkProperties(); linkProperties.setInterfaceName(iface); return linkProperties; } private SubscriptionInfo getSubscriptionInfoForSubId(int subId) { SubscriptionInfo subInfo = mock(SubscriptionInfo.class); when(subInfo.getSubscriptionId()).thenReturn(subId); return subInfo; } @Test public void testNetworkCallbacksRegisteredOnStartup() { // verify NetworkCallbacks registered when instantiated verify(mConnectivityManager) .requestBackgroundNetwork( eq(getWifiRequest()), any(), any(NetworkBringupCallback.class)); verify(mConnectivityManager) .requestBackgroundNetwork( eq(getCellRequestForSubId(INITIAL_SUB_ID_1)), any(), any(NetworkBringupCallback.class)); verify(mConnectivityManager) .requestBackgroundNetwork( eq(getCellRequestForSubId(INITIAL_SUB_ID_2)), any(), any(NetworkBringupCallback.class)); verify(mConnectivityManager) .requestBackgroundNetwork( eq(getRouteSelectionRequest()), any(), any(RouteSelectionCallback.class)); verify(mSubscriptionManager).getSubscriptionsInGroup(eq(SUB_GROUP)); } private NetworkRequest getWifiRequest() { return getExpectedRequestBase() .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) .build(); } private NetworkRequest getCellRequestForSubId(int subId) { return getExpectedRequestBase() .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) .setNetworkSpecifier(new TelephonyNetworkSpecifier(subId)) .build(); } private NetworkRequest getRouteSelectionRequest() { return getExpectedRequestBase().build(); } private NetworkRequest.Builder getExpectedRequestBase() { return new NetworkRequest.Builder() .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED) .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED) .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED) .addUnwantedCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED); } @Test public void testTeardown() { mUnderlyingNetworkTracker.teardown(); // Expect 3 NetworkBringupCallbacks to be unregistered: 1 for WiFi and 2 for Cellular (1x // for each subId) verify(mConnectivityManager, times(3)) .unregisterNetworkCallback(any(NetworkBringupCallback.class)); verify(mConnectivityManager).unregisterNetworkCallback(any(RouteSelectionCallback.class)); } @Test public void testUnderlyingNetworkRecordEquals() { UnderlyingNetworkRecord recordA = new UnderlyingNetworkRecord( mNetwork, INITIAL_NETWORK_CAPABILITIES, INITIAL_LINK_PROPERTIES, false /* isBlocked */); UnderlyingNetworkRecord recordB = new UnderlyingNetworkRecord( mNetwork, INITIAL_NETWORK_CAPABILITIES, INITIAL_LINK_PROPERTIES, false /* isBlocked */); UnderlyingNetworkRecord recordC = new UnderlyingNetworkRecord( mNetwork, UPDATED_NETWORK_CAPABILITIES, UPDATED_LINK_PROPERTIES, false /* isBlocked */); assertEquals(recordA, recordB); assertNotEquals(recordA, recordC); } @Test public void testRecordTrackerCallbackNotifiedForNetworkChange() { verifyRegistrationOnAvailableAndGetCallback(); } private RouteSelectionCallback verifyRegistrationOnAvailableAndGetCallback() { return verifyRegistrationOnAvailableAndGetCallback(INITIAL_NETWORK_CAPABILITIES); } private RouteSelectionCallback verifyRegistrationOnAvailableAndGetCallback( NetworkCapabilities networkCapabilities) { verify(mConnectivityManager) .requestBackgroundNetwork( eq(getRouteSelectionRequest()), any(), mRouteSelectionCallbackCaptor.capture()); RouteSelectionCallback cb = mRouteSelectionCallbackCaptor.getValue(); cb.onAvailable(mNetwork); cb.onCapabilitiesChanged(mNetwork, networkCapabilities); cb.onLinkPropertiesChanged(mNetwork, INITIAL_LINK_PROPERTIES); cb.onBlockedStatusChanged(mNetwork, false /* isFalse */); UnderlyingNetworkRecord expectedRecord = new UnderlyingNetworkRecord( mNetwork, networkCapabilities, INITIAL_LINK_PROPERTIES, false /* isBlocked */); verify(mNetworkTrackerCb).onSelectedUnderlyingNetworkChanged(eq(expectedRecord)); return cb; } @Test public void testRecordTrackerCallbackNotifiedForNetworkCapabilitiesChange() { RouteSelectionCallback cb = verifyRegistrationOnAvailableAndGetCallback(); cb.onCapabilitiesChanged(mNetwork, UPDATED_NETWORK_CAPABILITIES); UnderlyingNetworkRecord expectedRecord = new UnderlyingNetworkRecord( mNetwork, UPDATED_NETWORK_CAPABILITIES, INITIAL_LINK_PROPERTIES, false /* isBlocked */); verify(mNetworkTrackerCb).onSelectedUnderlyingNetworkChanged(eq(expectedRecord)); } @Test public void testRecordTrackerCallbackNotifiedForLinkPropertiesChange() { RouteSelectionCallback cb = verifyRegistrationOnAvailableAndGetCallback(); cb.onLinkPropertiesChanged(mNetwork, UPDATED_LINK_PROPERTIES); UnderlyingNetworkRecord expectedRecord = new UnderlyingNetworkRecord( mNetwork, INITIAL_NETWORK_CAPABILITIES, UPDATED_LINK_PROPERTIES, false /* isBlocked */); verify(mNetworkTrackerCb).onSelectedUnderlyingNetworkChanged(eq(expectedRecord)); } @Test public void testRecordTrackerCallbackNotifiedForNetworkSuspended() { RouteSelectionCallback cb = verifyRegistrationOnAvailableAndGetCallback(); cb.onNetworkSuspended(mNetwork); UnderlyingNetworkRecord expectedRecord = new UnderlyingNetworkRecord( mNetwork, SUSPENDED_NETWORK_CAPABILITIES, INITIAL_LINK_PROPERTIES, false /* isBlocked */); verify(mNetworkTrackerCb).onSelectedUnderlyingNetworkChanged(eq(expectedRecord)); } @Test public void testRecordTrackerCallbackNotifiedForNetworkResumed() { RouteSelectionCallback cb = verifyRegistrationOnAvailableAndGetCallback(SUSPENDED_NETWORK_CAPABILITIES); cb.onNetworkResumed(mNetwork); UnderlyingNetworkRecord expectedRecord = new UnderlyingNetworkRecord( mNetwork, INITIAL_NETWORK_CAPABILITIES, INITIAL_LINK_PROPERTIES, false /* isBlocked */); verify(mNetworkTrackerCb).onSelectedUnderlyingNetworkChanged(eq(expectedRecord)); } @Test public void testRecordTrackerCallbackNotifiedForBlocked() { RouteSelectionCallback cb = verifyRegistrationOnAvailableAndGetCallback(); cb.onBlockedStatusChanged(mNetwork, true /* isBlocked */); UnderlyingNetworkRecord expectedRecord = new UnderlyingNetworkRecord( mNetwork, INITIAL_NETWORK_CAPABILITIES, INITIAL_LINK_PROPERTIES, true /* isBlocked */); verify(mNetworkTrackerCb).onSelectedUnderlyingNetworkChanged(eq(expectedRecord)); } @Test public void testRecordTrackerCallbackNotifiedForNetworkLoss() { RouteSelectionCallback cb = verifyRegistrationOnAvailableAndGetCallback(); cb.onLost(mNetwork); verify(mNetworkTrackerCb).onSelectedUnderlyingNetworkChanged(null); } @Test public void testRecordTrackerCallbackIgnoresDuplicateRecord() { RouteSelectionCallback cb = verifyRegistrationOnAvailableAndGetCallback(); cb.onCapabilitiesChanged(mNetwork, INITIAL_NETWORK_CAPABILITIES); // Verify no more calls to the UnderlyingNetworkTrackerCallback when the // UnderlyingNetworkRecord does not actually change verifyNoMoreInteractions(mNetworkTrackerCb); } }