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.assertTrue;
27 import static org.junit.Assert.fail;
28 import static org.junit.Assume.assumeTrue;
29 
30 import android.net.NetworkCapabilities;
31 import android.os.Parcel;
32 import android.telephony.SubscriptionManager;
33 
34 import androidx.test.filters.SmallTest;
35 
36 import com.android.modules.utils.build.SdkLevel;
37 
38 import org.junit.Test;
39 
40 import java.nio.charset.StandardCharsets;
41 import java.util.ArrayList;
42 import java.util.List;
43 
44 /**
45  * Unit tests for {@link android.net.wifi.WifiInfo}.
46  */
47 @SmallTest
48 public class WifiInfoTest {
49     private static final long TEST_TX_SUCCESS = 1;
50     private static final long TEST_TX_RETRIES = 2;
51     private static final long TEST_TX_BAD = 3;
52     private static final long TEST_RX_SUCCESS = 4;
53     private static final String TEST_PACKAGE_NAME = "com.test.example";
54     private static final String TEST_FQDN = "test.com";
55     private static final String TEST_PROVIDER_NAME = "test";
56     private static final int TEST_WIFI_STANDARD = ScanResult.WIFI_STANDARD_11AC;
57     private static final int TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS = 866;
58     private static final int TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS = 1200;
59     private static final String TEST_SSID = "Test123";
60     private static final String TEST_BSSID = "12:12:12:12:12:12";
61     private static final int TEST_RSSI = -60;
62     private static final int TEST_NETWORK_ID = 5;
63     private static final int TEST_NETWORK_ID2 = 6;
64     private static final int TEST_SUB_ID = 1;
65 
makeWifiInfoForNoRedactions( List<ScanResult.InformationElement> informationElements)66     private WifiInfo makeWifiInfoForNoRedactions(
67             List<ScanResult.InformationElement> informationElements) {
68         WifiInfo info = new WifiInfo();
69         info.txSuccess = TEST_TX_SUCCESS;
70         info.txRetries = TEST_TX_RETRIES;
71         info.txBad = TEST_TX_BAD;
72         info.rxSuccess = TEST_RX_SUCCESS;
73         info.setSSID(WifiSsid.createFromAsciiEncoded(TEST_SSID));
74         info.setBSSID(TEST_BSSID);
75         info.setNetworkId(TEST_NETWORK_ID);
76         info.setTrusted(true);
77         info.setOemPaid(true);
78         info.setOemPrivate(true);
79         info.setCarrierMerged(true);
80         info.setOsuAp(true);
81         info.setFQDN(TEST_FQDN);
82         info.setProviderFriendlyName(TEST_PROVIDER_NAME);
83         info.setRequestingPackageName(TEST_PACKAGE_NAME);
84         info.setWifiStandard(TEST_WIFI_STANDARD);
85         info.setMaxSupportedTxLinkSpeedMbps(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS);
86         info.setMaxSupportedRxLinkSpeedMbps(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS);
87         info.setSubscriptionId(TEST_SUB_ID);
88         info.setInformationElements(informationElements);
89         info.setIsPrimary(true);
90         info.setMacAddress(TEST_BSSID);
91         return info;
92     }
93 
assertNoRedaction(WifiInfo info, List<ScanResult.InformationElement> informationElements)94     private void assertNoRedaction(WifiInfo info,
95             List<ScanResult.InformationElement> informationElements) {
96         assertEquals(TEST_TX_SUCCESS, info.txSuccess);
97         assertEquals(TEST_TX_RETRIES, info.txRetries);
98         assertEquals(TEST_TX_BAD, info.txBad);
99         assertEquals(TEST_RX_SUCCESS, info.rxSuccess);
100         assertEquals("\"" + TEST_SSID + "\"", info.getSSID());
101         assertEquals(TEST_BSSID, info.getBSSID());
102         assertEquals(TEST_NETWORK_ID, info.getNetworkId());
103         assertTrue(info.isTrusted());
104         assertTrue(info.isOsuAp());
105         assertTrue(info.isPasspointAp());
106         assertEquals(TEST_PACKAGE_NAME, info.getRequestingPackageName());
107         assertEquals(TEST_FQDN, info.getPasspointFqdn());
108         assertEquals(TEST_PROVIDER_NAME, info.getPasspointProviderFriendlyName());
109         assertEquals(TEST_WIFI_STANDARD, info.getWifiStandard());
110         assertEquals(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS, info.getMaxSupportedTxLinkSpeedMbps());
111         assertEquals(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS, info.getMaxSupportedRxLinkSpeedMbps());
112         assertEquals(TEST_BSSID, info.getMacAddress());
113         assertEquals(2, info.getInformationElements().size());
114         assertEquals(informationElements.get(0).id,
115                 info.getInformationElements().get(0).id);
116         assertEquals(informationElements.get(0).idExt,
117                 info.getInformationElements().get(0).idExt);
118         assertArrayEquals(informationElements.get(0).bytes,
119                 info.getInformationElements().get(0).bytes);
120         assertEquals(informationElements.get(1).id,
121                 info.getInformationElements().get(1).id);
122         assertEquals(informationElements.get(1).idExt,
123                 info.getInformationElements().get(1).idExt);
124         assertArrayEquals(informationElements.get(1).bytes,
125                 info.getInformationElements().get(1).bytes);
126         if (SdkLevel.isAtLeastS()) {
127             assertTrue(info.isOemPaid());
128             assertTrue(info.isOemPrivate());
129             assertTrue(info.isCarrierMerged());
130             assertEquals(TEST_SUB_ID, info.getSubscriptionId());
131             assertTrue(info.isPrimary());
132         }
133     }
134 
135     /**
136      *  Verify redaction of WifiInfo with REDACT_NONE.
137      */
138     @Test
testWifiInfoRedactNoRedactions()139     public void testWifiInfoRedactNoRedactions() throws Exception {
140         List<ScanResult.InformationElement> informationElements = generateIes();
141         WifiInfo writeWifiInfo = makeWifiInfoForNoRedactions(informationElements);
142 
143         // Make a copy which allows parcelling of location sensitive data.
144         WifiInfo redactedWifiInfo = writeWifiInfo.makeCopy(NetworkCapabilities.REDACT_NONE);
145 
146         Parcel parcel = Parcel.obtain();
147         redactedWifiInfo.writeToParcel(parcel, 0);
148         // Rewind the pointer to the head of the parcel.
149         parcel.setDataPosition(0);
150         WifiInfo readWifiInfo = WifiInfo.CREATOR.createFromParcel(parcel);
151 
152         assertNoRedaction(redactedWifiInfo, informationElements);
153         assertNoRedaction(readWifiInfo, informationElements);
154 
155         if (SdkLevel.isAtLeastS()) {
156             // equals() was only introduced in S.
157             assertEquals(readWifiInfo, redactedWifiInfo);
158         }
159     }
160 
makeWifiInfoForLocationSensitiveRedaction()161     private WifiInfo makeWifiInfoForLocationSensitiveRedaction() {
162         WifiInfo info = new WifiInfo();
163         info.txSuccess = TEST_TX_SUCCESS;
164         info.txRetries = TEST_TX_RETRIES;
165         info.txBad = TEST_TX_BAD;
166         info.rxSuccess = TEST_RX_SUCCESS;
167         info.setSSID(WifiSsid.createFromAsciiEncoded(TEST_SSID));
168         info.setBSSID(TEST_BSSID);
169         info.setNetworkId(TEST_NETWORK_ID);
170         info.setTrusted(true);
171         info.setOemPaid(true);
172         info.setOemPrivate(true);
173         info.setCarrierMerged(true);
174         info.setOsuAp(true);
175         info.setFQDN(TEST_FQDN);
176         info.setProviderFriendlyName(TEST_PROVIDER_NAME);
177         info.setRequestingPackageName(TEST_PACKAGE_NAME);
178         info.setWifiStandard(TEST_WIFI_STANDARD);
179         info.setMaxSupportedTxLinkSpeedMbps(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS);
180         info.setMaxSupportedRxLinkSpeedMbps(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS);
181         info.setSubscriptionId(TEST_SUB_ID);
182         info.setInformationElements(generateIes());
183         info.setIsPrimary(true);
184         info.setMacAddress(TEST_BSSID);
185         return info;
186     }
187 
assertLocationSensitiveRedaction(WifiInfo info)188     private void assertLocationSensitiveRedaction(WifiInfo info) {
189         assertNotNull(info);
190         assertEquals(TEST_TX_SUCCESS, info.txSuccess);
191         assertEquals(TEST_TX_RETRIES, info.txRetries);
192         assertEquals(TEST_TX_BAD, info.txBad);
193         assertEquals(TEST_RX_SUCCESS, info.rxSuccess);
194         assertEquals(WifiManager.UNKNOWN_SSID, info.getSSID());
195         assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS, info.getBSSID());
196         assertEquals(WifiConfiguration.INVALID_NETWORK_ID, info.getNetworkId());
197         assertTrue(info.isTrusted());
198         assertTrue(info.isOsuAp());
199         assertFalse(info.isPasspointAp()); // fqdn & friendly name is masked.
200         assertEquals(TEST_PACKAGE_NAME, info.getRequestingPackageName());
201         assertNull(info.getPasspointFqdn());
202         assertNull(info.getPasspointProviderFriendlyName());
203         assertEquals(TEST_WIFI_STANDARD, info.getWifiStandard());
204         assertEquals(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS, info.getMaxSupportedTxLinkSpeedMbps());
205         assertEquals(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS, info.getMaxSupportedRxLinkSpeedMbps());
206         assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS, info.getMacAddress());
207         assertNull(info.getInformationElements());
208         if (SdkLevel.isAtLeastS()) {
209             assertTrue(info.isOemPaid());
210             assertTrue(info.isOemPrivate());
211             assertTrue(info.isCarrierMerged());
212             assertEquals(TEST_SUB_ID, info.getSubscriptionId());
213             assertTrue(info.isPrimary());
214         }
215     }
216 
217     /**
218      *  Verify redaction of WifiInfo with REDACT_FOR_ACCESS_FINE_LOCATION.
219      */
220     @Test
testWifiInfoRedactLocationSensitiveInfo()221     public void testWifiInfoRedactLocationSensitiveInfo() throws Exception {
222         WifiInfo writeWifiInfo = makeWifiInfoForLocationSensitiveRedaction();
223 
224         WifiInfo redactedWifiInfo =
225                 writeWifiInfo.makeCopy(NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION);
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         assertLocationSensitiveRedaction(redactedWifiInfo);
234         assertLocationSensitiveRedaction(readWifiInfo);
235 
236         if (SdkLevel.isAtLeastS()) {
237             // equals() was only introduced in S.
238             assertEquals(redactedWifiInfo, readWifiInfo);
239         }
240     }
241 
242     /**
243      *  Verify redaction of WifiInfo with REDACT_FOR_LOCAL_MAC_ADDRESS.
244      */
245     @Test
testWifiInfoRedactLocalMacAddressInfo()246     public void testWifiInfoRedactLocalMacAddressInfo() throws Exception {
247         WifiInfo writeWifiInfo = new WifiInfo();
248         writeWifiInfo.setMacAddress(TEST_BSSID);
249 
250         WifiInfo redactedWifiInfo =
251                 writeWifiInfo.makeCopy(NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS);
252 
253         Parcel parcel = Parcel.obtain();
254         redactedWifiInfo.writeToParcel(parcel, 0);
255         // Rewind the pointer to the head of the parcel.
256         parcel.setDataPosition(0);
257         WifiInfo readWifiInfo = WifiInfo.CREATOR.createFromParcel(parcel);
258 
259         assertNotNull(redactedWifiInfo);
260         assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS, redactedWifiInfo.getMacAddress());
261 
262         assertNotNull(readWifiInfo);
263         assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS, readWifiInfo.getMacAddress());
264 
265         if (SdkLevel.isAtLeastS()) {
266             // equals() was only introduced in S.
267             assertEquals(redactedWifiInfo, readWifiInfo);
268         }
269     }
270 
assertIsPrimaryThrowsSecurityException(WifiInfo info)271     private void assertIsPrimaryThrowsSecurityException(WifiInfo info) {
272         try {
273             // Should generate a security exception if caller does not have network settings
274             // permission.
275             info.isPrimary();
276             fail();
277         } catch (SecurityException e) { /* pass */ }
278     }
279 
280     /**
281      *  Verify redaction of WifiInfo with REDACT_FOR_NETWORK_SETTINGS.
282      */
283     @Test
testWifiInfoRedactNetworkSettingsInfo()284     public void testWifiInfoRedactNetworkSettingsInfo() throws Exception {
285         assumeTrue(SdkLevel.isAtLeastS());
286 
287         WifiInfo writeWifiInfo = new WifiInfo();
288         writeWifiInfo.setIsPrimary(true);
289 
290         WifiInfo redactedWifiInfo =
291                 writeWifiInfo.makeCopy(NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS);
292 
293         Parcel parcel = Parcel.obtain();
294         redactedWifiInfo.writeToParcel(parcel, 0);
295         // Rewind the pointer to the head of the parcel.
296         parcel.setDataPosition(0);
297         WifiInfo readWifiInfo = WifiInfo.CREATOR.createFromParcel(parcel);
298 
299         assertNotNull(redactedWifiInfo);
300         assertIsPrimaryThrowsSecurityException(redactedWifiInfo);
301         assertNotNull(readWifiInfo);
302         assertIsPrimaryThrowsSecurityException(readWifiInfo);
303 
304         if (SdkLevel.isAtLeastS()) {
305             // equals() was only introduced in S.
306             assertEquals(redactedWifiInfo, readWifiInfo);
307         }
308     }
309 
310     @Test
testWifiInfoGetApplicableRedactions()311     public void testWifiInfoGetApplicableRedactions() throws Exception {
312         long redactions = new WifiInfo().getApplicableRedactions();
313         assertEquals(NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION
314                 | NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS
315                 | NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS, redactions);
316     }
317 
makeWifiInfoForLocationSensitiveAndLocalMacAddressRedaction()318     private WifiInfo makeWifiInfoForLocationSensitiveAndLocalMacAddressRedaction() {
319         WifiInfo info = new WifiInfo();
320         info.setSSID(WifiSsid.createFromAsciiEncoded(TEST_SSID));
321         info.setBSSID(TEST_BSSID);
322         info.setNetworkId(TEST_NETWORK_ID);
323         info.setFQDN(TEST_FQDN);
324         info.setProviderFriendlyName(TEST_PROVIDER_NAME);
325         info.setInformationElements(generateIes());
326         info.setMacAddress(TEST_BSSID);
327         return info;
328     }
329 
assertLocationSensitiveAndLocalMacAddressRedaction(WifiInfo info)330     private void assertLocationSensitiveAndLocalMacAddressRedaction(WifiInfo info) {
331         assertNotNull(info);
332         assertEquals(WifiManager.UNKNOWN_SSID, info.getSSID());
333         assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS, info.getBSSID());
334         assertEquals(WifiConfiguration.INVALID_NETWORK_ID, info.getNetworkId());
335         assertNull(info.getPasspointFqdn());
336         assertNull(info.getPasspointProviderFriendlyName());
337         assertEquals(WifiInfo.DEFAULT_MAC_ADDRESS, info.getMacAddress());
338         assertNull(info.getInformationElements());
339     }
340 
341     @Test
testWifiInfoRedactLocationAndLocalMacAddressSensitiveInfo()342     public void testWifiInfoRedactLocationAndLocalMacAddressSensitiveInfo()
343             throws Exception {
344         assumeTrue(SdkLevel.isAtLeastS());
345 
346         WifiInfo writeWifiInfo = makeWifiInfoForLocationSensitiveAndLocalMacAddressRedaction();
347 
348         WifiInfo redactedWifiInfo =
349                 writeWifiInfo.makeCopy(NetworkCapabilities.REDACT_FOR_ACCESS_FINE_LOCATION
350                         | NetworkCapabilities.REDACT_FOR_LOCAL_MAC_ADDRESS);
351 
352         Parcel parcel = Parcel.obtain();
353         redactedWifiInfo.writeToParcel(parcel, 0);
354         // Rewind the pointer to the head of the parcel.
355         parcel.setDataPosition(0);
356         WifiInfo readWifiInfo = WifiInfo.CREATOR.createFromParcel(parcel);
357 
358         assertLocationSensitiveAndLocalMacAddressRedaction(redactedWifiInfo);
359         assertLocationSensitiveAndLocalMacAddressRedaction(readWifiInfo);
360 
361         if (SdkLevel.isAtLeastS()) {
362             // equals() was only introduced in S.
363             assertEquals(redactedWifiInfo, readWifiInfo);
364         }
365     }
366 
367     /**
368      *  Verify parcel write/read with null information elements.
369      */
370     @Test
testWifiInfoParcelWriteReadWithNullInfoElements()371     public void testWifiInfoParcelWriteReadWithNullInfoElements() throws Exception {
372         assumeTrue(SdkLevel.isAtLeastS());
373 
374         WifiInfo writeWifiInfo = new WifiInfo();
375         writeWifiInfo.setInformationElements(null);
376 
377         // Make a copy which allows parcelling of location sensitive data.
378         WifiInfo writeWifiInfoCopy = writeWifiInfo.makeCopy(NetworkCapabilities.REDACT_NONE);
379 
380         Parcel parcel = Parcel.obtain();
381         writeWifiInfoCopy.writeToParcel(parcel, 0);
382         // Rewind the pointer to the head of the parcel.
383         parcel.setDataPosition(0);
384         WifiInfo readWifiInfo = WifiInfo.CREATOR.createFromParcel(parcel);
385         assertNull(readWifiInfo.getInformationElements());
386     }
387 
388     /**
389      *  Verify parcel write/read with empty information elements.
390      */
391     @Test
testWifiInfoParcelWriteReadWithEmptyInfoElements()392     public void testWifiInfoParcelWriteReadWithEmptyInfoElements() throws Exception {
393         assumeTrue(SdkLevel.isAtLeastS());
394 
395         WifiInfo writeWifiInfo = new WifiInfo();
396         writeWifiInfo.setInformationElements(new ArrayList<>());
397 
398         // Make a copy which allows parcelling of location sensitive data.
399         WifiInfo writeWifiInfoCopy = writeWifiInfo.makeCopy(NetworkCapabilities.REDACT_NONE);
400 
401         Parcel parcel = Parcel.obtain();
402         writeWifiInfoCopy.writeToParcel(parcel, 0);
403         // Rewind the pointer to the head of the parcel.
404         parcel.setDataPosition(0);
405         WifiInfo readWifiInfo = WifiInfo.CREATOR.createFromParcel(parcel);
406         assertTrue(readWifiInfo.getInformationElements().isEmpty());
407     }
408 
409     @Test
testWifiInfoCopyConstructor()410     public void testWifiInfoCopyConstructor() throws Exception {
411         WifiInfo writeWifiInfo = new WifiInfo();
412         writeWifiInfo.txSuccess = TEST_TX_SUCCESS;
413         writeWifiInfo.txRetries = TEST_TX_RETRIES;
414         writeWifiInfo.txBad = TEST_TX_BAD;
415         writeWifiInfo.rxSuccess = TEST_RX_SUCCESS;
416         writeWifiInfo.setTrusted(true);
417         writeWifiInfo.setOemPaid(true);
418         writeWifiInfo.setOemPrivate(true);
419         writeWifiInfo.setCarrierMerged(true);
420         writeWifiInfo.setOsuAp(true);
421         writeWifiInfo.setFQDN(TEST_FQDN);
422         writeWifiInfo.setProviderFriendlyName(TEST_PROVIDER_NAME);
423         writeWifiInfo.setRequestingPackageName(TEST_PACKAGE_NAME);
424         writeWifiInfo.setWifiStandard(TEST_WIFI_STANDARD);
425         writeWifiInfo.setMaxSupportedTxLinkSpeedMbps(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS);
426         writeWifiInfo.setMaxSupportedRxLinkSpeedMbps(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS);
427         writeWifiInfo.setSubscriptionId(TEST_SUB_ID);
428         writeWifiInfo.setIsPrimary(true);
429 
430         WifiInfo readWifiInfo = new WifiInfo(writeWifiInfo);
431 
432         assertEquals(TEST_TX_SUCCESS, readWifiInfo.txSuccess);
433         assertEquals(TEST_TX_RETRIES, readWifiInfo.txRetries);
434         assertEquals(TEST_TX_BAD, readWifiInfo.txBad);
435         assertEquals(TEST_RX_SUCCESS, readWifiInfo.rxSuccess);
436         assertTrue(readWifiInfo.isTrusted());
437         assertTrue(readWifiInfo.isOsuAp());
438         assertTrue(readWifiInfo.isPasspointAp());
439         assertEquals(TEST_PACKAGE_NAME, readWifiInfo.getRequestingPackageName());
440         assertEquals(TEST_FQDN, readWifiInfo.getPasspointFqdn());
441         assertEquals(TEST_PROVIDER_NAME, readWifiInfo.getPasspointProviderFriendlyName());
442         assertEquals(TEST_WIFI_STANDARD, readWifiInfo.getWifiStandard());
443         assertEquals(TEST_MAX_SUPPORTED_TX_LINK_SPEED_MBPS,
444                 readWifiInfo.getMaxSupportedTxLinkSpeedMbps());
445         assertEquals(TEST_MAX_SUPPORTED_RX_LINK_SPEED_MBPS,
446                 readWifiInfo.getMaxSupportedRxLinkSpeedMbps());
447         if (SdkLevel.isAtLeastS()) {
448             assertTrue(readWifiInfo.isOemPaid());
449             assertTrue(readWifiInfo.isOemPrivate());
450             assertTrue(readWifiInfo.isCarrierMerged());
451             assertEquals(TEST_SUB_ID, readWifiInfo.getSubscriptionId());
452             assertTrue(readWifiInfo.isPrimary());
453         }
454     }
455 
456     /**
457      *  Verify values after reset()
458      */
459     @Test
testWifiInfoResetValue()460     public void testWifiInfoResetValue() throws Exception {
461         WifiInfo wifiInfo = new WifiInfo();
462         wifiInfo.reset();
463         assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getMaxSupportedTxLinkSpeedMbps());
464         assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getMaxSupportedRxLinkSpeedMbps());
465         assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getTxLinkSpeedMbps());
466         assertEquals(WifiInfo.LINK_SPEED_UNKNOWN, wifiInfo.getRxLinkSpeedMbps());
467         assertEquals(WifiInfo.INVALID_RSSI, wifiInfo.getRssi());
468         assertEquals(WifiManager.UNKNOWN_SSID, wifiInfo.getSSID());
469         assertEquals(null, wifiInfo.getBSSID());
470         assertEquals(-1, wifiInfo.getNetworkId());
471         if (SdkLevel.isAtLeastS()) {
472             assertFalse(wifiInfo.isOemPaid());
473             assertFalse(wifiInfo.isOemPrivate());
474             assertFalse(wifiInfo.isCarrierMerged());
475             assertEquals(SubscriptionManager.INVALID_SUBSCRIPTION_ID, wifiInfo.getSubscriptionId());
476             assertFalse(wifiInfo.isPrimary());
477         }
478     }
479 
480     /**
481      * Test that the WifiInfo Builder returns the same values that was set, and that
482      * calling build multiple times returns different instances.
483      */
484     @Test
testWifiInfoBuilder()485     public void testWifiInfoBuilder() throws Exception {
486         WifiInfo.Builder builder = new WifiInfo.Builder()
487                 .setSsid(TEST_SSID.getBytes(StandardCharsets.UTF_8))
488                 .setBssid(TEST_BSSID)
489                 .setRssi(TEST_RSSI)
490                 .setNetworkId(TEST_NETWORK_ID);
491 
492         WifiInfo info1 = builder.build();
493 
494         assertEquals("\"" + TEST_SSID + "\"", info1.getSSID());
495         assertEquals(TEST_BSSID, info1.getBSSID());
496         assertEquals(TEST_RSSI, info1.getRssi());
497         assertEquals(TEST_NETWORK_ID, info1.getNetworkId());
498 
499         WifiInfo info2 = builder
500                 .setNetworkId(TEST_NETWORK_ID2)
501                 .build();
502 
503         // different instances
504         assertNotSame(info1, info2);
505 
506         // assert that info1 didn't change
507         assertEquals("\"" + TEST_SSID + "\"", info1.getSSID());
508         assertEquals(TEST_BSSID, info1.getBSSID());
509         assertEquals(TEST_RSSI, info1.getRssi());
510         assertEquals(TEST_NETWORK_ID, info1.getNetworkId());
511 
512         // assert that info2 changed
513         assertEquals("\"" + TEST_SSID + "\"", info2.getSSID());
514         assertEquals(TEST_BSSID, info2.getBSSID());
515         assertEquals(TEST_RSSI, info2.getRssi());
516         assertEquals(TEST_NETWORK_ID2, info2.getNetworkId());
517     }
518 
519     @Test
testWifiInfoEquals()520     public void testWifiInfoEquals() throws Exception {
521         WifiInfo.Builder builder = new WifiInfo.Builder()
522                 .setSsid(TEST_SSID.getBytes(StandardCharsets.UTF_8))
523                 .setBssid(TEST_BSSID)
524                 .setRssi(TEST_RSSI)
525                 .setNetworkId(TEST_NETWORK_ID);
526 
527         WifiInfo info1 = builder.build();
528         WifiInfo info2 = builder.build();
529         if (SdkLevel.isAtLeastS()) {
530             assertEquals(info1, info2);
531         } else {
532             // On R devices, reference equality.
533             assertNotEquals(info1, info2);
534         }
535 
536         info1.setSubscriptionId(TEST_SUB_ID);
537         assertNotEquals(info1, info2);
538 
539         info2.setSubscriptionId(TEST_SUB_ID);
540         if (SdkLevel.isAtLeastS()) {
541             assertEquals(info1, info2);
542         } else {
543             // On R devices, reference equality.
544             assertNotEquals(info1, info2);
545         }
546 
547         info1.setSSID(WifiSsid.createFromHex(null));
548         assertNotEquals(info1, info2);
549 
550         info2.setSSID(WifiSsid.createFromHex(null));
551         if (SdkLevel.isAtLeastS()) {
552             assertEquals(info1, info2);
553         } else {
554             // On R devices, reference equality.
555             assertNotEquals(info1, info2);
556         }
557     }
558 
559     @Test
testWifiInfoEqualsWithInfoElements()560     public void testWifiInfoEqualsWithInfoElements() throws Exception {
561         WifiInfo.Builder builder = new WifiInfo.Builder()
562                 .setSsid(TEST_SSID.getBytes(StandardCharsets.UTF_8))
563                 .setBssid(TEST_BSSID)
564                 .setRssi(TEST_RSSI)
565                 .setNetworkId(TEST_NETWORK_ID);
566 
567         WifiInfo info1 = builder.build();
568         WifiInfo info2 = builder.build();
569         if (SdkLevel.isAtLeastS()) {
570             assertEquals(info1, info2);
571         } else {
572             // On R devices, reference equality.
573             assertNotEquals(info1, info2);
574         }
575 
576         info1.setInformationElements(generateIes());
577         info2.setInformationElements(generateIes());
578 
579         if (SdkLevel.isAtLeastS()) {
580             assertEquals(info1, info2);
581         } else {
582             // On R devices, reference equality.
583             assertNotEquals(info1, info2);
584         }
585     }
586 
587     @Test
testWifiInfoHashcode()588     public void testWifiInfoHashcode() throws Exception {
589         WifiInfo.Builder builder = new WifiInfo.Builder()
590                 .setSsid(TEST_SSID.getBytes(StandardCharsets.UTF_8))
591                 .setBssid(TEST_BSSID)
592                 .setRssi(TEST_RSSI)
593                 .setNetworkId(TEST_NETWORK_ID);
594 
595         WifiInfo info1 = builder.build();
596         WifiInfo info2 = builder.build();
597         if (SdkLevel.isAtLeastS()) {
598             assertEquals(info1.hashCode(), info2.hashCode());
599         } else {
600             // On R devices, system generated hashcode.
601             assertNotEquals(info1.hashCode(), info2.hashCode());
602         }
603 
604         info1.setSubscriptionId(TEST_SUB_ID);
605         assertNotEquals(info1.hashCode(), info2.hashCode());
606 
607         info2.setSubscriptionId(TEST_SUB_ID);
608         if (SdkLevel.isAtLeastS()) {
609             assertEquals(info1.hashCode(), info2.hashCode());
610         } else {
611             // On R devices, system generated hashcode.
612             assertNotEquals(info1.hashCode(), info2.hashCode());
613         }
614 
615         info1.setSSID(WifiSsid.createFromHex(null));
616         assertNotEquals(info1.hashCode(), info2.hashCode());
617 
618         info2.setSSID(WifiSsid.createFromHex(null));
619         if (SdkLevel.isAtLeastS()) {
620             assertEquals(info1.hashCode(), info2.hashCode());
621         } else {
622             // On R devices, system generated hashcode.
623             assertNotEquals(info1.hashCode(), info2.hashCode());
624         }
625     }
626 
627     @Test
testWifiInfoCurrentSecurityType()628     public void testWifiInfoCurrentSecurityType() throws Exception {
629         WifiInfo.Builder builder = new WifiInfo.Builder()
630                 .setSsid(TEST_SSID.getBytes(StandardCharsets.UTF_8))
631                 .setBssid(TEST_BSSID)
632                 .setRssi(TEST_RSSI)
633                 .setNetworkId(TEST_NETWORK_ID)
634                 .setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_SAE);
635 
636         WifiInfo info = new WifiInfo();
637         assertEquals(WifiInfo.SECURITY_TYPE_UNKNOWN, info.getCurrentSecurityType());
638 
639         info = builder.build();
640         assertEquals(WifiInfo.SECURITY_TYPE_SAE, info.getCurrentSecurityType());
641 
642         info = builder.setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_OPEN).build();
643         assertEquals(WifiInfo.SECURITY_TYPE_OPEN, info.getCurrentSecurityType());
644 
645         info = builder.setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_WEP).build();
646         assertEquals(WifiInfo.SECURITY_TYPE_WEP, info.getCurrentSecurityType());
647 
648         info = builder.setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_PSK).build();
649         assertEquals(WifiInfo.SECURITY_TYPE_PSK, info.getCurrentSecurityType());
650 
651         info = builder.setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_EAP).build();
652         assertEquals(WifiInfo.SECURITY_TYPE_EAP, info.getCurrentSecurityType());
653 
654         info = builder.setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_OWE).build();
655         assertEquals(WifiInfo.SECURITY_TYPE_OWE, info.getCurrentSecurityType());
656 
657         info = builder.setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_WAPI_PSK).build();
658         assertEquals(WifiInfo.SECURITY_TYPE_WAPI_PSK, info.getCurrentSecurityType());
659 
660         info = builder.setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_WAPI_CERT).build();
661         assertEquals(WifiInfo.SECURITY_TYPE_WAPI_CERT, info.getCurrentSecurityType());
662 
663         info = builder.setCurrentSecurityType(
664                 WifiConfiguration.SECURITY_TYPE_EAP_WPA3_ENTERPRISE).build();
665         assertEquals(WifiInfo.SECURITY_TYPE_EAP_WPA3_ENTERPRISE, info.getCurrentSecurityType());
666 
667         info = builder.setCurrentSecurityType(
668                 WifiConfiguration.SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT).build();
669         assertEquals(WifiInfo.SECURITY_TYPE_EAP_WPA3_ENTERPRISE_192_BIT,
670                 info.getCurrentSecurityType());
671 
672         info = builder.setCurrentSecurityType(
673                 WifiConfiguration.SECURITY_TYPE_PASSPOINT_R1_R2).build();
674         assertEquals(WifiInfo.SECURITY_TYPE_PASSPOINT_R1_R2, info.getCurrentSecurityType());
675 
676         info = builder.setCurrentSecurityType(WifiConfiguration.SECURITY_TYPE_PASSPOINT_R3).build();
677         assertEquals(WifiInfo.SECURITY_TYPE_PASSPOINT_R3, info.getCurrentSecurityType());
678 
679         info.clearCurrentSecurityType();
680         assertEquals(WifiInfo.SECURITY_TYPE_UNKNOWN, info.getCurrentSecurityType());
681     }
682 
generateIes()683     private static List<ScanResult.InformationElement> generateIes() {
684         List<ScanResult.InformationElement> informationElements = new ArrayList<>();
685         ScanResult.InformationElement informationElement = new ScanResult.InformationElement();
686         informationElement.id = ScanResult.InformationElement.EID_HT_OPERATION;
687         informationElement.idExt = 0;
688         informationElement.bytes = new byte[]{0x11, 0x22, 0x33};
689         informationElements.add(informationElement);
690 
691         informationElement = new ScanResult.InformationElement();
692         informationElement.id = ScanResult.InformationElement.EID_EXTENSION_PRESENT;
693         informationElement.idExt = ScanResult.InformationElement.EID_EXT_HE_OPERATION;
694         informationElement.bytes = new byte[]{0x44, 0x55, 0x66};
695         informationElements.add(informationElement);
696 
697         return informationElements;
698     }
699 }
700