1 /*
2  * Copyright (C) 2017 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 android.net;
18 
19 import static android.net.NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
20 import static android.net.NetworkCapabilities.MAX_TRANSPORT;
21 import static android.net.NetworkCapabilities.MIN_TRANSPORT;
22 import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
23 import static android.net.NetworkCapabilities.NET_CAPABILITY_CBS;
24 import static android.net.NetworkCapabilities.NET_CAPABILITY_EIMS;
25 import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND;
26 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
27 import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS;
28 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
29 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
30 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
31 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
32 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
33 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PAID;
34 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE;
35 import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
36 import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED;
37 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
38 import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P;
39 import static android.net.NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION;
40 import static android.net.NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS;
41 import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
42 import static android.net.NetworkCapabilities.SIGNAL_STRENGTH_UNSPECIFIED;
43 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
44 import static android.net.NetworkCapabilities.TRANSPORT_TEST;
45 import static android.net.NetworkCapabilities.TRANSPORT_VPN;
46 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
47 import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE;
48 import static android.os.Process.INVALID_UID;
49 
50 import static com.android.modules.utils.build.SdkLevel.isAtLeastR;
51 import static com.android.modules.utils.build.SdkLevel.isAtLeastS;
52 import static com.android.net.module.util.NetworkCapabilitiesUtils.TRANSPORT_USB;
53 import static com.android.testutils.MiscAsserts.assertEmpty;
54 import static com.android.testutils.MiscAsserts.assertThrows;
55 import static com.android.testutils.ParcelUtils.assertParcelingIsLossless;
56 
57 import static org.junit.Assert.assertArrayEquals;
58 import static org.junit.Assert.assertEquals;
59 import static org.junit.Assert.assertFalse;
60 import static org.junit.Assert.assertNotEquals;
61 import static org.junit.Assert.assertNull;
62 import static org.junit.Assert.assertTrue;
63 import static org.junit.Assert.fail;
64 import static org.junit.Assume.assumeTrue;
65 
66 import android.net.wifi.aware.DiscoverySession;
67 import android.net.wifi.aware.PeerHandle;
68 import android.net.wifi.aware.WifiAwareNetworkSpecifier;
69 import android.os.Build;
70 import android.test.suitebuilder.annotation.SmallTest;
71 import android.util.ArraySet;
72 import android.util.Range;
73 
74 import androidx.test.runner.AndroidJUnit4;
75 
76 import com.android.testutils.CompatUtil;
77 import com.android.testutils.DevSdkIgnoreRule;
78 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
79 
80 import org.junit.Rule;
81 import org.junit.Test;
82 import org.junit.runner.RunWith;
83 import org.mockito.Mockito;
84 
85 import java.util.Arrays;
86 import java.util.Set;
87 
88 @RunWith(AndroidJUnit4.class)
89 @SmallTest
90 public class NetworkCapabilitiesTest {
91     private static final String TEST_SSID = "TEST_SSID";
92     private static final String DIFFERENT_TEST_SSID = "DIFFERENT_TEST_SSID";
93     private static final int TEST_SUBID1 = 1;
94     private static final int TEST_SUBID2 = 2;
95     private static final int TEST_SUBID3 = 3;
96 
97     @Rule
98     public DevSdkIgnoreRule mDevSdkIgnoreRule = new DevSdkIgnoreRule();
99 
100     private DiscoverySession mDiscoverySession = Mockito.mock(DiscoverySession.class);
101     private PeerHandle mPeerHandle = Mockito.mock(PeerHandle.class);
102 
103     @Test
testMaybeMarkCapabilitiesRestricted()104     public void testMaybeMarkCapabilitiesRestricted() {
105         // check that internet does not get restricted
106         NetworkCapabilities netCap = new NetworkCapabilities();
107         netCap.addCapability(NET_CAPABILITY_INTERNET);
108         netCap.maybeMarkCapabilitiesRestricted();
109         assertTrue(netCap.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
110 
111         // metered-ness shouldn't matter
112         netCap = new NetworkCapabilities();
113         netCap.addCapability(NET_CAPABILITY_INTERNET);
114         netCap.addCapability(NET_CAPABILITY_NOT_METERED);
115         netCap.maybeMarkCapabilitiesRestricted();
116         assertTrue(netCap.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
117         netCap = new NetworkCapabilities();
118         netCap.addCapability(NET_CAPABILITY_INTERNET);
119         netCap.removeCapability(NET_CAPABILITY_NOT_METERED);
120         netCap.maybeMarkCapabilitiesRestricted();
121         assertTrue(netCap.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
122 
123         // add EIMS - bundled with unrestricted means it's unrestricted
124         netCap = new NetworkCapabilities();
125         netCap.addCapability(NET_CAPABILITY_INTERNET);
126         netCap.addCapability(NET_CAPABILITY_EIMS);
127         netCap.addCapability(NET_CAPABILITY_NOT_METERED);
128         netCap.maybeMarkCapabilitiesRestricted();
129         assertTrue(netCap.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
130         netCap = new NetworkCapabilities();
131         netCap.addCapability(NET_CAPABILITY_INTERNET);
132         netCap.addCapability(NET_CAPABILITY_EIMS);
133         netCap.removeCapability(NET_CAPABILITY_NOT_METERED);
134         netCap.maybeMarkCapabilitiesRestricted();
135         assertTrue(netCap.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
136 
137         // just a restricted cap should be restricted regardless of meteredness
138         netCap = new NetworkCapabilities();
139         netCap.addCapability(NET_CAPABILITY_EIMS);
140         netCap.addCapability(NET_CAPABILITY_NOT_METERED);
141         netCap.maybeMarkCapabilitiesRestricted();
142         assertFalse(netCap.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
143         netCap = new NetworkCapabilities();
144         netCap.addCapability(NET_CAPABILITY_EIMS);
145         netCap.removeCapability(NET_CAPABILITY_NOT_METERED);
146         netCap.maybeMarkCapabilitiesRestricted();
147         assertFalse(netCap.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
148 
149         // try 2 restricted caps
150         netCap = new NetworkCapabilities();
151         netCap.addCapability(NET_CAPABILITY_CBS);
152         netCap.addCapability(NET_CAPABILITY_EIMS);
153         netCap.addCapability(NET_CAPABILITY_NOT_METERED);
154         netCap.maybeMarkCapabilitiesRestricted();
155         assertFalse(netCap.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
156         netCap = new NetworkCapabilities();
157         netCap.addCapability(NET_CAPABILITY_CBS);
158         netCap.addCapability(NET_CAPABILITY_EIMS);
159         netCap.removeCapability(NET_CAPABILITY_NOT_METERED);
160         netCap.maybeMarkCapabilitiesRestricted();
161         assertFalse(netCap.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
162     }
163 
164     @Test
testDescribeImmutableDifferences()165     public void testDescribeImmutableDifferences() {
166         NetworkCapabilities nc1;
167         NetworkCapabilities nc2;
168 
169         // Transports changing
170         nc1 = new NetworkCapabilities().addTransportType(TRANSPORT_CELLULAR);
171         nc2 = new NetworkCapabilities().addTransportType(TRANSPORT_WIFI);
172         assertNotEquals("", nc1.describeImmutableDifferences(nc2));
173         assertEquals("", nc1.describeImmutableDifferences(nc1));
174 
175         // Mutable capability changing
176         nc1 = new NetworkCapabilities().addCapability(NET_CAPABILITY_VALIDATED);
177         nc2 = new NetworkCapabilities();
178         assertEquals("", nc1.describeImmutableDifferences(nc2));
179         assertEquals("", nc1.describeImmutableDifferences(nc1));
180 
181         // NOT_METERED changing (http://b/63326103)
182         nc1 = new NetworkCapabilities()
183                 .addCapability(NET_CAPABILITY_NOT_METERED)
184                 .addCapability(NET_CAPABILITY_INTERNET);
185         nc2 = new NetworkCapabilities().addCapability(NET_CAPABILITY_INTERNET);
186         assertEquals("", nc1.describeImmutableDifferences(nc2));
187         assertEquals("", nc1.describeImmutableDifferences(nc1));
188 
189         // Immutable capability changing
190         nc1 = new NetworkCapabilities()
191                 .addCapability(NET_CAPABILITY_INTERNET)
192                 .removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
193         nc2 = new NetworkCapabilities().addCapability(NET_CAPABILITY_INTERNET);
194         assertNotEquals("", nc1.describeImmutableDifferences(nc2));
195         assertEquals("", nc1.describeImmutableDifferences(nc1));
196 
197         // Specifier changing
198         nc1 = new NetworkCapabilities().addTransportType(TRANSPORT_WIFI);
199         nc2 = new NetworkCapabilities()
200                 .addTransportType(TRANSPORT_WIFI)
201                 .setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier("eth42"));
202         assertNotEquals("", nc1.describeImmutableDifferences(nc2));
203         assertEquals("", nc1.describeImmutableDifferences(nc1));
204     }
205 
206     @Test
testLinkBandwidthUtils()207     public void testLinkBandwidthUtils() {
208         assertEquals(LINK_BANDWIDTH_UNSPECIFIED, NetworkCapabilities
209                 .minBandwidth(LINK_BANDWIDTH_UNSPECIFIED, LINK_BANDWIDTH_UNSPECIFIED));
210         assertEquals(10, NetworkCapabilities
211                 .minBandwidth(LINK_BANDWIDTH_UNSPECIFIED, 10));
212         assertEquals(10, NetworkCapabilities
213                 .minBandwidth(10, LINK_BANDWIDTH_UNSPECIFIED));
214         assertEquals(10, NetworkCapabilities
215                 .minBandwidth(10, 20));
216 
217         assertEquals(LINK_BANDWIDTH_UNSPECIFIED, NetworkCapabilities
218                 .maxBandwidth(LINK_BANDWIDTH_UNSPECIFIED, LINK_BANDWIDTH_UNSPECIFIED));
219         assertEquals(10, NetworkCapabilities
220                 .maxBandwidth(LINK_BANDWIDTH_UNSPECIFIED, 10));
221         assertEquals(10, NetworkCapabilities
222                 .maxBandwidth(10, LINK_BANDWIDTH_UNSPECIFIED));
223         assertEquals(20, NetworkCapabilities
224                 .maxBandwidth(10, 20));
225     }
226 
227     @Test
testSetUids()228     public void testSetUids() {
229         final NetworkCapabilities netCap = new NetworkCapabilities();
230         // Null uids match all UIDs
231         netCap.setUids(null);
232         assertTrue(netCap.appliesToUid(10));
233         assertTrue(netCap.appliesToUid(200));
234         assertTrue(netCap.appliesToUid(3000));
235         assertTrue(netCap.appliesToUid(10010));
236         assertTrue(netCap.appliesToUidRange(new UidRange(50, 100)));
237         assertTrue(netCap.appliesToUidRange(new UidRange(70, 72)));
238         assertTrue(netCap.appliesToUidRange(new UidRange(3500, 3912)));
239         assertTrue(netCap.appliesToUidRange(new UidRange(1, 100000)));
240 
241         if (isAtLeastS()) {
242             final Set<Range<Integer>> uids = new ArraySet<>();
243             uids.add(uidRange(50, 100));
244             uids.add(uidRange(3000, 4000));
245             netCap.setUids(uids);
246             assertTrue(netCap.appliesToUid(50));
247             assertTrue(netCap.appliesToUid(80));
248             assertTrue(netCap.appliesToUid(100));
249             assertTrue(netCap.appliesToUid(3000));
250             assertTrue(netCap.appliesToUid(3001));
251             assertFalse(netCap.appliesToUid(10));
252             assertFalse(netCap.appliesToUid(25));
253             assertFalse(netCap.appliesToUid(49));
254             assertFalse(netCap.appliesToUid(101));
255             assertFalse(netCap.appliesToUid(2000));
256             assertFalse(netCap.appliesToUid(100000));
257 
258             assertTrue(netCap.appliesToUidRange(new UidRange(50, 100)));
259             assertTrue(netCap.appliesToUidRange(new UidRange(70, 72)));
260             assertTrue(netCap.appliesToUidRange(new UidRange(3500, 3912)));
261             assertFalse(netCap.appliesToUidRange(new UidRange(1, 100)));
262             assertFalse(netCap.appliesToUidRange(new UidRange(49, 100)));
263             assertFalse(netCap.appliesToUidRange(new UidRange(1, 10)));
264             assertFalse(netCap.appliesToUidRange(new UidRange(60, 101)));
265             assertFalse(netCap.appliesToUidRange(new UidRange(60, 3400)));
266 
267             NetworkCapabilities netCap2 = new NetworkCapabilities();
268             // A new netcap object has null UIDs, so anything will satisfy it.
269             assertTrue(netCap2.satisfiedByUids(netCap));
270             // Still not equal though.
271             assertFalse(netCap2.equalsUids(netCap));
272             netCap2.setUids(uids);
273             assertTrue(netCap2.satisfiedByUids(netCap));
274             assertTrue(netCap.equalsUids(netCap2));
275             assertTrue(netCap2.equalsUids(netCap));
276 
277             uids.add(uidRange(600, 700));
278             netCap2.setUids(uids);
279             assertFalse(netCap2.satisfiedByUids(netCap));
280             assertFalse(netCap.appliesToUid(650));
281             assertTrue(netCap2.appliesToUid(650));
282             netCap.combineCapabilities(netCap2);
283             assertTrue(netCap2.satisfiedByUids(netCap));
284             assertTrue(netCap.appliesToUid(650));
285             assertFalse(netCap.appliesToUid(500));
286 
287             assertTrue(new NetworkCapabilities().satisfiedByUids(netCap));
288             netCap.combineCapabilities(new NetworkCapabilities());
289             assertTrue(netCap.appliesToUid(500));
290             assertTrue(netCap.appliesToUidRange(new UidRange(1, 100000)));
291             assertFalse(netCap2.appliesToUid(500));
292             assertFalse(netCap2.appliesToUidRange(new UidRange(1, 100000)));
293             assertTrue(new NetworkCapabilities().satisfiedByUids(netCap));
294 
295             // Null uids satisfies everything.
296             netCap.setUids(null);
297             assertTrue(netCap2.satisfiedByUids(netCap));
298             assertTrue(netCap.satisfiedByUids(netCap2));
299             netCap2.setUids(null);
300             assertTrue(netCap2.satisfiedByUids(netCap));
301             assertTrue(netCap.satisfiedByUids(netCap2));
302         }
303     }
304 
305     @Test
testParcelNetworkCapabilities()306     public void testParcelNetworkCapabilities() {
307         final Set<Range<Integer>> uids = new ArraySet<>();
308         uids.add(uidRange(50, 100));
309         uids.add(uidRange(3000, 4000));
310         final NetworkCapabilities netCap = new NetworkCapabilities()
311             .addCapability(NET_CAPABILITY_INTERNET)
312             .addCapability(NET_CAPABILITY_EIMS)
313             .addCapability(NET_CAPABILITY_NOT_METERED);
314         if (isAtLeastS()) {
315             netCap.setSubscriptionIds(Set.of(TEST_SUBID1, TEST_SUBID2));
316             netCap.setUids(uids);
317         }
318         if (isAtLeastR()) {
319             netCap.setOwnerUid(123);
320             netCap.setAdministratorUids(new int[] {5, 11});
321         }
322         assertParcelingIsLossless(netCap);
323         netCap.setSSID(TEST_SSID);
324         testParcelSane(netCap);
325     }
326 
327     @Test
testParcelNetworkCapabilitiesWithRequestorUidAndPackageName()328     public void testParcelNetworkCapabilitiesWithRequestorUidAndPackageName() {
329         final NetworkCapabilities netCap = new NetworkCapabilities()
330                 .addCapability(NET_CAPABILITY_INTERNET)
331                 .addCapability(NET_CAPABILITY_EIMS)
332                 .addCapability(NET_CAPABILITY_NOT_METERED);
333         if (isAtLeastR()) {
334             netCap.setRequestorPackageName("com.android.test");
335             netCap.setRequestorUid(9304);
336         }
337         assertParcelingIsLossless(netCap);
338         netCap.setSSID(TEST_SSID);
339         testParcelSane(netCap);
340     }
341 
testParcelSane(NetworkCapabilities cap)342     private void testParcelSane(NetworkCapabilities cap) {
343         assertParcelingIsLossless(cap);
344     }
345 
createNetworkCapabilitiesWithTransportInfo()346     private static NetworkCapabilities createNetworkCapabilitiesWithTransportInfo() {
347         return new NetworkCapabilities()
348                 .addCapability(NET_CAPABILITY_INTERNET)
349                 .addCapability(NET_CAPABILITY_EIMS)
350                 .addCapability(NET_CAPABILITY_NOT_METERED)
351                 .setSSID(TEST_SSID)
352                 .setTransportInfo(new TestTransportInfo())
353                 .setRequestorPackageName("com.android.test")
354                 .setRequestorUid(9304);
355     }
356 
357     @Test
testNetworkCapabilitiesCopyWithNoRedactions()358     public void testNetworkCapabilitiesCopyWithNoRedactions() {
359         assumeTrue(isAtLeastS());
360 
361         final NetworkCapabilities netCap = createNetworkCapabilitiesWithTransportInfo();
362         final NetworkCapabilities netCapWithNoRedactions =
363                 new NetworkCapabilities(netCap, NetworkCapabilities.REDACT_NONE);
364         TestTransportInfo testTransportInfo =
365                 (TestTransportInfo) netCapWithNoRedactions.getTransportInfo();
366         assertFalse(testTransportInfo.locationRedacted);
367         assertFalse(testTransportInfo.localMacAddressRedacted);
368         assertFalse(testTransportInfo.settingsRedacted);
369     }
370 
371     @Test
testNetworkCapabilitiesCopyWithoutLocationSensitiveFields()372     public void testNetworkCapabilitiesCopyWithoutLocationSensitiveFields() {
373         assumeTrue(isAtLeastS());
374 
375         final NetworkCapabilities netCap = createNetworkCapabilitiesWithTransportInfo();
376         final NetworkCapabilities netCapWithNoRedactions =
377                 new NetworkCapabilities(netCap, REDACT_FOR_ACCESS_FINE_LOCATION);
378         TestTransportInfo testTransportInfo =
379                 (TestTransportInfo) netCapWithNoRedactions.getTransportInfo();
380         assertTrue(testTransportInfo.locationRedacted);
381         assertFalse(testTransportInfo.localMacAddressRedacted);
382         assertFalse(testTransportInfo.settingsRedacted);
383     }
384 
385     @Test
testOemPaid()386     public void testOemPaid() {
387         NetworkCapabilities nc = new NetworkCapabilities();
388         // By default OEM_PAID is neither in the required or forbidden lists and the network is not
389         // restricted.
390         if (isAtLeastS()) {
391             assertFalse(nc.hasForbiddenCapability(NET_CAPABILITY_OEM_PAID));
392         }
393         assertFalse(nc.hasCapability(NET_CAPABILITY_OEM_PAID));
394         nc.maybeMarkCapabilitiesRestricted();
395         assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
396 
397         // Adding OEM_PAID to capability list should make network restricted.
398         nc.addCapability(NET_CAPABILITY_OEM_PAID);
399         nc.addCapability(NET_CAPABILITY_INTERNET);  // Combine with unrestricted capability.
400         nc.maybeMarkCapabilitiesRestricted();
401         assertTrue(nc.hasCapability(NET_CAPABILITY_OEM_PAID));
402         assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
403 
404         // Now let's make request for OEM_PAID network.
405         NetworkCapabilities nr = new NetworkCapabilities();
406         nr.addCapability(NET_CAPABILITY_OEM_PAID);
407         nr.maybeMarkCapabilitiesRestricted();
408         assertTrue(nr.satisfiedByNetworkCapabilities(nc));
409 
410         // Request fails for network with the default capabilities.
411         assertFalse(nr.satisfiedByNetworkCapabilities(new NetworkCapabilities()));
412     }
413 
414     @Test @IgnoreUpTo(Build.VERSION_CODES.R)
testOemPrivate()415     public void testOemPrivate() {
416         NetworkCapabilities nc = new NetworkCapabilities();
417         // By default OEM_PRIVATE is neither in the required or forbidden lists and the network is
418         // not restricted.
419         assertFalse(nc.hasForbiddenCapability(NET_CAPABILITY_OEM_PRIVATE));
420         assertFalse(nc.hasCapability(NET_CAPABILITY_OEM_PRIVATE));
421         nc.maybeMarkCapabilitiesRestricted();
422         assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
423 
424         // Adding OEM_PRIVATE to capability list should make network restricted.
425         nc.addCapability(NET_CAPABILITY_OEM_PRIVATE);
426         nc.addCapability(NET_CAPABILITY_INTERNET);  // Combine with unrestricted capability.
427         nc.maybeMarkCapabilitiesRestricted();
428         assertTrue(nc.hasCapability(NET_CAPABILITY_OEM_PRIVATE));
429         assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
430 
431         // Now let's make request for OEM_PRIVATE network.
432         NetworkCapabilities nr = new NetworkCapabilities();
433         nr.addCapability(NET_CAPABILITY_OEM_PRIVATE);
434         nr.maybeMarkCapabilitiesRestricted();
435         assertTrue(nr.satisfiedByNetworkCapabilities(nc));
436 
437         // Request fails for network with the default capabilities.
438         assertFalse(nr.satisfiedByNetworkCapabilities(new NetworkCapabilities()));
439     }
440 
441     @Test @IgnoreUpTo(Build.VERSION_CODES.R)
testForbiddenCapabilities()442     public void testForbiddenCapabilities() {
443         NetworkCapabilities network = new NetworkCapabilities();
444 
445         NetworkCapabilities request = new NetworkCapabilities();
446         assertTrue("Request: " + request + ", Network:" + network,
447                 request.satisfiedByNetworkCapabilities(network));
448 
449         // Requesting absence of capabilities that network doesn't have. Request should satisfy.
450         request.addForbiddenCapability(NET_CAPABILITY_WIFI_P2P);
451         request.addForbiddenCapability(NET_CAPABILITY_NOT_METERED);
452         assertTrue(request.satisfiedByNetworkCapabilities(network));
453         assertArrayEquals(new int[]{NET_CAPABILITY_WIFI_P2P,
454                         NET_CAPABILITY_NOT_METERED},
455                 request.getForbiddenCapabilities());
456 
457         // This is a default capability, just want to make sure its there because we use it below.
458         assertTrue(network.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
459 
460         // Verify that adding forbidden capability will effectively remove it from capability list.
461         request.addForbiddenCapability(NET_CAPABILITY_NOT_RESTRICTED);
462         assertTrue(request.hasForbiddenCapability(NET_CAPABILITY_NOT_RESTRICTED));
463         assertFalse(request.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
464 
465         // Now this request won't be satisfied because network contains NOT_RESTRICTED.
466         assertFalse(request.satisfiedByNetworkCapabilities(network));
467         network.removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
468         assertTrue(request.satisfiedByNetworkCapabilities(network));
469 
470         // Verify that adding capability will effectively remove it from forbidden list
471         request.addCapability(NET_CAPABILITY_NOT_RESTRICTED);
472         assertTrue(request.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
473         assertFalse(request.hasForbiddenCapability(NET_CAPABILITY_NOT_RESTRICTED));
474 
475         assertFalse(request.satisfiedByNetworkCapabilities(network));
476         network.addCapability(NET_CAPABILITY_NOT_RESTRICTED);
477         assertTrue(request.satisfiedByNetworkCapabilities(network));
478     }
479 
480     @Test
testConnectivityManagedCapabilities()481     public void testConnectivityManagedCapabilities() {
482         NetworkCapabilities nc = new NetworkCapabilities();
483         assertFalse(nc.hasConnectivityManagedCapability());
484         // Check every single system managed capability.
485         nc.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
486         assertTrue(nc.hasConnectivityManagedCapability());
487         nc.removeCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
488         nc.addCapability(NET_CAPABILITY_FOREGROUND);
489         assertTrue(nc.hasConnectivityManagedCapability());
490         nc.removeCapability(NET_CAPABILITY_FOREGROUND);
491         nc.addCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY);
492         assertTrue(nc.hasConnectivityManagedCapability());
493         nc.removeCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY);
494         nc.addCapability(NET_CAPABILITY_VALIDATED);
495         assertTrue(nc.hasConnectivityManagedCapability());
496     }
497 
498     @Test
testEqualsNetCapabilities()499     public void testEqualsNetCapabilities() {
500         NetworkCapabilities nc1 = new NetworkCapabilities();
501         NetworkCapabilities nc2 = new NetworkCapabilities();
502         assertTrue(nc1.equalsNetCapabilities(nc2));
503         assertEquals(nc1, nc2);
504 
505         nc1.addCapability(NET_CAPABILITY_MMS);
506         assertFalse(nc1.equalsNetCapabilities(nc2));
507         assertNotEquals(nc1, nc2);
508         nc2.addCapability(NET_CAPABILITY_MMS);
509         assertTrue(nc1.equalsNetCapabilities(nc2));
510         assertEquals(nc1, nc2);
511 
512         if (isAtLeastS()) {
513             nc1.addForbiddenCapability(NET_CAPABILITY_INTERNET);
514             assertFalse(nc1.equalsNetCapabilities(nc2));
515             nc2.addForbiddenCapability(NET_CAPABILITY_INTERNET);
516             assertTrue(nc1.equalsNetCapabilities(nc2));
517 
518             // Remove a required capability doesn't affect forbidden capabilities.
519             // This is a behaviour change from R to S.
520             nc1.removeCapability(NET_CAPABILITY_INTERNET);
521             assertTrue(nc1.equalsNetCapabilities(nc2));
522 
523             nc1.removeForbiddenCapability(NET_CAPABILITY_INTERNET);
524             assertFalse(nc1.equalsNetCapabilities(nc2));
525             nc2.removeForbiddenCapability(NET_CAPABILITY_INTERNET);
526             assertTrue(nc1.equalsNetCapabilities(nc2));
527         }
528     }
529 
530     @Test
testSSID()531     public void testSSID() {
532         NetworkCapabilities nc1 = new NetworkCapabilities();
533         NetworkCapabilities nc2 = new NetworkCapabilities();
534         assertTrue(nc2.satisfiedBySSID(nc1));
535 
536         nc1.setSSID(TEST_SSID);
537         assertTrue(nc2.satisfiedBySSID(nc1));
538         nc2.setSSID("different " + TEST_SSID);
539         assertFalse(nc2.satisfiedBySSID(nc1));
540 
541         assertTrue(nc1.satisfiedByImmutableNetworkCapabilities(nc2));
542         assertFalse(nc1.satisfiedByNetworkCapabilities(nc2));
543     }
544 
uidRanges(int from, int to)545     private ArraySet<Range<Integer>> uidRanges(int from, int to) {
546         final ArraySet<Range<Integer>> range = new ArraySet<>(1);
547         range.add(uidRange(from, to));
548         return range;
549     }
550 
uidRange(int from, int to)551     private Range<Integer> uidRange(int from, int to) {
552         return new Range<Integer>(from, to);
553     }
554 
555     @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
testSetAdministratorUids()556     public void testSetAdministratorUids() {
557         NetworkCapabilities nc =
558                 new NetworkCapabilities().setAdministratorUids(new int[] {2, 1, 3});
559 
560         assertArrayEquals(new int[] {1, 2, 3}, nc.getAdministratorUids());
561     }
562 
563     @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
testSetAdministratorUidsWithDuplicates()564     public void testSetAdministratorUidsWithDuplicates() {
565         try {
566             new NetworkCapabilities().setAdministratorUids(new int[] {1, 1});
567             fail("Expected IllegalArgumentException for duplicate uids");
568         } catch (IllegalArgumentException expected) {
569         }
570     }
571 
572     @Test
testCombineCapabilities()573     public void testCombineCapabilities() {
574         NetworkCapabilities nc1 = new NetworkCapabilities();
575         NetworkCapabilities nc2 = new NetworkCapabilities();
576 
577         if (isAtLeastS()) {
578             nc1.addForbiddenCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
579         }
580         nc1.addCapability(NET_CAPABILITY_NOT_ROAMING);
581         assertNotEquals(nc1, nc2);
582         nc2.combineCapabilities(nc1);
583         assertEquals(nc1, nc2);
584         assertTrue(nc2.hasCapability(NET_CAPABILITY_NOT_ROAMING));
585         if (isAtLeastS()) {
586             assertTrue(nc2.hasForbiddenCapability(NET_CAPABILITY_CAPTIVE_PORTAL));
587         }
588 
589         if (isAtLeastS()) {
590             // This will effectively move NOT_ROAMING capability from required to forbidden for nc1.
591             nc1.addForbiddenCapability(NET_CAPABILITY_NOT_ROAMING);
592             // It is not allowed to have the same capability in both wanted and forbidden list.
593             assertThrows(IllegalArgumentException.class, () -> nc2.combineCapabilities(nc1));
594             // Remove forbidden capability to continue other tests.
595             nc1.removeForbiddenCapability(NET_CAPABILITY_NOT_ROAMING);
596         }
597 
598         nc1.setSSID(TEST_SSID);
599         nc2.combineCapabilities(nc1);
600         if (isAtLeastR()) {
601             assertTrue(TEST_SSID.equals(nc2.getSsid()));
602         }
603 
604         // Because they now have the same SSID, the following call should not throw
605         nc2.combineCapabilities(nc1);
606 
607         nc1.setSSID(DIFFERENT_TEST_SSID);
608         try {
609             nc2.combineCapabilities(nc1);
610             fail("Expected IllegalStateException: can't combine different SSIDs");
611         } catch (IllegalStateException expected) {}
612         nc1.setSSID(TEST_SSID);
613 
614         if (isAtLeastS()) {
615             nc1.setUids(uidRanges(10, 13));
616             assertNotEquals(nc1, nc2);
617             nc2.combineCapabilities(nc1);  // Everything + 10~13 is still everything.
618             assertNotEquals(nc1, nc2);
619             nc1.combineCapabilities(nc2);  // 10~13 + everything is everything.
620             assertEquals(nc1, nc2);
621             nc1.setUids(uidRanges(10, 13));
622             nc2.setUids(uidRanges(20, 23));
623             assertNotEquals(nc1, nc2);
624             nc1.combineCapabilities(nc2);
625             assertTrue(nc1.appliesToUid(12));
626             assertFalse(nc2.appliesToUid(12));
627             assertTrue(nc1.appliesToUid(22));
628             assertTrue(nc2.appliesToUid(22));
629 
630             // Verify the subscription id list can be combined only when they are equal.
631             nc1.setSubscriptionIds(Set.of(TEST_SUBID1, TEST_SUBID2));
632             nc2.setSubscriptionIds(Set.of(TEST_SUBID2));
633             assertThrows(IllegalStateException.class, () -> nc2.combineCapabilities(nc1));
634 
635             nc2.setSubscriptionIds(Set.of());
636             assertThrows(IllegalStateException.class, () -> nc2.combineCapabilities(nc1));
637 
638             nc2.setSubscriptionIds(Set.of(TEST_SUBID2, TEST_SUBID1));
639             nc2.combineCapabilities(nc1);
640             assertEquals(Set.of(TEST_SUBID2, TEST_SUBID1), nc2.getSubscriptionIds());
641         }
642     }
643 
644     @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
testCombineCapabilities_AdministratorUids()645     public void testCombineCapabilities_AdministratorUids() {
646         final NetworkCapabilities nc1 = new NetworkCapabilities();
647         final NetworkCapabilities nc2 = new NetworkCapabilities();
648 
649         final int[] adminUids = {3, 6, 12};
650         nc1.setAdministratorUids(adminUids);
651         nc2.combineCapabilities(nc1);
652         assertTrue(nc2.equalsAdministratorUids(nc1));
653         assertArrayEquals(nc2.getAdministratorUids(), adminUids);
654 
655         final int[] adminUidsOtherOrder = {3, 12, 6};
656         nc1.setAdministratorUids(adminUidsOtherOrder);
657         assertTrue(nc2.equalsAdministratorUids(nc1));
658 
659         final int[] adminUids2 = {11, 1, 12, 3, 6};
660         nc1.setAdministratorUids(adminUids2);
661         assertFalse(nc2.equalsAdministratorUids(nc1));
662         assertFalse(Arrays.equals(nc2.getAdministratorUids(), adminUids2));
663         try {
664             nc2.combineCapabilities(nc1);
665             fail("Shouldn't be able to combine different lists of admin UIDs");
666         } catch (IllegalStateException expected) { }
667     }
668 
669     @Test
testSetCapabilities()670     public void testSetCapabilities() {
671         final int[] REQUIRED_CAPABILITIES = new int[] {
672                 NET_CAPABILITY_INTERNET, NET_CAPABILITY_NOT_VPN };
673 
674         NetworkCapabilities nc1 = new NetworkCapabilities();
675         NetworkCapabilities nc2 = new NetworkCapabilities();
676 
677         nc1.setCapabilities(REQUIRED_CAPABILITIES);
678         assertArrayEquals(REQUIRED_CAPABILITIES, nc1.getCapabilities());
679 
680         // Verify that setting and adding capabilities leads to the same object state.
681         nc2.clearAll();
682         for (int cap : REQUIRED_CAPABILITIES) {
683             nc2.addCapability(cap);
684         }
685         assertEquals(nc1, nc2);
686 
687         if (isAtLeastS()) {
688             final int[] forbiddenCapabilities = new int[]{
689                     NET_CAPABILITY_NOT_METERED, NET_CAPABILITY_NOT_RESTRICTED };
690 
691             nc1.setCapabilities(REQUIRED_CAPABILITIES, forbiddenCapabilities);
692             assertArrayEquals(REQUIRED_CAPABILITIES, nc1.getCapabilities());
693             assertArrayEquals(forbiddenCapabilities, nc1.getForbiddenCapabilities());
694 
695             nc2.clearAll();
696             for (int cap : REQUIRED_CAPABILITIES) {
697                 nc2.addCapability(cap);
698             }
699             for (int cap : forbiddenCapabilities) {
700                 nc2.addForbiddenCapability(cap);
701             }
702             assertEquals(nc1, nc2);
703         }
704     }
705 
706     @Test
testSetNetworkSpecifierOnMultiTransportNc()707     public void testSetNetworkSpecifierOnMultiTransportNc() {
708         // Sequence 1: Transport + Transport + NetworkSpecifier
709         NetworkCapabilities nc1 = new NetworkCapabilities();
710         nc1.addTransportType(TRANSPORT_CELLULAR).addTransportType(TRANSPORT_WIFI);
711         try {
712             nc1.setNetworkSpecifier(CompatUtil.makeEthernetNetworkSpecifier("eth0"));
713             fail("Cannot set NetworkSpecifier on a NetworkCapability with multiple transports!");
714         } catch (IllegalStateException expected) {
715             // empty
716         }
717 
718         // Sequence 2: Transport + NetworkSpecifier + Transport
719         NetworkCapabilities nc2 = new NetworkCapabilities();
720         nc2.addTransportType(TRANSPORT_CELLULAR).setNetworkSpecifier(
721                 CompatUtil.makeEthernetNetworkSpecifier("testtap3"));
722         try {
723             nc2.addTransportType(TRANSPORT_WIFI);
724             fail("Cannot set a second TransportType of a network which has a NetworkSpecifier!");
725         } catch (IllegalStateException expected) {
726             // empty
727         }
728     }
729 
730     @Test
testSetTransportInfoOnMultiTransportNc()731     public void testSetTransportInfoOnMultiTransportNc() {
732         // Sequence 1: Transport + Transport + TransportInfo
733         NetworkCapabilities nc1 = new NetworkCapabilities();
734         nc1.addTransportType(TRANSPORT_CELLULAR).addTransportType(TRANSPORT_WIFI)
735                 .setTransportInfo(new TestTransportInfo());
736 
737         // Sequence 2: Transport + NetworkSpecifier + Transport
738         NetworkCapabilities nc2 = new NetworkCapabilities();
739         nc2.addTransportType(TRANSPORT_CELLULAR).setTransportInfo(new TestTransportInfo())
740                 .addTransportType(TRANSPORT_WIFI);
741     }
742 
743     @Test
testCombineTransportInfo()744     public void testCombineTransportInfo() {
745         NetworkCapabilities nc1 = new NetworkCapabilities();
746         nc1.setTransportInfo(new TestTransportInfo());
747 
748         NetworkCapabilities nc2 = new NetworkCapabilities();
749         // new TransportInfo so that object is not #equals to nc1's TransportInfo (that's where
750         // combine fails)
751         nc2.setTransportInfo(new TestTransportInfo());
752 
753         try {
754             nc1.combineCapabilities(nc2);
755             fail("Should not be able to combine NetworkCabilities which contain TransportInfos");
756         } catch (IllegalStateException expected) {
757             // empty
758         }
759 
760         // verify that can combine with identical TransportInfo objects
761         NetworkCapabilities nc3 = new NetworkCapabilities();
762         nc3.setTransportInfo(nc1.getTransportInfo());
763         nc1.combineCapabilities(nc3);
764     }
765 
766     @Test
testSet()767     public void testSet() {
768         NetworkCapabilities nc1 = new NetworkCapabilities();
769         NetworkCapabilities nc2 = new NetworkCapabilities();
770 
771         if (isAtLeastS()) {
772             nc1.addForbiddenCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
773         }
774         nc1.addCapability(NET_CAPABILITY_NOT_ROAMING);
775         assertNotEquals(nc1, nc2);
776         nc2.set(nc1);
777         assertEquals(nc1, nc2);
778         assertTrue(nc2.hasCapability(NET_CAPABILITY_NOT_ROAMING));
779         if (isAtLeastS()) {
780             assertTrue(nc2.hasForbiddenCapability(NET_CAPABILITY_CAPTIVE_PORTAL));
781         }
782 
783         if (isAtLeastS()) {
784             // This will effectively move NOT_ROAMING capability from required to forbidden for nc1.
785             nc1.addForbiddenCapability(NET_CAPABILITY_NOT_ROAMING);
786         }
787         nc1.setSSID(TEST_SSID);
788         nc2.set(nc1);
789         assertEquals(nc1, nc2);
790         if (isAtLeastS()) {
791             // Contrary to combineCapabilities, set() will have removed the NOT_ROAMING capability
792             // from nc2.
793             assertFalse(nc2.hasCapability(NET_CAPABILITY_NOT_ROAMING));
794             assertTrue(nc2.hasForbiddenCapability(NET_CAPABILITY_NOT_ROAMING));
795         }
796 
797         if (isAtLeastR()) {
798             assertTrue(TEST_SSID.equals(nc2.getSsid()));
799         }
800 
801         nc1.setSSID(DIFFERENT_TEST_SSID);
802         nc2.set(nc1);
803         assertEquals(nc1, nc2);
804         if (isAtLeastR()) {
805             assertTrue(DIFFERENT_TEST_SSID.equals(nc2.getSsid()));
806         }
807         if (isAtLeastS()) {
808             nc1.setUids(uidRanges(10, 13));
809         } else {
810             nc1.setUids(null);
811         }
812         nc2.set(nc1);  // Overwrites, as opposed to combineCapabilities
813         assertEquals(nc1, nc2);
814 
815         if (isAtLeastS()) {
816             assertThrows(NullPointerException.class, () -> nc1.setSubscriptionIds(null));
817             nc1.setSubscriptionIds(Set.of());
818             nc2.set(nc1);
819             assertEquals(nc1, nc2);
820 
821             nc1.setSubscriptionIds(Set.of(TEST_SUBID1));
822             nc2.set(nc1);
823             assertEquals(nc1, nc2);
824 
825             nc2.setSubscriptionIds(Set.of(TEST_SUBID2, TEST_SUBID1));
826             nc2.set(nc1);
827             assertEquals(nc1, nc2);
828 
829             nc2.setSubscriptionIds(Set.of(TEST_SUBID3, TEST_SUBID2));
830             assertNotEquals(nc1, nc2);
831         }
832     }
833 
834     @Test
testGetTransportTypes()835     public void testGetTransportTypes() {
836         final NetworkCapabilities nc = new NetworkCapabilities();
837         nc.addTransportType(TRANSPORT_CELLULAR);
838         nc.addTransportType(TRANSPORT_WIFI);
839         nc.addTransportType(TRANSPORT_VPN);
840         nc.addTransportType(TRANSPORT_TEST);
841 
842         final int[] transportTypes = nc.getTransportTypes();
843         assertEquals(4, transportTypes.length);
844         assertEquals(TRANSPORT_CELLULAR, transportTypes[0]);
845         assertEquals(TRANSPORT_WIFI, transportTypes[1]);
846         assertEquals(TRANSPORT_VPN, transportTypes[2]);
847         assertEquals(TRANSPORT_TEST, transportTypes[3]);
848     }
849 
850     @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
testTelephonyNetworkSpecifier()851     public void testTelephonyNetworkSpecifier() {
852         final TelephonyNetworkSpecifier specifier = new TelephonyNetworkSpecifier(1);
853         final NetworkCapabilities nc1 = new NetworkCapabilities.Builder()
854                 .addTransportType(TRANSPORT_WIFI)
855                 .setNetworkSpecifier(specifier)
856                 .build();
857         assertEquals(specifier, nc1.getNetworkSpecifier());
858         try {
859             final NetworkCapabilities nc2 = new NetworkCapabilities.Builder()
860                     .setNetworkSpecifier(specifier)
861                     .build();
862             fail("Must have a single transport type. Without transport type or multiple transport"
863                     + " types is invalid.");
864         } catch (IllegalStateException expected) { }
865     }
866 
867     @Test
testWifiAwareNetworkSpecifier()868     public void testWifiAwareNetworkSpecifier() {
869         final NetworkCapabilities nc = new NetworkCapabilities()
870                 .addTransportType(TRANSPORT_WIFI_AWARE);
871         // If NetworkSpecifier is not set, the default value is null.
872         assertNull(nc.getNetworkSpecifier());
873         final WifiAwareNetworkSpecifier specifier = new WifiAwareNetworkSpecifier.Builder(
874                 mDiscoverySession, mPeerHandle).build();
875         nc.setNetworkSpecifier(specifier);
876         assertEquals(specifier, nc.getNetworkSpecifier());
877     }
878 
879     @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
testAdministratorUidsAndOwnerUid()880     public void testAdministratorUidsAndOwnerUid() {
881         // Test default owner uid.
882         // If the owner uid is not set, the default value should be Process.INVALID_UID.
883         final NetworkCapabilities nc1 = new NetworkCapabilities.Builder().build();
884         assertEquals(INVALID_UID, nc1.getOwnerUid());
885         // Test setAdministratorUids and getAdministratorUids.
886         final int[] administratorUids = {1001, 10001};
887         final NetworkCapabilities nc2 = new NetworkCapabilities.Builder()
888                 .setAdministratorUids(administratorUids)
889                 .build();
890         assertTrue(Arrays.equals(administratorUids, nc2.getAdministratorUids()));
891         // Test setOwnerUid and getOwnerUid.
892         // The owner UID must be included in administrator UIDs, or throw IllegalStateException.
893         try {
894             final NetworkCapabilities nc3 = new NetworkCapabilities.Builder()
895                     .setOwnerUid(1001)
896                     .build();
897             fail("The owner UID must be included in administrator UIDs.");
898         } catch (IllegalStateException expected) { }
899         final NetworkCapabilities nc4 = new NetworkCapabilities.Builder()
900                 .setAdministratorUids(administratorUids)
901                 .setOwnerUid(1001)
902                 .build();
903         assertEquals(1001, nc4.getOwnerUid());
904         try {
905             final NetworkCapabilities nc5 = new NetworkCapabilities.Builder()
906                     .setAdministratorUids(null)
907                     .build();
908             fail("Should not set null into setAdministratorUids");
909         } catch (NullPointerException expected) { }
910     }
911 
capsWithSubIds(Integer .... subIds)912     private static NetworkCapabilities capsWithSubIds(Integer ... subIds) {
913         // Since the NetworkRequest would put NOT_VCN_MANAGED capabilities in general, for
914         // every NetworkCapabilities that simulates networks needs to add it too in order to
915         // satisfy these requests.
916         final NetworkCapabilities nc = new NetworkCapabilities.Builder()
917                 .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
918                 .setSubscriptionIds(new ArraySet<>(subIds)).build();
919         assertEquals(new ArraySet<>(subIds), nc.getSubscriptionIds());
920         return nc;
921     }
922 
923     @Test @IgnoreUpTo(Build.VERSION_CODES.R)
testSubIds()924     public void testSubIds() throws Exception {
925         final NetworkCapabilities ncWithoutId = capsWithSubIds();
926         final NetworkCapabilities ncWithId = capsWithSubIds(TEST_SUBID1);
927         final NetworkCapabilities ncWithOtherIds = capsWithSubIds(TEST_SUBID1, TEST_SUBID3);
928         final NetworkCapabilities ncWithoutRequestedIds = capsWithSubIds(TEST_SUBID3);
929 
930         final NetworkRequest requestWithoutId = new NetworkRequest.Builder().build();
931         assertEmpty(requestWithoutId.networkCapabilities.getSubscriptionIds());
932         final NetworkRequest requestWithIds = new NetworkRequest.Builder()
933                 .setSubscriptionIds(Set.of(TEST_SUBID1, TEST_SUBID2)).build();
934         assertEquals(Set.of(TEST_SUBID1, TEST_SUBID2),
935                 requestWithIds.networkCapabilities.getSubscriptionIds());
936 
937         assertFalse(requestWithIds.canBeSatisfiedBy(ncWithoutId));
938         assertTrue(requestWithIds.canBeSatisfiedBy(ncWithOtherIds));
939         assertFalse(requestWithIds.canBeSatisfiedBy(ncWithoutRequestedIds));
940         assertTrue(requestWithIds.canBeSatisfiedBy(ncWithId));
941         assertTrue(requestWithoutId.canBeSatisfiedBy(ncWithoutId));
942         assertTrue(requestWithoutId.canBeSatisfiedBy(ncWithId));
943     }
944 
945     @Test @IgnoreUpTo(Build.VERSION_CODES.R)
testEqualsSubIds()946     public void testEqualsSubIds() throws Exception {
947         assertEquals(capsWithSubIds(), capsWithSubIds());
948         assertNotEquals(capsWithSubIds(), capsWithSubIds(TEST_SUBID1));
949         assertEquals(capsWithSubIds(TEST_SUBID1), capsWithSubIds(TEST_SUBID1));
950         assertNotEquals(capsWithSubIds(TEST_SUBID1), capsWithSubIds(TEST_SUBID2));
951         assertNotEquals(capsWithSubIds(TEST_SUBID1), capsWithSubIds(TEST_SUBID2, TEST_SUBID1));
952         assertEquals(capsWithSubIds(TEST_SUBID1, TEST_SUBID2),
953                 capsWithSubIds(TEST_SUBID2, TEST_SUBID1));
954     }
955 
956     @Test
testLinkBandwidthKbps()957     public void testLinkBandwidthKbps() {
958         final NetworkCapabilities nc = new NetworkCapabilities();
959         // The default value of LinkDown/UpstreamBandwidthKbps should be LINK_BANDWIDTH_UNSPECIFIED.
960         assertEquals(LINK_BANDWIDTH_UNSPECIFIED, nc.getLinkDownstreamBandwidthKbps());
961         assertEquals(LINK_BANDWIDTH_UNSPECIFIED, nc.getLinkUpstreamBandwidthKbps());
962         nc.setLinkDownstreamBandwidthKbps(512);
963         nc.setLinkUpstreamBandwidthKbps(128);
964         assertEquals(512, nc.getLinkDownstreamBandwidthKbps());
965         assertNotEquals(128, nc.getLinkDownstreamBandwidthKbps());
966         assertEquals(128, nc.getLinkUpstreamBandwidthKbps());
967         assertNotEquals(512, nc.getLinkUpstreamBandwidthKbps());
968     }
969 
getMaxTransport()970     private int getMaxTransport() {
971         if (!isAtLeastS() && MAX_TRANSPORT == TRANSPORT_USB) return MAX_TRANSPORT - 1;
972         return MAX_TRANSPORT;
973     }
974 
975     @Test
testSignalStrength()976     public void testSignalStrength() {
977         final NetworkCapabilities nc = new NetworkCapabilities();
978         // The default value of signal strength should be SIGNAL_STRENGTH_UNSPECIFIED.
979         assertEquals(SIGNAL_STRENGTH_UNSPECIFIED, nc.getSignalStrength());
980         nc.setSignalStrength(-80);
981         assertEquals(-80, nc.getSignalStrength());
982         assertNotEquals(-50, nc.getSignalStrength());
983     }
984 
assertNoTransport(NetworkCapabilities nc)985     private void assertNoTransport(NetworkCapabilities nc) {
986         for (int i = MIN_TRANSPORT; i <= getMaxTransport(); i++) {
987             assertFalse(nc.hasTransport(i));
988         }
989     }
990 
991     // Checks that all transport types from MIN_TRANSPORT to maxTransportType are set and all
992     // transport types from maxTransportType + 1 to MAX_TRANSPORT are not set when positiveSequence
993     // is true. If positiveSequence is false, then the check sequence is opposite.
checkCurrentTransportTypes(NetworkCapabilities nc, int maxTransportType, boolean positiveSequence)994     private void checkCurrentTransportTypes(NetworkCapabilities nc, int maxTransportType,
995             boolean positiveSequence) {
996         for (int i = MIN_TRANSPORT; i <= maxTransportType; i++) {
997             if (positiveSequence) {
998                 assertTrue(nc.hasTransport(i));
999             } else {
1000                 assertFalse(nc.hasTransport(i));
1001             }
1002         }
1003         for (int i = getMaxTransport(); i > maxTransportType; i--) {
1004             if (positiveSequence) {
1005                 assertFalse(nc.hasTransport(i));
1006             } else {
1007                 assertTrue(nc.hasTransport(i));
1008             }
1009         }
1010     }
1011 
1012     @Test
testMultipleTransportTypes()1013     public void testMultipleTransportTypes() {
1014         final NetworkCapabilities nc = new NetworkCapabilities();
1015         assertNoTransport(nc);
1016         // Test adding multiple transport types.
1017         for (int i = MIN_TRANSPORT; i <= getMaxTransport(); i++) {
1018             nc.addTransportType(i);
1019             checkCurrentTransportTypes(nc, i, true /* positiveSequence */);
1020         }
1021         // Test removing multiple transport types.
1022         for (int i = MIN_TRANSPORT; i <= getMaxTransport(); i++) {
1023             nc.removeTransportType(i);
1024             checkCurrentTransportTypes(nc, i, false /* positiveSequence */);
1025         }
1026         assertNoTransport(nc);
1027         nc.addTransportType(TRANSPORT_WIFI);
1028         assertTrue(nc.hasTransport(TRANSPORT_WIFI));
1029         assertFalse(nc.hasTransport(TRANSPORT_VPN));
1030         nc.addTransportType(TRANSPORT_VPN);
1031         assertTrue(nc.hasTransport(TRANSPORT_WIFI));
1032         assertTrue(nc.hasTransport(TRANSPORT_VPN));
1033         nc.removeTransportType(TRANSPORT_WIFI);
1034         assertFalse(nc.hasTransport(TRANSPORT_WIFI));
1035         assertTrue(nc.hasTransport(TRANSPORT_VPN));
1036         nc.removeTransportType(TRANSPORT_VPN);
1037         assertFalse(nc.hasTransport(TRANSPORT_WIFI));
1038         assertFalse(nc.hasTransport(TRANSPORT_VPN));
1039         assertNoTransport(nc);
1040     }
1041 
1042     @Test
testAddAndRemoveTransportType()1043     public void testAddAndRemoveTransportType() {
1044         final NetworkCapabilities nc = new NetworkCapabilities();
1045         try {
1046             nc.addTransportType(-1);
1047             fail("Should not set invalid transport type into addTransportType");
1048         } catch (IllegalArgumentException expected) { }
1049         try {
1050             nc.removeTransportType(-1);
1051             fail("Should not set invalid transport type into removeTransportType");
1052         } catch (IllegalArgumentException e) { }
1053     }
1054 
1055     /**
1056      * Test TransportInfo to verify redaction mechanism.
1057      */
1058     private static class TestTransportInfo implements TransportInfo {
1059         public final boolean locationRedacted;
1060         public final boolean localMacAddressRedacted;
1061         public final boolean settingsRedacted;
1062 
TestTransportInfo()1063         TestTransportInfo() {
1064             locationRedacted = false;
1065             localMacAddressRedacted = false;
1066             settingsRedacted = false;
1067         }
1068 
TestTransportInfo(boolean locationRedacted, boolean localMacAddressRedacted, boolean settingsRedacted)1069         TestTransportInfo(boolean locationRedacted,
1070                 boolean localMacAddressRedacted,
1071                 boolean settingsRedacted) {
1072             this.locationRedacted = locationRedacted;
1073             this.localMacAddressRedacted =
1074                     localMacAddressRedacted;
1075             this.settingsRedacted = settingsRedacted;
1076         }
1077 
1078         @Override
makeCopy(@etworkCapabilities.RedactionType long redactions)1079         public TransportInfo makeCopy(@NetworkCapabilities.RedactionType long redactions) {
1080             return new TestTransportInfo(
1081                     (redactions & NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION) != 0,
1082                     (redactions & REDACT_FOR_LOCAL_MAC_ADDRESS) != 0,
1083                     (redactions & REDACT_FOR_NETWORK_SETTINGS) != 0
1084             );
1085         }
1086 
1087         @Override
getApplicableRedactions()1088         public @NetworkCapabilities.RedactionType long getApplicableRedactions() {
1089             return REDACT_FOR_ACCESS_FINE_LOCATION | REDACT_FOR_LOCAL_MAC_ADDRESS
1090                     | REDACT_FOR_NETWORK_SETTINGS;
1091         }
1092     }
1093 
1094     @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
testBuilder()1095     public void testBuilder() {
1096         final int ownerUid = 1001;
1097         final int signalStrength = -80;
1098         final int requestUid = 10100;
1099         final int[] administratorUids = {ownerUid, 10001};
1100         final TelephonyNetworkSpecifier specifier = new TelephonyNetworkSpecifier(1);
1101         final TransportInfo transportInfo = new TransportInfo() {};
1102         final String ssid = "TEST_SSID";
1103         final String packageName = "com.google.test.networkcapabilities";
1104         final NetworkCapabilities nc = new NetworkCapabilities.Builder()
1105                 .addTransportType(TRANSPORT_WIFI)
1106                 .addTransportType(TRANSPORT_CELLULAR)
1107                 .removeTransportType(TRANSPORT_CELLULAR)
1108                 .addCapability(NET_CAPABILITY_EIMS)
1109                 .addCapability(NET_CAPABILITY_CBS)
1110                 .removeCapability(NET_CAPABILITY_CBS)
1111                 .setAdministratorUids(administratorUids)
1112                 .setOwnerUid(ownerUid)
1113                 .setLinkDownstreamBandwidthKbps(512)
1114                 .setLinkUpstreamBandwidthKbps(128)
1115                 .setNetworkSpecifier(specifier)
1116                 .setTransportInfo(transportInfo)
1117                 .setSignalStrength(signalStrength)
1118                 .setSsid(ssid)
1119                 .setRequestorUid(requestUid)
1120                 .setRequestorPackageName(packageName)
1121                 .build();
1122         assertEquals(1, nc.getTransportTypes().length);
1123         assertEquals(TRANSPORT_WIFI, nc.getTransportTypes()[0]);
1124         assertTrue(nc.hasCapability(NET_CAPABILITY_EIMS));
1125         assertFalse(nc.hasCapability(NET_CAPABILITY_CBS));
1126         assertTrue(Arrays.equals(administratorUids, nc.getAdministratorUids()));
1127         assertEquals(ownerUid, nc.getOwnerUid());
1128         assertEquals(512, nc.getLinkDownstreamBandwidthKbps());
1129         assertNotEquals(128, nc.getLinkDownstreamBandwidthKbps());
1130         assertEquals(128, nc.getLinkUpstreamBandwidthKbps());
1131         assertNotEquals(512, nc.getLinkUpstreamBandwidthKbps());
1132         assertEquals(specifier, nc.getNetworkSpecifier());
1133         assertEquals(transportInfo, nc.getTransportInfo());
1134         assertEquals(signalStrength, nc.getSignalStrength());
1135         assertNotEquals(-50, nc.getSignalStrength());
1136         assertEquals(ssid, nc.getSsid());
1137         assertEquals(requestUid, nc.getRequestorUid());
1138         assertEquals(packageName, nc.getRequestorPackageName());
1139         // Cannot assign null into NetworkCapabilities.Builder
1140         try {
1141             final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder(null);
1142             fail("Should not set null into NetworkCapabilities.Builder");
1143         } catch (NullPointerException expected) { }
1144         assertEquals(nc, new NetworkCapabilities.Builder(nc).build());
1145 
1146         if (isAtLeastS()) {
1147             final NetworkCapabilities nc2 = new NetworkCapabilities.Builder()
1148                     .setSubscriptionIds(Set.of(TEST_SUBID1)).build();
1149             assertEquals(Set.of(TEST_SUBID1), nc2.getSubscriptionIds());
1150         }
1151     }
1152 
1153     @Test @IgnoreUpTo(Build.VERSION_CODES.R)
testBuilderWithoutDefaultCap()1154     public void testBuilderWithoutDefaultCap() {
1155         final NetworkCapabilities nc =
1156                 NetworkCapabilities.Builder.withoutDefaultCapabilities().build();
1157         assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
1158         assertFalse(nc.hasCapability(NET_CAPABILITY_TRUSTED));
1159         assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_VPN));
1160         // Ensure test case fails if new net cap is added into default cap but no update here.
1161         assertEquals(0, nc.getCapabilities().length);
1162     }
1163 }
1164