1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.vcn.routeselection;
18 
19 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
20 import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_FORBIDDEN;
21 import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_REQUIRED;
22 import static android.net.vcn.VcnUnderlyingNetworkTemplateTestBase.TEST_MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS;
23 import static android.net.vcn.VcnUnderlyingNetworkTemplateTestBase.TEST_MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS;
24 import static android.net.vcn.VcnUnderlyingNetworkTemplateTestBase.TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS;
25 import static android.net.vcn.VcnUnderlyingNetworkTemplateTestBase.TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS;
26 
27 import static com.android.server.vcn.VcnTestUtils.setupSystemService;
28 import static com.android.server.vcn.routeselection.NetworkPriorityClassifier.PRIORITY_FALLBACK;
29 import static com.android.server.vcn.routeselection.NetworkPriorityClassifier.PRIORITY_INVALID;
30 import static com.android.server.vcn.routeselection.NetworkPriorityClassifier.checkMatchesCellPriorityRule;
31 import static com.android.server.vcn.routeselection.NetworkPriorityClassifier.checkMatchesPriorityRule;
32 import static com.android.server.vcn.routeselection.NetworkPriorityClassifier.checkMatchesWifiPriorityRule;
33 import static com.android.server.vcn.routeselection.UnderlyingNetworkControllerTest.getLinkPropertiesWithName;
34 import static com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;
35 
36 import static org.junit.Assert.assertEquals;
37 import static org.junit.Assert.assertFalse;
38 import static org.junit.Assert.assertTrue;
39 import static org.mockito.Mockito.doNothing;
40 import static org.mockito.Mockito.mock;
41 import static org.mockito.Mockito.spy;
42 import static org.mockito.Mockito.when;
43 
44 import android.content.Context;
45 import android.net.LinkProperties;
46 import android.net.Network;
47 import android.net.NetworkCapabilities;
48 import android.net.TelephonyNetworkSpecifier;
49 import android.net.vcn.VcnCellUnderlyingNetworkTemplate;
50 import android.net.vcn.VcnGatewayConnectionConfig;
51 import android.net.vcn.VcnManager;
52 import android.net.vcn.VcnUnderlyingNetworkTemplate;
53 import android.net.vcn.VcnWifiUnderlyingNetworkTemplate;
54 import android.os.ParcelUuid;
55 import android.os.PersistableBundle;
56 import android.os.test.TestLooper;
57 import android.telephony.TelephonyManager;
58 import android.util.ArraySet;
59 
60 import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
61 import com.android.server.vcn.VcnContext;
62 import com.android.server.vcn.VcnNetworkProvider;
63 
64 import org.junit.Before;
65 import org.junit.Test;
66 import org.mockito.Mock;
67 import org.mockito.MockitoAnnotations;
68 
69 import java.util.Collections;
70 import java.util.List;
71 import java.util.Set;
72 import java.util.UUID;
73 
74 public class NetworkPriorityClassifierTest {
75     private static final String SSID = "TestWifi";
76     private static final String SSID_OTHER = "TestWifiOther";
77     private static final String PLMN_ID = "123456";
78     private static final String PLMN_ID_OTHER = "234567";
79 
80     private static final int SUB_ID = 1;
81     private static final int WIFI_RSSI = -60;
82     private static final int WIFI_RSSI_HIGH = -50;
83     private static final int WIFI_RSSI_LOW = -80;
84     private static final int CARRIER_ID = 1;
85     private static final int CARRIER_ID_OTHER = 2;
86 
87     private static final int LINK_UPSTREAM_BANDWIDTH_KBPS = 1024;
88     private static final int LINK_DOWNSTREAM_BANDWIDTH_KBPS = 2048;
89 
90     private static final int TEST_MIN_UPSTREAM_BANDWIDTH_KBPS = 100;
91     private static final int TEST_MIN_DOWNSTREAM_BANDWIDTH_KBPS = 200;
92 
93     private static final ParcelUuid SUB_GROUP = new ParcelUuid(new UUID(0, 0));
94 
95     private static final NetworkCapabilities WIFI_NETWORK_CAPABILITIES =
96             new NetworkCapabilities.Builder()
97                     .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
98                     .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
99                     .setSignalStrength(WIFI_RSSI)
100                     .setSsid(SSID)
101                     .setLinkUpstreamBandwidthKbps(LINK_UPSTREAM_BANDWIDTH_KBPS)
102                     .setLinkDownstreamBandwidthKbps(LINK_DOWNSTREAM_BANDWIDTH_KBPS)
103                     .build();
104 
105     private static final TelephonyNetworkSpecifier TEL_NETWORK_SPECIFIER =
106             new TelephonyNetworkSpecifier.Builder().setSubscriptionId(SUB_ID).build();
107     private static final NetworkCapabilities CELL_NETWORK_CAPABILITIES =
108             new NetworkCapabilities.Builder()
109                     .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
110                     .addCapability(NetworkCapabilities.NET_CAPABILITY_DUN)
111                     .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
112                     .setSubscriptionIds(Set.of(SUB_ID))
113                     .setNetworkSpecifier(TEL_NETWORK_SPECIFIER)
114                     .setLinkUpstreamBandwidthKbps(LINK_UPSTREAM_BANDWIDTH_KBPS)
115                     .setLinkDownstreamBandwidthKbps(LINK_DOWNSTREAM_BANDWIDTH_KBPS)
116                     .build();
117 
118     private static final LinkProperties LINK_PROPERTIES = getLinkPropertiesWithName("test_iface");
119 
120     @Mock private Network mNetwork;
121     @Mock private TelephonySubscriptionSnapshot mSubscriptionSnapshot;
122     @Mock private TelephonyManager mTelephonyManager;
123 
124     private TestLooper mTestLooper;
125     private VcnContext mVcnContext;
126     private UnderlyingNetworkRecord mWifiNetworkRecord;
127     private UnderlyingNetworkRecord mCellNetworkRecord;
128 
129     @Before
setUp()130     public void setUp() {
131         MockitoAnnotations.initMocks(this);
132 
133         final Context mockContext = mock(Context.class);
134         mTestLooper = new TestLooper();
135         mVcnContext =
136                 spy(
137                         new VcnContext(
138                                 mockContext,
139                                 mTestLooper.getLooper(),
140                                 mock(VcnNetworkProvider.class),
141                                 false /* isInTestMode */));
142         doNothing().when(mVcnContext).ensureRunningOnLooperThread();
143 
144         setupSystemService(
145                 mockContext, mTelephonyManager, Context.TELEPHONY_SERVICE, TelephonyManager.class);
146         when(mTelephonyManager.createForSubscriptionId(SUB_ID)).thenReturn(mTelephonyManager);
147         when(mTelephonyManager.getNetworkOperator()).thenReturn(PLMN_ID);
148         when(mTelephonyManager.getSimSpecificCarrierId()).thenReturn(CARRIER_ID);
149 
150         mWifiNetworkRecord =
151                 getTestNetworkRecord(
152                         WIFI_NETWORK_CAPABILITIES,
153                         VcnGatewayConnectionConfig.DEFAULT_UNDERLYING_NETWORK_TEMPLATES);
154         mCellNetworkRecord =
155                 getTestNetworkRecord(
156                         CELL_NETWORK_CAPABILITIES,
157                         VcnGatewayConnectionConfig.DEFAULT_UNDERLYING_NETWORK_TEMPLATES);
158     }
159 
getTestNetworkRecord( NetworkCapabilities nc, List<VcnUnderlyingNetworkTemplate> underlyingNetworkTemplates)160     private UnderlyingNetworkRecord getTestNetworkRecord(
161             NetworkCapabilities nc, List<VcnUnderlyingNetworkTemplate> underlyingNetworkTemplates) {
162         return new UnderlyingNetworkRecord(
163                 mNetwork,
164                 nc,
165                 LINK_PROPERTIES,
166                 false /* isBlocked */,
167                 mVcnContext,
168                 underlyingNetworkTemplates,
169                 SUB_GROUP,
170                 mSubscriptionSnapshot,
171                 null /* currentlySelected */,
172                 null /* carrierConfig */);
173     }
174 
175     @Test
testMatchWithoutNotMeteredBit()176     public void testMatchWithoutNotMeteredBit() {
177         final VcnWifiUnderlyingNetworkTemplate wifiNetworkPriority =
178                 new VcnWifiUnderlyingNetworkTemplate.Builder()
179                         .setMetered(MATCH_FORBIDDEN)
180                         .build();
181 
182         assertFalse(
183                 checkMatchesPriorityRule(
184                         mVcnContext,
185                         wifiNetworkPriority,
186                         mWifiNetworkRecord,
187                         SUB_GROUP,
188                         mSubscriptionSnapshot,
189                         null /* currentlySelecetd */,
190                         null /* carrierConfig */));
191     }
192 
verifyMatchesPriorityRuleForUpstreamBandwidth( int entryUpstreamBandwidth, int exitUpstreamBandwidth, UnderlyingNetworkRecord currentlySelected, boolean expectMatch)193     private void verifyMatchesPriorityRuleForUpstreamBandwidth(
194             int entryUpstreamBandwidth,
195             int exitUpstreamBandwidth,
196             UnderlyingNetworkRecord currentlySelected,
197             boolean expectMatch) {
198         final VcnWifiUnderlyingNetworkTemplate wifiNetworkPriority =
199                 new VcnWifiUnderlyingNetworkTemplate.Builder()
200                         .setMinUpstreamBandwidthKbps(entryUpstreamBandwidth, exitUpstreamBandwidth)
201                         .build();
202 
203         assertEquals(
204                 expectMatch,
205                 checkMatchesPriorityRule(
206                         mVcnContext,
207                         wifiNetworkPriority,
208                         mWifiNetworkRecord,
209                         SUB_GROUP,
210                         mSubscriptionSnapshot,
211                         currentlySelected,
212                         null /* carrierConfig */));
213     }
214 
verifyMatchesPriorityRuleForDownstreamBandwidth( int entryDownstreamBandwidth, int exitDownstreamBandwidth, UnderlyingNetworkRecord currentlySelected, boolean expectMatch)215     private void verifyMatchesPriorityRuleForDownstreamBandwidth(
216             int entryDownstreamBandwidth,
217             int exitDownstreamBandwidth,
218             UnderlyingNetworkRecord currentlySelected,
219             boolean expectMatch) {
220         final VcnWifiUnderlyingNetworkTemplate wifiNetworkPriority =
221                 new VcnWifiUnderlyingNetworkTemplate.Builder()
222                         .setMinDownstreamBandwidthKbps(
223                                 entryDownstreamBandwidth, exitDownstreamBandwidth)
224                         .build();
225 
226         assertEquals(
227                 expectMatch,
228                 checkMatchesPriorityRule(
229                         mVcnContext,
230                         wifiNetworkPriority,
231                         mWifiNetworkRecord,
232                         SUB_GROUP,
233                         mSubscriptionSnapshot,
234                         currentlySelected,
235                         null /* carrierConfig */));
236     }
237 
238     @Test
testMatchWithEntryUpstreamBandwidthEquals()239     public void testMatchWithEntryUpstreamBandwidthEquals() {
240         verifyMatchesPriorityRuleForUpstreamBandwidth(
241                 TEST_MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS,
242                 TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS,
243                 null /* currentlySelected */,
244                 true);
245     }
246 
247     @Test
testMatchWithEntryUpstreamBandwidthTooLow()248     public void testMatchWithEntryUpstreamBandwidthTooLow() {
249         verifyMatchesPriorityRuleForUpstreamBandwidth(
250                 LINK_UPSTREAM_BANDWIDTH_KBPS + 1,
251                 LINK_UPSTREAM_BANDWIDTH_KBPS + 1,
252                 null /* currentlySelected */,
253                 false);
254     }
255 
256     @Test
testMatchWithEntryDownstreamBandwidthEquals()257     public void testMatchWithEntryDownstreamBandwidthEquals() {
258         verifyMatchesPriorityRuleForDownstreamBandwidth(
259                 TEST_MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS,
260                 TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS,
261                 null /* currentlySelected */,
262                 true);
263     }
264 
265     @Test
testMatchWithEntryDownstreamBandwidthTooLow()266     public void testMatchWithEntryDownstreamBandwidthTooLow() {
267         verifyMatchesPriorityRuleForDownstreamBandwidth(
268                 LINK_DOWNSTREAM_BANDWIDTH_KBPS + 1,
269                 LINK_DOWNSTREAM_BANDWIDTH_KBPS + 1,
270                 null /* currentlySelected */,
271                 false);
272     }
273 
274     @Test
testMatchWithExitUpstreamBandwidthEquals()275     public void testMatchWithExitUpstreamBandwidthEquals() {
276         verifyMatchesPriorityRuleForUpstreamBandwidth(
277                 TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS,
278                 TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS,
279                 mWifiNetworkRecord,
280                 true);
281     }
282 
283     @Test
testMatchWithExitUpstreamBandwidthTooLow()284     public void testMatchWithExitUpstreamBandwidthTooLow() {
285         verifyMatchesPriorityRuleForUpstreamBandwidth(
286                 LINK_UPSTREAM_BANDWIDTH_KBPS + 1,
287                 LINK_UPSTREAM_BANDWIDTH_KBPS + 1,
288                 mWifiNetworkRecord,
289                 false);
290     }
291 
292     @Test
testMatchWithExitDownstreamBandwidthEquals()293     public void testMatchWithExitDownstreamBandwidthEquals() {
294         verifyMatchesPriorityRuleForDownstreamBandwidth(
295                 TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS,
296                 TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS,
297                 mWifiNetworkRecord,
298                 true);
299     }
300 
301     @Test
testMatchWithExitDownstreamBandwidthTooLow()302     public void testMatchWithExitDownstreamBandwidthTooLow() {
303         verifyMatchesPriorityRuleForDownstreamBandwidth(
304                 LINK_DOWNSTREAM_BANDWIDTH_KBPS + 1,
305                 LINK_DOWNSTREAM_BANDWIDTH_KBPS + 1,
306                 mWifiNetworkRecord,
307                 false);
308     }
309 
verifyMatchWifi( boolean isSelectedNetwork, PersistableBundle carrierConfig, boolean expectMatch)310     private void verifyMatchWifi(
311             boolean isSelectedNetwork, PersistableBundle carrierConfig, boolean expectMatch) {
312         final VcnWifiUnderlyingNetworkTemplate wifiNetworkPriority =
313                 new VcnWifiUnderlyingNetworkTemplate.Builder()
314                         .setMinUpstreamBandwidthKbps(
315                                 TEST_MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS,
316                                 TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS)
317                         .setMinDownstreamBandwidthKbps(
318                                 TEST_MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS,
319                                 TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS)
320                         .build();
321         final UnderlyingNetworkRecord selectedNetworkRecord =
322                 isSelectedNetwork ? mWifiNetworkRecord : null;
323         assertEquals(
324                 expectMatch,
325                 checkMatchesWifiPriorityRule(
326                         wifiNetworkPriority,
327                         mWifiNetworkRecord,
328                         selectedNetworkRecord,
329                         carrierConfig == null
330                                 ? null
331                                 : new PersistableBundleWrapper(carrierConfig)));
332     }
333 
334     @Test
testMatchSelectedWifi()335     public void testMatchSelectedWifi() {
336         verifyMatchWifi(
337                 true /* isSelectedNetwork */, null /* carrierConfig */, true /* expectMatch */);
338     }
339 
340     @Test
testMatchSelectedWifiBelowRssiThreshold()341     public void testMatchSelectedWifiBelowRssiThreshold() {
342         final PersistableBundle carrierConfig = new PersistableBundle();
343         carrierConfig.putInt(
344                 VcnManager.VCN_NETWORK_SELECTION_WIFI_EXIT_RSSI_THRESHOLD_KEY, WIFI_RSSI_HIGH);
345         carrierConfig.putInt(
346                 VcnManager.VCN_NETWORK_SELECTION_WIFI_ENTRY_RSSI_THRESHOLD_KEY, WIFI_RSSI_HIGH);
347 
348         verifyMatchWifi(true /* isSelectedNetwork */, carrierConfig, false /* expectMatch */);
349     }
350 
351     @Test
testMatchUnselectedWifi()352     public void testMatchUnselectedWifi() {
353         verifyMatchWifi(
354                 false /* isSelectedNetwork */, null /* carrierConfig */, true /* expectMatch */);
355     }
356 
357     @Test
testMatchUnselectedWifiBelowRssiThreshold()358     public void testMatchUnselectedWifiBelowRssiThreshold() {
359         final PersistableBundle carrierConfig = new PersistableBundle();
360         carrierConfig.putInt(
361                 VcnManager.VCN_NETWORK_SELECTION_WIFI_ENTRY_RSSI_THRESHOLD_KEY, WIFI_RSSI_HIGH);
362 
363         verifyMatchWifi(false /* isSelectedNetwork */, carrierConfig, false /* expectMatch */);
364     }
365 
verifyMatchWifiWithSsid(boolean useMatchedSsid, boolean expectMatch)366     private void verifyMatchWifiWithSsid(boolean useMatchedSsid, boolean expectMatch) {
367         final String nwPrioritySsid = useMatchedSsid ? SSID : SSID_OTHER;
368         final VcnWifiUnderlyingNetworkTemplate wifiNetworkPriority =
369                 new VcnWifiUnderlyingNetworkTemplate.Builder()
370                         .setMinUpstreamBandwidthKbps(
371                                 TEST_MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS,
372                                 TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS)
373                         .setMinDownstreamBandwidthKbps(
374                                 TEST_MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS,
375                                 TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS)
376                         .setSsids(Set.of(nwPrioritySsid))
377                         .build();
378 
379         assertEquals(
380                 expectMatch,
381                 checkMatchesWifiPriorityRule(
382                         wifiNetworkPriority,
383                         mWifiNetworkRecord,
384                         null /* currentlySelecetd */,
385                         null /* carrierConfig */));
386     }
387 
388     @Test
testMatchWifiWithSsid()389     public void testMatchWifiWithSsid() {
390         verifyMatchWifiWithSsid(true /* useMatchedSsid */, true /* expectMatch */);
391     }
392 
393     @Test
testMatchWifiFailWithWrongSsid()394     public void testMatchWifiFailWithWrongSsid() {
395         verifyMatchWifiWithSsid(false /* useMatchedSsid */, false /* expectMatch */);
396     }
397 
getCellNetworkPriorityBuilder()398     private static VcnCellUnderlyingNetworkTemplate.Builder getCellNetworkPriorityBuilder() {
399         return new VcnCellUnderlyingNetworkTemplate.Builder()
400                 .setMinUpstreamBandwidthKbps(
401                         TEST_MIN_ENTRY_UPSTREAM_BANDWIDTH_KBPS,
402                         TEST_MIN_EXIT_UPSTREAM_BANDWIDTH_KBPS)
403                 .setMinDownstreamBandwidthKbps(
404                         TEST_MIN_ENTRY_DOWNSTREAM_BANDWIDTH_KBPS,
405                         TEST_MIN_EXIT_DOWNSTREAM_BANDWIDTH_KBPS);
406     }
407 
408     @Test
testMatchMacroCell()409     public void testMatchMacroCell() {
410         assertTrue(
411                 checkMatchesCellPriorityRule(
412                         mVcnContext,
413                         getCellNetworkPriorityBuilder().build(),
414                         mCellNetworkRecord,
415                         SUB_GROUP,
416                         mSubscriptionSnapshot));
417     }
418 
419     @Test
testMatchOpportunisticCell()420     public void testMatchOpportunisticCell() {
421         final VcnCellUnderlyingNetworkTemplate opportunisticCellNetworkPriority =
422                 getCellNetworkPriorityBuilder().setOpportunistic(MATCH_REQUIRED).build();
423 
424         when(mSubscriptionSnapshot.isOpportunistic(SUB_ID)).thenReturn(true);
425         when(mSubscriptionSnapshot.getAllSubIdsInGroup(SUB_GROUP)).thenReturn(new ArraySet<>());
426 
427         assertTrue(
428                 checkMatchesCellPriorityRule(
429                         mVcnContext,
430                         opportunisticCellNetworkPriority,
431                         mCellNetworkRecord,
432                         SUB_GROUP,
433                         mSubscriptionSnapshot));
434     }
435 
verifyMatchMacroCellWithAllowedPlmnIds( boolean useMatchedPlmnId, boolean expectMatch)436     private void verifyMatchMacroCellWithAllowedPlmnIds(
437             boolean useMatchedPlmnId, boolean expectMatch) {
438         final String networkPriorityPlmnId = useMatchedPlmnId ? PLMN_ID : PLMN_ID_OTHER;
439         final VcnCellUnderlyingNetworkTemplate networkPriority =
440                 getCellNetworkPriorityBuilder()
441                         .setOperatorPlmnIds(Set.of(networkPriorityPlmnId))
442                         .build();
443 
444         assertEquals(
445                 expectMatch,
446                 checkMatchesCellPriorityRule(
447                         mVcnContext,
448                         networkPriority,
449                         mCellNetworkRecord,
450                         SUB_GROUP,
451                         mSubscriptionSnapshot));
452     }
453 
454     @Test
testMatchMacroCellWithAllowedPlmnIds()455     public void testMatchMacroCellWithAllowedPlmnIds() {
456         verifyMatchMacroCellWithAllowedPlmnIds(true /* useMatchedPlmnId */, true /* expectMatch */);
457     }
458 
459     @Test
testMatchMacroCellFailWithDisallowedPlmnIds()460     public void testMatchMacroCellFailWithDisallowedPlmnIds() {
461         verifyMatchMacroCellWithAllowedPlmnIds(
462                 false /* useMatchedPlmnId */, false /* expectMatch */);
463     }
464 
verifyMatchMacroCellWithAllowedSpecificCarrierIds( boolean useMatchedCarrierId, boolean expectMatch)465     private void verifyMatchMacroCellWithAllowedSpecificCarrierIds(
466             boolean useMatchedCarrierId, boolean expectMatch) {
467         final int networkPriorityCarrierId = useMatchedCarrierId ? CARRIER_ID : CARRIER_ID_OTHER;
468         final VcnCellUnderlyingNetworkTemplate networkPriority =
469                 getCellNetworkPriorityBuilder()
470                         .setSimSpecificCarrierIds(Set.of(networkPriorityCarrierId))
471                         .build();
472 
473         assertEquals(
474                 expectMatch,
475                 checkMatchesCellPriorityRule(
476                         mVcnContext,
477                         networkPriority,
478                         mCellNetworkRecord,
479                         SUB_GROUP,
480                         mSubscriptionSnapshot));
481     }
482 
483     @Test
testMatchMacroCellWithAllowedSpecificCarrierIds()484     public void testMatchMacroCellWithAllowedSpecificCarrierIds() {
485         verifyMatchMacroCellWithAllowedSpecificCarrierIds(
486                 true /* useMatchedCarrierId */, true /* expectMatch */);
487     }
488 
489     @Test
testMatchMacroCellFailWithDisallowedSpecificCarrierIds()490     public void testMatchMacroCellFailWithDisallowedSpecificCarrierIds() {
491         verifyMatchMacroCellWithAllowedSpecificCarrierIds(
492                 false /* useMatchedCarrierId */, false /* expectMatch */);
493     }
494 
495     @Test
testMatchWifiFailWithoutNotRoamingBit()496     public void testMatchWifiFailWithoutNotRoamingBit() {
497         final VcnCellUnderlyingNetworkTemplate networkPriority =
498                 getCellNetworkPriorityBuilder().setRoaming(MATCH_FORBIDDEN).build();
499 
500         assertFalse(
501                 checkMatchesCellPriorityRule(
502                         mVcnContext,
503                         networkPriority,
504                         mCellNetworkRecord,
505                         SUB_GROUP,
506                         mSubscriptionSnapshot));
507     }
508 
verifyMatchCellWithRequiredCapabilities( VcnCellUnderlyingNetworkTemplate template, boolean expectMatch)509     private void verifyMatchCellWithRequiredCapabilities(
510             VcnCellUnderlyingNetworkTemplate template, boolean expectMatch) {
511         assertEquals(
512                 expectMatch,
513                 checkMatchesPriorityRule(
514                         mVcnContext,
515                         template,
516                         mCellNetworkRecord,
517                         SUB_GROUP,
518                         mSubscriptionSnapshot,
519                         null /* currentlySelected */,
520                         null /* carrierConfig */));
521     }
522 
523     @Test
testMatchCell()524     public void testMatchCell() {
525         final VcnCellUnderlyingNetworkTemplate template =
526                 getCellNetworkPriorityBuilder().setInternet(MATCH_REQUIRED).build();
527         verifyMatchCellWithRequiredCapabilities(template, true /* expectMatch */);
528     }
529 
530     @Test
testMatchCellFail_RequiredCapabilitiesMissing()531     public void testMatchCellFail_RequiredCapabilitiesMissing() {
532         final VcnCellUnderlyingNetworkTemplate template =
533                 getCellNetworkPriorityBuilder().setCbs(MATCH_REQUIRED).build();
534         verifyMatchCellWithRequiredCapabilities(template, false /* expectMatch */);
535     }
536 
537     @Test
testMatchCellFail_ForbiddenCapabilitiesFound()538     public void testMatchCellFail_ForbiddenCapabilitiesFound() {
539         final VcnCellUnderlyingNetworkTemplate template =
540                 getCellNetworkPriorityBuilder().setDun(MATCH_FORBIDDEN).build();
541         verifyMatchCellWithRequiredCapabilities(template, false /* expectMatch */);
542     }
543 
544     @Test
testCalculatePriorityClass()545     public void testCalculatePriorityClass() throws Exception {
546         assertEquals(2, mCellNetworkRecord.priorityClass);
547     }
548 
checkCalculatePriorityClassFailToMatchAny( boolean hasInternet, int expectedPriorityClass)549     private void checkCalculatePriorityClassFailToMatchAny(
550             boolean hasInternet, int expectedPriorityClass) throws Exception {
551         final List<VcnUnderlyingNetworkTemplate> templatesRequireDun =
552                 Collections.singletonList(
553                         new VcnCellUnderlyingNetworkTemplate.Builder()
554                                 .setDun(MATCH_REQUIRED)
555                                 .build());
556 
557         final NetworkCapabilities.Builder ncBuilder =
558                 new NetworkCapabilities.Builder()
559                         .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
560         if (hasInternet) {
561             ncBuilder.addCapability(NET_CAPABILITY_INTERNET);
562         }
563 
564         final UnderlyingNetworkRecord nonDunNetworkRecord =
565                 getTestNetworkRecord(ncBuilder.build(), templatesRequireDun);
566 
567         assertEquals(expectedPriorityClass, nonDunNetworkRecord.priorityClass);
568     }
569 
570     @Test
testCalculatePriorityClassFailToMatchAny_InternetNetwork()571     public void testCalculatePriorityClassFailToMatchAny_InternetNetwork() throws Exception {
572         checkCalculatePriorityClassFailToMatchAny(true /* hasInternet */, PRIORITY_FALLBACK);
573     }
574 
575     @Test
testCalculatePriorityClassFailToMatchAny_NonInternetNetwork()576     public void testCalculatePriorityClassFailToMatchAny_NonInternetNetwork() throws Exception {
577         checkCalculatePriorityClassFailToMatchAny(false /* hasInternet */, PRIORITY_INVALID);
578     }
579 }
580