• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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.wifi;
18 
19 import static org.junit.Assert.assertArrayEquals;
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertFalse;
22 import static org.junit.Assert.assertNotEquals;
23 import static org.junit.Assert.assertNotNull;
24 import static org.junit.Assert.assertNotSame;
25 import static org.junit.Assert.assertNull;
26 import static org.junit.Assert.assertThrows;
27 import static org.junit.Assert.assertTrue;
28 import static org.junit.Assert.fail;
29 import static org.junit.Assume.assumeTrue;
30 
31 import android.net.MacAddress;
32 import android.net.NetworkCapabilities;
33 import android.net.wifi.util.HexEncoding;
34 import android.os.Parcel;
35 import android.telephony.SubscriptionManager;
36 
37 import androidx.test.filters.SmallTest;
38 
39 import com.android.modules.utils.build.SdkLevel;
40 
41 import org.junit.Test;
42 
43 import java.nio.charset.Charset;
44 import java.nio.charset.StandardCharsets;
45 import java.util.ArrayList;
46 import java.util.List;
47 
48 /**
49  * Unit tests for {@link android.net.wifi.WifiInfo}.
50  */
51 @SmallTest
52 public class WifiInfoTest {
53     private static final long TEST_TX_SUCCESS = 1;
54     private static final long TEST_TX_RETRIES = 2;
55     private static final long TEST_TX_BAD = 3;
56     private static final long TEST_RX_SUCCESS = 4;
57     private static final String TEST_PACKAGE_NAME = "com.test.example";
58     private static final String TEST_FQDN = "test.com";
59     private static final String TEST_PROVIDER_NAME = "test";
60     private static final int TEST_WIFI_STANDARD = ScanResult.WIFI_STANDARD_11AC;
61     private static final int TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS = 866;
62     private static final int TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS = 1200;
63     private static final String TEST_SSID = "Test123";
64     private static final String TEST_BSSID = "12:12:12:12:12:12";
65     private static final int TEST_RSSI = -60;
66     private static final int TEST_NETWORK_ID = 5;
67     private static final int TEST_NETWORK_ID2 = 6;
68     private static final int TEST_SUB_ID = 1;
69     private static final String TEST_NETWORK_KEY = "TestNetworkKey";
70     private static final String AP_MLD_MAC_ADDRESS = "22:33:44:55:66:77";
71     private static final String MLO_LINK_STA_MAC_ADDRESS = "12:34:56:78:9a:bc";
72     private static final String MLO_LINK_AP_MAC_ADDRESS = "bc:9a:78:56:34:12";
73     private static final int TEST_MLO_LINK_ID = 3;
74     private static final int TEST_CHANNEL = 36;
75     private static final int TEST_LINK_SPEED = 300;
76 
addMloInfo(WifiInfo info)77     private void addMloInfo(WifiInfo info) {
78         info.setApMldMacAddress(MacAddress.fromString(AP_MLD_MAC_ADDRESS));
79         info.enableApTidToLinkMappingNegotiationSupport(true);
80         List<MloLink> links = new ArrayList<>();
81         MloLink link = new MloLink();
82         link.setStaMacAddress(MacAddress.fromString(MLO_LINK_STA_MAC_ADDRESS));
83         link.setApMacAddress(MacAddress.fromString(MLO_LINK_AP_MAC_ADDRESS));
84         links.add(link);
85         info.setAffiliatedMloLinks(links);
86         link.setRssi(TEST_RSSI);
87         link.setLinkId(TEST_MLO_LINK_ID);
88         link.setBand(WifiScanner.WIFI_BAND_5_GHZ);
89         link.setChannel(TEST_CHANNEL);
90         link.setRxLinkSpeedMbps(TEST_LINK_SPEED);
91         link.setTxLinkSpeedMbps(TEST_LINK_SPEED);
92         link.setState(MloLink.MLO_LINK_STATE_UNASSOCIATED);
93     }
94 
assertMloNoRedaction(WifiInfo info)95     private void assertMloNoRedaction(WifiInfo info) {
96         assertTrue(info.isApTidToLinkMappingNegotiationSupported());
97         assertNotNull(info.getApMldMacAddress());
98         assertEquals(AP_MLD_MAC_ADDRESS, info.getApMldMacAddress().toString());
99         List<MloLink> links = info.getAffiliatedMloLinks();
100         assertEquals(1, links.size());
101         for (MloLink link : links) {
102             assertNotNull(link.getApMacAddress());
103             assertEquals(MLO_LINK_AP_MAC_ADDRESS, link.getApMacAddress().toString());
104             assertNotNull(link.getStaMacAddress());
105             assertEquals(MLO_LINK_STA_MAC_ADDRESS, link.getStaMacAddress().toString());
106             assertEquals(TEST_RSSI, link.getRssi());
107             assertEquals(TEST_CHANNEL, link.getChannel());
108             assertEquals(TEST_LINK_SPEED, link.getRxLinkSpeedMbps());
109             assertEquals(TEST_LINK_SPEED, link.getTxLinkSpeedMbps());
110             assertEquals(TEST_MLO_LINK_ID, link.getLinkId());
111             assertEquals(WifiScanner.WIFI_BAND_5_GHZ, link.getBand());
112             assertEquals(MloLink.MLO_LINK_STATE_UNASSOCIATED, link.getState());
113         }
114     }
115 
assertMloLocalMacRedaction(WifiInfo info)116     private void assertMloLocalMacRedaction(WifiInfo info) {
117         assertNotNull(info.getApMldMacAddress());
118         assertEquals(AP_MLD_MAC_ADDRESS, info.getApMldMacAddress().toString());
119         List<MloLink> links = info.getAffiliatedMloLinks();
120         assertEquals(1, links.size());
121         for (MloLink link : links) {
122             assertNotNull(link.getApMacAddress());
123             assertEquals(MLO_LINK_AP_MAC_ADDRESS, link.getApMacAddress().toString());
124             assertNull(link.getStaMacAddress());
125         }
126     }
127 
assertMloSensitiveLocationRedaction(WifiInfo info)128     private void assertMloSensitiveLocationRedaction(WifiInfo info) {
129         assertNull(info.getApMldMacAddress());
130         List<MloLink> links = info.getAffiliatedMloLinks();
131         assertEquals(1, links.size());
132         for (MloLink link : links) {
133             assertNull(link.getApMacAddress());
134             assertNotNull(link.getStaMacAddress());
135             assertEquals(MLO_LINK_STA_MAC_ADDRESS, link.getStaMacAddress().toString());
136         }
137     }
138 
makeWifiInfoForRedactionTest( List<ScanResult.InformationElement> informationElements)139     private WifiInfo makeWifiInfoForRedactionTest(
140             List<ScanResult.InformationElement> informationElements) {
141         WifiInfo info = new WifiInfo();
142         info.txSuccess = TEST_TX_SUCCESS;
143         info.txRetries = TEST_TX_RETRIES;
144         info.txBad = TEST_TX_BAD;
145         info.rxSuccess = TEST_RX_SUCCESS;
146         info.setSSID(WifiSsid.fromUtf8Text(TEST_SSID));
147         info.setBSSID(TEST_BSSID);
148         info.setNetworkId(TEST_NETWORK_ID);
149         info.setTrusted(true);
150         info.setOemPaid(true);
151         info.setOemPrivate(true);
152         info.setCarrierMerged(true);
153         info.setOsuAp(true);
154         info.setFQDN(TEST_FQDN);
155         info.setProviderFriendlyName(TEST_PROVIDER_NAME);
156         info.setRequestingPackageName(TEST_PACKAGE_NAME);
157         info.setWifiStandard(TEST_WIFI_STANDARD);
158         info.setMaxSupportedTxLinkSpeedMbps(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS);
159         info.setMaxSupportedRxLinkSpeedMbps(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS);
160         info.setSubscriptionId(TEST_SUB_ID);
161         info.setInformationElements(informationElements);
162         info.setIsPrimary(true);
163         info.setMacAddress(TEST_BSSID);
164         if (SdkLevel.isAtLeastT()) {
165             addMloInfo(info);
166         }
167 
168         return info;
169     }
170 
assertNoRedaction(WifiInfo info, List<ScanResult.InformationElement> informationElements)171     private void assertNoRedaction(WifiInfo info,
172             List<ScanResult.InformationElement> informationElements) {
173         assertEquals(TEST_TX_SUCCESS, info.txSuccess);
174         assertEquals(TEST_TX_RETRIES, info.txRetries);
175         assertEquals(TEST_TX_BAD, info.txBad);
176         assertEquals(TEST_RX_SUCCESS, info.rxSuccess);
177         assertEquals("\"" + TEST_SSID + "\"", info.getSSID());
178         assertEquals(TEST_BSSID, info.getBSSID());
179         assertEquals(TEST_NETWORK_ID, info.getNetworkId());
180         assertTrue(info.isTrusted());
181         assertFalse((info.isRestricted()));
182         assertTrue(info.isOsuAp());
183         assertTrue(info.isPasspointAp());
184         assertEquals(TEST_PACKAGE_NAME, info.getRequestingPackageName());
185         assertEquals(TEST_FQDN, info.getPasspointFqdn());
186         assertEquals(TEST_PROVIDER_NAME, info.getPasspointProviderFriendlyName());
187         assertEquals(TEST_WIFI_STANDARD, info.getWifiStandard());
188         assertEquals(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS, info.getMaxSupportedTxLinkSpeedMbps());
189         assertEquals(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS, info.getMaxSupportedRxLinkSpeedMbps());
190         assertEquals(TEST_BSSID, info.getMacAddress());
191         assertEquals(2, info.getInformationElements().size());
192         assertEquals(informationElements.get(0).id,
193                 info.getInformationElements().get(0).id);
194         assertEquals(informationElements.get(0).idExt,
195                 info.getInformationElements().get(0).idExt);
196         assertArrayEquals(informationElements.get(0).bytes,
197                 info.getInformationElements().get(0).bytes);
198         assertEquals(informationElements.get(1).id,
199                 info.getInformationElements().get(1).id);
200         assertEquals(informationElements.get(1).idExt,
201                 info.getInformationElements().get(1).idExt);
202         assertArrayEquals(informationElements.get(1).bytes,
203                 info.getInformationElements().get(1).bytes);
204         if (SdkLevel.isAtLeastS()) {
205             assertTrue(info.isOemPaid());
206             assertTrue(info.isOemPrivate());
207             assertTrue(info.isCarrierMerged());
208             assertEquals(TEST_SUB_ID, info.getSubscriptionId());
209             assertTrue(info.isPrimary());
210         }
211         if (SdkLevel.isAtLeastT()) {
212             assertMloNoRedaction(info);
213         }
214     }
215 
216     /**
217      *  Verify redaction of WifiInfo with REDACT_NONE.
218      */
219     @Test
testWifiInfoRedactNoRedactions()220     public void testWifiInfoRedactNoRedactions() throws Exception {
221         List<ScanResult.InformationElement> informationElements = generateIes();
222         WifiInfo writeWifiInfo = makeWifiInfoForRedactionTest(informationElements);
223 
224         // Make a copy which allows parcelling of location sensitive data.
225         WifiInfo redactedWifiInfo = writeWifiInfo.makeCopy(NetworkCapabilities.REDACT_NONE);
226 
227         Parcel parcel = Parcel.obtain();
228         redactedWifiInfo.writeToParcel(parcel, 0);
229         // Rewind the pointer to the head of the parcel.
230         parcel.setDataPosition(0);
231         WifiInfo readWifiInfo = WifiInfo.CREATOR.createFromParcel(parcel);
232 
233         // Verify that redaction did not affect the original WifiInfo
234         assertNoRedaction(writeWifiInfo, informationElements);
235 
236         assertNoRedaction(redactedWifiInfo, informationElements);
237         assertNoRedaction(readWifiInfo, informationElements);
238 
239         if (SdkLevel.isAtLeastS()) {
240             // equals() was only introduced in S.
241             assertEquals(readWifiInfo, redactedWifiInfo);
242         }
243     }
244 
assertLocationSensitiveRedaction(WifiInfo info)245     private void assertLocationSensitiveRedaction(WifiInfo info) {
246         assertNotNull(info);
247         assertEquals(TEST_TX_SUCCESS, info.txSuccess);
248         assertEquals(TEST_TX_RETRIES, info.txRetries);
249         assertEquals(TEST_TX_BAD, info.txBad);
250         assertEquals(TEST_RX_SUCCESS, info.rxSuccess);
251         assertEquals(WifiManager.UNKNOWN_SSID, info.getSSID());
252         assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS, info.getBSSID());
253         assertEquals(WifiConfiguration.INVALID_NETWORK_ID, info.getNetworkId());
254         assertTrue(info.isTrusted());
255         assertFalse(info.isRestricted());
256         assertTrue(info.isOsuAp());
257         assertFalse(info.isPasspointAp()); // fqdn & friendly name is masked.
258         assertEquals(TEST_PACKAGE_NAME, info.getRequestingPackageName());
259         assertNull(info.getPasspointFqdn());
260         assertNull(info.getPasspointProviderFriendlyName());
261         assertEquals(TEST_WIFI_STANDARD, info.getWifiStandard());
262         assertEquals(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS, info.getMaxSupportedTxLinkSpeedMbps());
263         assertEquals(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS, info.getMaxSupportedRxLinkSpeedMbps());
264         assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS, info.getMacAddress());
265         assertNull(info.getInformationElements());
266         if (SdkLevel.isAtLeastS()) {
267             assertTrue(info.isOemPaid());
268             assertTrue(info.isOemPrivate());
269             assertTrue(info.isCarrierMerged());
270             assertEquals(TEST_SUB_ID, info.getSubscriptionId());
271             assertTrue(info.isPrimary());
272         }
273         assertEquals(null, info.getNetworkKey());
274         if (SdkLevel.isAtLeastT()) {
275             assertMloSensitiveLocationRedaction(info);
276         }
277     }
278 
279     /**
280      *  Verify redaction of WifiInfo with REDACT_FOR_ACCESS_FINE_LOCATION.
281      */
282     @Test
testWifiInfoRedactLocationSensitiveInfo()283     public void testWifiInfoRedactLocationSensitiveInfo() throws Exception {
284         List<ScanResult.InformationElement> informationElements = generateIes();
285         WifiInfo writeWifiInfo = makeWifiInfoForRedactionTest(informationElements);
286 
287         WifiInfo redactedWifiInfo =
288                 writeWifiInfo.makeCopy(NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION);
289 
290         Parcel parcel = Parcel.obtain();
291         redactedWifiInfo.writeToParcel(parcel, 0);
292         // Rewind the pointer to the head of the parcel.
293         parcel.setDataPosition(0);
294         WifiInfo readWifiInfo = WifiInfo.CREATOR.createFromParcel(parcel);
295 
296         // Verify that redaction did not affect the original WifiInfo
297         assertNoRedaction(writeWifiInfo, informationElements);
298 
299         assertLocationSensitiveRedaction(redactedWifiInfo);
300         assertLocationSensitiveRedaction(readWifiInfo);
301 
302         if (SdkLevel.isAtLeastS()) {
303             // equals() was only introduced in S.
304             assertEquals(redactedWifiInfo, readWifiInfo);
305         }
306     }
307 
assertLocalMacAddressInfoRedaction(WifiInfo info)308     private void assertLocalMacAddressInfoRedaction(WifiInfo info) {
309         assertNotNull(info);
310         assertEquals(TEST_TX_SUCCESS, info.txSuccess);
311         assertEquals(TEST_TX_RETRIES, info.txRetries);
312         assertEquals(TEST_TX_BAD, info.txBad);
313         assertEquals(TEST_RX_SUCCESS, info.rxSuccess);
314         assertEquals("\"" + TEST_SSID + "\"", info.getSSID());
315         assertEquals(TEST_BSSID, info.getBSSID());
316         assertEquals(TEST_NETWORK_ID, info.getNetworkId());
317         assertTrue(info.isTrusted());
318         assertFalse(info.isRestricted());
319         assertTrue(info.isOsuAp());
320         assertTrue(info.isPasspointAp());
321         assertEquals(TEST_PACKAGE_NAME, info.getRequestingPackageName());
322 
323         assertEquals(TEST_FQDN, info.getPasspointFqdn());
324         assertEquals(TEST_PROVIDER_NAME, info.getPasspointProviderFriendlyName());
325         assertEquals(TEST_WIFI_STANDARD, info.getWifiStandard());
326         assertEquals(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS, info.getMaxSupportedTxLinkSpeedMbps());
327         assertEquals(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS, info.getMaxSupportedRxLinkSpeedMbps());
328         assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS, info.getMacAddress());
329         if (SdkLevel.isAtLeastS()) {
330             assertTrue(info.isOemPaid());
331             assertTrue(info.isOemPrivate());
332             assertTrue(info.isCarrierMerged());
333             assertEquals(TEST_SUB_ID, info.getSubscriptionId());
334             assertTrue(info.isPrimary());
335         }
336         assertEquals(null, info.getNetworkKey());
337         if (SdkLevel.isAtLeastT()) {
338             assertMloLocalMacRedaction(info);
339         }
340     }
341 
342     /**
343      *  Verify redaction of WifiInfo with REDACT_FOR_LOCAL_MAC_ADDRESS.
344      */
345     @Test
testWifiInfoRedactLocalMacAddressInfo()346     public void testWifiInfoRedactLocalMacAddressInfo() throws Exception {
347         List<ScanResult.InformationElement> informationElements = generateIes();
348         WifiInfo writeWifiInfo = makeWifiInfoForRedactionTest(informationElements);
349 
350         WifiInfo redactedWifiInfo =
351                 writeWifiInfo.makeCopy(NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS);
352 
353         Parcel parcel = Parcel.obtain();
354         redactedWifiInfo.writeToParcel(parcel, 0);
355         // Rewind the pointer to the head of the parcel.
356         parcel.setDataPosition(0);
357         WifiInfo readWifiInfo = WifiInfo.CREATOR.createFromParcel(parcel);
358 
359         // Verify that redaction did not affect the original WifiInfo
360         assertNoRedaction(writeWifiInfo, informationElements);
361 
362         assertLocalMacAddressInfoRedaction(redactedWifiInfo);
363         assertLocalMacAddressInfoRedaction(readWifiInfo);
364         if (SdkLevel.isAtLeastS()) {
365             // equals() was only introduced in S.
366             assertEquals(redactedWifiInfo, readWifiInfo);
367         }
368     }
369 
assertIsPrimaryThrowsSecurityException(WifiInfo info)370     private void assertIsPrimaryThrowsSecurityException(WifiInfo info) {
371         try {
372             // Should generate a security exception if caller does not have network settings
373             // permission.
374             info.isPrimary();
375             fail();
376         } catch (SecurityException e) { /* pass */ }
377     }
378 
379     /**
380      *  Verify redaction of WifiInfo with REDACT_FOR_NETWORK_SETTINGS.
381      */
382     @Test
testWifiInfoRedactNetworkSettingsInfo()383     public void testWifiInfoRedactNetworkSettingsInfo() throws Exception {
384         assumeTrue(SdkLevel.isAtLeastS());
385 
386         WifiInfo writeWifiInfo = new WifiInfo();
387         writeWifiInfo.setIsPrimary(true);
388         writeWifiInfo.setRequestingPackageName(TEST_PACKAGE_NAME);
389         writeWifiInfo.setIsPrimary(true);
390         assertTrue(writeWifiInfo.isPrimary());
391 
392         WifiInfo redactedWifiInfo =
393                 writeWifiInfo.makeCopy(NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS);
394         assertNull(redactedWifiInfo.getRequestingPackageName());
395         assertThrows(SecurityException.class, () -> redactedWifiInfo.isPrimary());
396 
397         Parcel parcel = Parcel.obtain();
398         redactedWifiInfo.writeToParcel(parcel, 0);
399         // Rewind the pointer to the head of the parcel.
400         parcel.setDataPosition(0);
401         WifiInfo readWifiInfo = WifiInfo.CREATOR.createFromParcel(parcel);
402 
403         assertNotNull(redactedWifiInfo);
404         assertIsPrimaryThrowsSecurityException(redactedWifiInfo);
405         assertNotNull(readWifiInfo);
406         assertIsPrimaryThrowsSecurityException(readWifiInfo);
407 
408         if (SdkLevel.isAtLeastS()) {
409             // equals() was only introduced in S.
410             assertEquals(redactedWifiInfo, readWifiInfo);
411         }
412     }
413 
414     @Test
testWifiInfoGetApplicableRedactions()415     public void testWifiInfoGetApplicableRedactions() throws Exception {
416         long redactions = new WifiInfo().getApplicableRedactions();
417         assertEquals(NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION
418                 | NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS
419                 | NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS, redactions);
420     }
421 
assertLocationSensitiveAndLocalMacAddressRedaction(WifiInfo info)422     private void assertLocationSensitiveAndLocalMacAddressRedaction(WifiInfo info) {
423         assertNotNull(info);
424         assertEquals(WifiManager.UNKNOWN_SSID, info.getSSID());
425         assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS, info.getBSSID());
426         assertEquals(WifiConfiguration.INVALID_NETWORK_ID, info.getNetworkId());
427         assertNull(info.getPasspointFqdn());
428         assertNull(info.getPasspointProviderFriendlyName());
429         assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS, info.getMacAddress());
430         assertNull(info.getInformationElements());
431         assertNull(info.getNetworkKey());
432     }
433 
434     @Test
testWifiInfoRedactLocationAndLocalMacAddressSensitiveInfo()435     public void testWifiInfoRedactLocationAndLocalMacAddressSensitiveInfo()
436             throws Exception {
437         assumeTrue(SdkLevel.isAtLeastS());
438         List<ScanResult.InformationElement> informationElements = generateIes();
439         WifiInfo writeWifiInfo = makeWifiInfoForRedactionTest(informationElements);
440 
441         WifiInfo redactedWifiInfo =
442                 writeWifiInfo.makeCopy(NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION
443                         | NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS);
444 
445         Parcel parcel = Parcel.obtain();
446         redactedWifiInfo.writeToParcel(parcel, 0);
447         // Rewind the pointer to the head of the parcel.
448         parcel.setDataPosition(0);
449         WifiInfo readWifiInfo = WifiInfo.CREATOR.createFromParcel(parcel);
450 
451         assertLocationSensitiveAndLocalMacAddressRedaction(redactedWifiInfo);
452         assertLocationSensitiveAndLocalMacAddressRedaction(readWifiInfo);
453 
454         if (SdkLevel.isAtLeastS()) {
455             // equals() was only introduced in S.
456             assertEquals(redactedWifiInfo, readWifiInfo);
457         }
458     }
459 
460     /**
461      *  Verify parcel write/read with null information elements.
462      */
463     @Test
testWifiInfoParcelWriteReadWithNullInfoElements()464     public void testWifiInfoParcelWriteReadWithNullInfoElements() throws Exception {
465         assumeTrue(SdkLevel.isAtLeastS());
466 
467         WifiInfo writeWifiInfo = new WifiInfo();
468         writeWifiInfo.setInformationElements(null);
469 
470         // Make a copy which allows parcelling of location sensitive data.
471         WifiInfo writeWifiInfoCopy = writeWifiInfo.makeCopy(NetworkCapabilities.REDACT_NONE);
472 
473         Parcel parcel = Parcel.obtain();
474         writeWifiInfoCopy.writeToParcel(parcel, 0);
475         // Rewind the pointer to the head of the parcel.
476         parcel.setDataPosition(0);
477         WifiInfo readWifiInfo = WifiInfo.CREATOR.createFromParcel(parcel);
478         assertNull(readWifiInfo.getInformationElements());
479     }
480 
481     /**
482      *  Verify parcel write/read with empty information elements.
483      */
484     @Test
testWifiInfoParcelWriteReadWithEmptyInfoElements()485     public void testWifiInfoParcelWriteReadWithEmptyInfoElements() throws Exception {
486         assumeTrue(SdkLevel.isAtLeastS());
487 
488         WifiInfo writeWifiInfo = new WifiInfo();
489         writeWifiInfo.setInformationElements(new ArrayList<>());
490 
491         // Make a copy which allows parcelling of location sensitive data.
492         WifiInfo writeWifiInfoCopy = writeWifiInfo.makeCopy(NetworkCapabilities.REDACT_NONE);
493 
494         Parcel parcel = Parcel.obtain();
495         writeWifiInfoCopy.writeToParcel(parcel, 0);
496         // Rewind the pointer to the head of the parcel.
497         parcel.setDataPosition(0);
498         WifiInfo readWifiInfo = WifiInfo.CREATOR.createFromParcel(parcel);
499         assertTrue(readWifiInfo.getInformationElements().isEmpty());
500     }
501 
502     @Test
testWifiInfoCopyConstructor()503     public void testWifiInfoCopyConstructor() throws Exception {
504         WifiInfo writeWifiInfo = new WifiInfo();
505         writeWifiInfo.txSuccess = TEST_TX_SUCCESS;
506         writeWifiInfo.txRetries = TEST_TX_RETRIES;
507         writeWifiInfo.txBad = TEST_TX_BAD;
508         writeWifiInfo.rxSuccess = TEST_RX_SUCCESS;
509         writeWifiInfo.setTrusted(true);
510         writeWifiInfo.setOemPaid(true);
511         writeWifiInfo.setOemPrivate(true);
512         writeWifiInfo.setCarrierMerged(true);
513         writeWifiInfo.setOsuAp(true);
514         writeWifiInfo.setFQDN(TEST_FQDN);
515         writeWifiInfo.setProviderFriendlyName(TEST_PROVIDER_NAME);
516         writeWifiInfo.setRequestingPackageName(TEST_PACKAGE_NAME);
517         writeWifiInfo.setWifiStandard(TEST_WIFI_STANDARD);
518         writeWifiInfo.setMaxSupportedTxLinkSpeedMbps(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS);
519         writeWifiInfo.setMaxSupportedRxLinkSpeedMbps(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS);
520         writeWifiInfo.setSubscriptionId(TEST_SUB_ID);
521         writeWifiInfo.setIsPrimary(true);
522         writeWifiInfo.setRestricted(true);
523         writeWifiInfo.enableApTidToLinkMappingNegotiationSupport(true);
524 
525         WifiInfo readWifiInfo = new WifiInfo(writeWifiInfo);
526 
527         assertEquals(TEST_TX_SUCCESS, readWifiInfo.txSuccess);
528         assertEquals(TEST_TX_RETRIES, readWifiInfo.txRetries);
529         assertEquals(TEST_TX_BAD, readWifiInfo.txBad);
530         assertEquals(TEST_RX_SUCCESS, readWifiInfo.rxSuccess);
531         assertTrue(readWifiInfo.isTrusted());
532         assertTrue(readWifiInfo.isOsuAp());
533         assertTrue(readWifiInfo.isPasspointAp());
534         assertEquals(TEST_PACKAGE_NAME, readWifiInfo.getRequestingPackageName());
535         assertEquals(TEST_FQDN, readWifiInfo.getPasspointFqdn());
536         assertEquals(TEST_PROVIDER_NAME, readWifiInfo.getPasspointProviderFriendlyName());
537         assertEquals(TEST_WIFI_STANDARD, readWifiInfo.getWifiStandard());
538         assertEquals(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS,
539                 readWifiInfo.getMaxSupportedTxLinkSpeedMbps());
540         assertEquals(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS,
541                 readWifiInfo.getMaxSupportedRxLinkSpeedMbps());
542         assertTrue(readWifiInfo.isRestricted());
543         if (SdkLevel.isAtLeastS()) {
544             assertTrue(readWifiInfo.isOemPaid());
545             assertTrue(readWifiInfo.isOemPrivate());
546             assertTrue(readWifiInfo.isCarrierMerged());
547             assertEquals(TEST_SUB_ID, readWifiInfo.getSubscriptionId());
548             assertTrue(readWifiInfo.isPrimary());
549         }
550         assertTrue(readWifiInfo.isApTidToLinkMappingNegotiationSupported());
551     }
552 
553     /**
554      *  Verify values after reset()
555      */
556     @Test
testWifiInfoResetValue()557     public void testWifiInfoResetValue() throws Exception {
558         WifiInfo wifiInfo = new WifiInfo();
559         wifiInfo.reset();
560         assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getMaxSupportedTxLinkSpeedMbps());
561         assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getMaxSupportedRxLinkSpeedMbps());
562         assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getTxLinkSpeedMbps());
563         assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getRxLinkSpeedMbps());
564         assertEquals(WifiInfo.INVALID_RSSI, wifiInfo.getRssi());
565         assertEquals(WifiManager.UNKNOWN_SSID, wifiInfo.getSSID());
566         assertNull(wifiInfo.getBSSID());
567         assertEquals(-1, wifiInfo.getNetworkId());
568         if (SdkLevel.isAtLeastS()) {
569             assertFalse(wifiInfo.isOemPaid());
570             assertFalse(wifiInfo.isOemPrivate());
571             assertFalse(wifiInfo.isCarrierMerged());
572             assertEquals(SubscriptionManager.INVALID_SUBSCRIPTION_ID, wifiInfo.getSubscriptionId());
573             assertFalse(wifiInfo.isPrimary());
574         }
575         assertNull(wifiInfo.getNetworkKey());
576         assertEquals(MloLink.INVALID_MLO_LINK_ID, wifiInfo.getApMloLinkId());
577         assertNull(wifiInfo.getApMldMacAddress());
578         assertEquals(0, wifiInfo.getAffiliatedMloLinks().size());
579         assertFalse(wifiInfo.isApTidToLinkMappingNegotiationSupported());
580     }
581 
582     /**
583      * Test that the WifiInfo Builder returns the same values that was set, and that
584      * calling build multiple times returns different instances.
585      */
586     @Test
testWifiInfoBuilder()587     public void testWifiInfoBuilder() throws Exception {
588         WifiInfo.Builder builder = new WifiInfo.Builder()
589                 .setSsid(TEST_SSID.getBytes(StandardCharsets.UTF_8))
590                 .setBssid(TEST_BSSID)
591                 .setRssi(TEST_RSSI)
592                 .setNetworkId(TEST_NETWORK_ID);
593 
594         WifiInfo info1 = builder.build();
595 
596         assertEquals("\"" + TEST_SSID + "\"", info1.getSSID());
597         assertEquals(TEST_BSSID, info1.getBSSID());
598         assertEquals(TEST_RSSI, info1.getRssi());
599         assertEquals(TEST_NETWORK_ID, info1.getNetworkId());
600 
601         WifiInfo info2 = builder
602                 .setNetworkId(TEST_NETWORK_ID2)
603                 .build();
604 
605         // different instances
606         assertNotSame(info1, info2);
607 
608         // assert that info1 didn't change
609         assertEquals("\"" + TEST_SSID + "\"", info1.getSSID());
610         assertEquals(TEST_BSSID, info1.getBSSID());
611         assertEquals(TEST_RSSI, info1.getRssi());
612         assertEquals(TEST_NETWORK_ID, info1.getNetworkId());
613 
614         // assert that info2 changed
615         assertEquals("\"" + TEST_SSID + "\"", info2.getSSID());
616         assertEquals(TEST_BSSID, info2.getBSSID());
617         assertEquals(TEST_RSSI, info2.getRssi());
618         assertEquals(TEST_NETWORK_ID2, info2.getNetworkId());
619     }
620 
621     @Test
testSetSsid()622     public void testSetSsid() throws Exception {
623         WifiInfo.Builder builder = new WifiInfo.Builder();
624 
625         // Null
626         assertEquals(WifiManager.UNKNOWN_SSID, builder.build().getSSID());
627 
628         // Empty
629         builder.setSsid(new byte[0]);
630         assertEquals(WifiManager.UNKNOWN_SSID, builder.build().getSSID());
631 
632         // UTF-8
633         builder.setSsid(TEST_SSID.getBytes(StandardCharsets.UTF_8));
634         assertEquals("\"" + TEST_SSID + "\"", builder.build().getSSID());
635 
636         // Non-UTF-8
637         byte[] gbkBytes = "服務集識別碼".getBytes(Charset.forName("GBK"));
638         builder.setSsid(gbkBytes);
639         assertEquals(HexEncoding.encodeToString(gbkBytes, false), builder.build().getSSID());
640     }
641 
642     @Test
testWifiInfoEquals()643     public void testWifiInfoEquals() throws Exception {
644         WifiInfo.Builder builder = new WifiInfo.Builder()
645                 .setSsid(TEST_SSID.getBytes(StandardCharsets.UTF_8))
646                 .setBssid(TEST_BSSID)
647                 .setRssi(TEST_RSSI)
648                 .setNetworkId(TEST_NETWORK_ID);
649 
650         WifiInfo info1 = builder.build();
651         WifiInfo info2 = builder.build();
652         if (SdkLevel.isAtLeastS()) {
653             assertEquals(info1, info2);
654         } else {
655             // On R devices, reference equality.
656             assertNotEquals(info1, info2);
657         }
658 
659         info1.setSubscriptionId(TEST_SUB_ID);
660         assertNotEquals(info1, info2);
661 
662         info2.setSubscriptionId(TEST_SUB_ID);
663         if (SdkLevel.isAtLeastS()) {
664             assertEquals(info1, info2);
665         } else {
666             // On R devices, reference equality.
667             assertNotEquals(info1, info2);
668         }
669 
670         info1.setSSID(WifiSsid.fromBytes(null));
671         assertNotEquals(info1, info2);
672 
673         info2.setSSID(WifiSsid.fromBytes(null));
674         if (SdkLevel.isAtLeastS()) {
675             assertEquals(info1, info2);
676         } else {
677             // On R devices, reference equality.
678             assertNotEquals(info1, info2);
679         }
680     }
681 
682     @Test
testWifiInfoEqualsWithInfoElements()683     public void testWifiInfoEqualsWithInfoElements() throws Exception {
684         WifiInfo.Builder builder = new WifiInfo.Builder()
685                 .setSsid(TEST_SSID.getBytes(StandardCharsets.UTF_8))
686                 .setBssid(TEST_BSSID)
687                 .setRssi(TEST_RSSI)
688                 .setNetworkId(TEST_NETWORK_ID);
689 
690         WifiInfo info1 = builder.build();
691         WifiInfo info2 = builder.build();
692         if (SdkLevel.isAtLeastS()) {
693             assertEquals(info1, info2);
694         } else {
695             // On R devices, reference equality.
696             assertNotEquals(info1, info2);
697         }
698 
699         info1.setInformationElements(generateIes());
700         info2.setInformationElements(generateIes());
701 
702         if (SdkLevel.isAtLeastS()) {
703             assertEquals(info1, info2);
704         } else {
705             // On R devices, reference equality.
706             assertNotEquals(info1, info2);
707         }
708     }
709 
710     @Test
testWifiInfoHashcode()711     public void testWifiInfoHashcode() throws Exception {
712         WifiInfo.Builder builder = new WifiInfo.Builder()
713                 .setSsid(TEST_SSID.getBytes(StandardCharsets.UTF_8))
714                 .setBssid(TEST_BSSID)
715                 .setRssi(TEST_RSSI)
716                 .setNetworkId(TEST_NETWORK_ID);
717 
718         WifiInfo info1 = builder.build();
719         WifiInfo info2 = builder.build();
720         if (SdkLevel.isAtLeastS()) {
721             assertEquals(info1.hashCode(), info2.hashCode());
722         } else {
723             // On R devices, system generated hashcode.
724             assertNotEquals(info1.hashCode(), info2.hashCode());
725         }
726 
727         info1.setSubscriptionId(TEST_SUB_ID);
728         assertNotEquals(info1.hashCode(), info2.hashCode());
729 
730         info2.setSubscriptionId(TEST_SUB_ID);
731         if (SdkLevel.isAtLeastS()) {
732             assertEquals(info1.hashCode(), info2.hashCode());
733         } else {
734             // On R devices, system generated hashcode.
735             assertNotEquals(info1.hashCode(), info2.hashCode());
736         }
737 
738         info1.setSSID(WifiSsid.fromBytes(null));
739         assertNotEquals(info1.hashCode(), info2.hashCode());
740 
741         info2.setSSID(WifiSsid.fromBytes(null));
742         if (SdkLevel.isAtLeastS()) {
743             assertEquals(info1.hashCode(), info2.hashCode());
744         } else {
745             // On R devices, system generated hashcode.
746             assertNotEquals(info1.hashCode(), info2.hashCode());
747         }
748     }
749 
750     @Test
testWifiInfoCurrentSecurityType()751     public void testWifiInfoCurrentSecurityType() throws Exception {
752         WifiInfo.Builder builder = new WifiInfo.Builder()
753                 .setSsid(TEST_SSID.getBytes(StandardCharsets.UTF_8))
754                 .setBssid(TEST_BSSID)
755                 .setRssi(TEST_RSSI)
756                 .setNetworkId(TEST_NETWORK_ID)
757                 .setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_SAE);
758 
759         WifiInfo info = new WifiInfo();
760         assertEquals(WifiInfo.SECURITY_TYPE_UNKNOWN, info.getCurrentSecurityType());
761 
762         info = builder.build();
763         assertEquals(WifiInfo.SECURITY_TYPE_SAE, info.getCurrentSecurityType());
764 
765         info = builder.setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_OPEN).build();
766         assertEquals(WifiInfo.SECURITY_TYPE_OPEN, info.getCurrentSecurityType());
767 
768         info = builder.setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_WEP).build();
769         assertEquals(WifiInfo.SECURITY_TYPE_WEP, info.getCurrentSecurityType());
770 
771         info = builder.setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_PSK).build();
772         assertEquals(WifiInfo.SECURITY_TYPE_PSK, info.getCurrentSecurityType());
773 
774         info = builder.setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_EAP).build();
775         assertEquals(WifiInfo.SECURITY_TYPE_EAP, info.getCurrentSecurityType());
776 
777         info = builder.setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_OWE).build();
778         assertEquals(WifiInfo.SECURITY_TYPE_OWE, info.getCurrentSecurityType());
779 
780         info = builder.setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_WAPI_PSK).build();
781         assertEquals(WifiInfo.SECURITY_TYPE_WAPI_PSK, info.getCurrentSecurityType());
782 
783         info = builder.setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_WAPI_CERT).build();
784         assertEquals(WifiInfo.SECURITY_TYPE_WAPI_CERT, info.getCurrentSecurityType());
785 
786         info = builder.setCurrentSecurityType(
787                 WifiConfiguration.SECURITY_TYPE_EAP_WPA3_ENTERPRISE).build();
788         assertEquals(WifiInfo.SECURITY_TYPE_EAP_WPA3_ENTERPRISE, info.getCurrentSecurityType());
789 
790         info = builder.setCurrentSecurityType(
791                 WifiConfiguration.SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT).build();
792         assertEquals(WifiInfo.SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT,
793                 info.getCurrentSecurityType());
794 
795         info = builder.setCurrentSecurityType(
796                 WifiConfiguration.SECURITY_TYPE_PASSPOINT_R1_R2).build();
797         assertEquals(WifiInfo.SECURITY_TYPE_PASSPOINT_R1_R2, info.getCurrentSecurityType());
798 
799         info = builder.setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_PASSPOINT_R3).build();
800         assertEquals(WifiInfo.SECURITY_TYPE_PASSPOINT_R3, info.getCurrentSecurityType());
801 
802         info.clearCurrentSecurityType();
803         assertEquals(WifiInfo.SECURITY_TYPE_UNKNOWN, info.getCurrentSecurityType());
804     }
805 
generateIes()806     private static List<ScanResult.InformationElement> generateIes() {
807         List<ScanResult.InformationElement> informationElements = new ArrayList<>();
808         ScanResult.InformationElement informationElement = new ScanResult.InformationElement();
809         informationElement.id = ScanResult.InformationElement.EID_HT_OPERATION;
810         informationElement.idExt = 0;
811         informationElement.bytes = new byte[]{0x11, 0x22, 0x33};
812         informationElements.add(informationElement);
813 
814         informationElement = new ScanResult.InformationElement();
815         informationElement.id = ScanResult.InformationElement.EID_EXTENSION_PRESENT;
816         informationElement.idExt = ScanResult.InformationElement.EID_EXT_HE_OPERATION;
817         informationElement.bytes = new byte[]{0x44, 0x55, 0x66};
818         informationElements.add(informationElement);
819 
820         return informationElements;
821     }
822 
823     @Test
testMloLink()824     public void testMloLink() throws Exception {
825         // Create an MLO link and set parameters.
826         MloLink link1 = new MloLink();
827         link1.setStaMacAddress(MacAddress.fromString(MLO_LINK_STA_MAC_ADDRESS));
828         link1.setApMacAddress(MacAddress.fromString(MLO_LINK_AP_MAC_ADDRESS));
829         link1.setRssi(TEST_RSSI);
830         link1.setLinkId(TEST_MLO_LINK_ID);
831         link1.setBand(WifiScanner.WIFI_BAND_5_GHZ);
832         link1.setChannel(TEST_CHANNEL);
833         link1.setRxLinkSpeedMbps(TEST_LINK_SPEED);
834         link1.setTxLinkSpeedMbps(TEST_LINK_SPEED);
835         link1.setState(MloLink.MLO_LINK_STATE_UNASSOCIATED);
836 
837         // Make sure all parameters are set.
838         assertNotNull(link1.getApMacAddress());
839         assertEquals(MLO_LINK_AP_MAC_ADDRESS, link1.getApMacAddress().toString());
840         assertNotNull(link1.getStaMacAddress());
841         assertEquals(MLO_LINK_STA_MAC_ADDRESS, link1.getStaMacAddress().toString());
842         assertEquals(TEST_RSSI, link1.getRssi());
843         assertEquals(TEST_CHANNEL, link1.getChannel());
844         assertEquals(TEST_LINK_SPEED, link1.getRxLinkSpeedMbps());
845         assertEquals(TEST_LINK_SPEED, link1.getTxLinkSpeedMbps());
846         assertEquals(TEST_MLO_LINK_ID, link1.getLinkId());
847         assertEquals(WifiScanner.WIFI_BAND_5_GHZ, link1.getBand());
848         assertEquals(MloLink.MLO_LINK_STATE_UNASSOCIATED, link1.getState());
849 
850         // Test RSSI range.
851         link1.setRssi(WifiInfo.INVALID_RSSI - 1);
852         assertEquals(WifiInfo.INVALID_RSSI, link1.getRssi());
853         link1.setRssi(WifiInfo.MAX_RSSI + 1);
854         assertEquals(WifiInfo.MAX_RSSI, link1.getRssi());
855 
856         // Copy link
857         MloLink link2 = new MloLink(link1, 0);
858 
859         // Check links are equal.
860         assertTrue(link1.equals(link2));
861         assertEquals(link2.hashCode(), link1.hashCode());
862         assertEquals(link2.toString(), link1.toString());
863 
864         // Change one parameter and check the links are not equal.
865         link1.setState(MloLink.MLO_LINK_STATE_INVALID);
866         assertFalse(link1.equals(link2));
867         assertNotEquals(link2.hashCode(), link1.hashCode());
868         assertNotEquals(link2.toString(), link1.toString());
869 
870         // Validate states.
871         assertTrue(MloLink.isValidState(MloLink.MLO_LINK_STATE_INVALID));
872         assertTrue(MloLink.isValidState(MloLink.MLO_LINK_STATE_UNASSOCIATED));
873         assertTrue(MloLink.isValidState(MloLink.MLO_LINK_STATE_ACTIVE));
874         assertTrue(MloLink.isValidState(MloLink.MLO_LINK_STATE_IDLE));
875         assertFalse(MloLink.isValidState(MloLink.MLO_LINK_STATE_INVALID - 1));
876     }
877 }
878