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.assertNull;
22 import static org.mockito.Mockito.validateMockitoUsage;
23 
24 import android.net.wifi.ScanResult.InformationElement;
25 import android.os.Parcel;
26 
27 import androidx.test.filters.SmallTest;
28 
29 import org.junit.After;
30 import org.junit.Before;
31 import org.junit.Test;
32 import org.mockito.MockitoAnnotations;
33 
34 /**
35  * Unit tests for {@link android.net.wifi.WifiScanner}.
36  */
37 @SmallTest
38 public class ScanResultTest {
39     public static final String TEST_SSID = "\"test_ssid\"";
40     public static final String TEST_BSSID = "04:ac:fe:45:34:10";
41     public static final String TEST_CAPS = "CCMP";
42     public static final int TEST_LEVEL = -56;
43     public static final int TEST_FREQUENCY = 2412;
44     public static final long TEST_TSF = 04660l;
45     public static final @WifiAnnotations.WifiStandard int TEST_WIFI_STANDARD =
46             ScanResult.WIFI_STANDARD_11AC;
47 
48     /**
49      * Frequency to channel map. This include some frequencies used outside the US.
50      * Representing it using a vector (instead of map) for simplification.
51      */
52     private static final int[] FREQUENCY_TO_CHANNEL_MAP = {
53             2412, WifiScanner.WIFI_BAND_24_GHZ, 1,
54             2417, WifiScanner.WIFI_BAND_24_GHZ, 2,
55             2422, WifiScanner.WIFI_BAND_24_GHZ, 3,
56             2427, WifiScanner.WIFI_BAND_24_GHZ, 4,
57             2432, WifiScanner.WIFI_BAND_24_GHZ, 5,
58             2437, WifiScanner.WIFI_BAND_24_GHZ, 6,
59             2442, WifiScanner.WIFI_BAND_24_GHZ, 7,
60             2447, WifiScanner.WIFI_BAND_24_GHZ, 8,
61             2452, WifiScanner.WIFI_BAND_24_GHZ, 9,
62             2457, WifiScanner.WIFI_BAND_24_GHZ, 10,
63             2462, WifiScanner.WIFI_BAND_24_GHZ, 11,
64             /* 12, 13 are only legitimate outside the US. */
65             2467, WifiScanner.WIFI_BAND_24_GHZ, 12,
66             2472, WifiScanner.WIFI_BAND_24_GHZ, 13,
67             /* 14 is for Japan, DSSS and CCK only. */
68             2484, WifiScanner.WIFI_BAND_24_GHZ, 14,
69             /* 34 valid in Japan. */
70             5170, WifiScanner.WIFI_BAND_5_GHZ, 34,
71             5180, WifiScanner.WIFI_BAND_5_GHZ, 36,
72             5190, WifiScanner.WIFI_BAND_5_GHZ, 38,
73             5200, WifiScanner.WIFI_BAND_5_GHZ, 40,
74             5210, WifiScanner.WIFI_BAND_5_GHZ, 42,
75             5220, WifiScanner.WIFI_BAND_5_GHZ, 44,
76             5230, WifiScanner.WIFI_BAND_5_GHZ, 46,
77             5240, WifiScanner.WIFI_BAND_5_GHZ, 48,
78             5260, WifiScanner.WIFI_BAND_5_GHZ, 52,
79             5280, WifiScanner.WIFI_BAND_5_GHZ, 56,
80             5300, WifiScanner.WIFI_BAND_5_GHZ, 60,
81             5320, WifiScanner.WIFI_BAND_5_GHZ, 64,
82             5500, WifiScanner.WIFI_BAND_5_GHZ, 100,
83             5520, WifiScanner.WIFI_BAND_5_GHZ, 104,
84             5540, WifiScanner.WIFI_BAND_5_GHZ, 108,
85             5560, WifiScanner.WIFI_BAND_5_GHZ, 112,
86             5580, WifiScanner.WIFI_BAND_5_GHZ, 116,
87             /* 120, 124, 128 valid in Europe/Japan. */
88             5600, WifiScanner.WIFI_BAND_5_GHZ, 120,
89             5620, WifiScanner.WIFI_BAND_5_GHZ, 124,
90             5640, WifiScanner.WIFI_BAND_5_GHZ, 128,
91             /* 132+ valid in US. */
92             5660, WifiScanner.WIFI_BAND_5_GHZ, 132,
93             5680, WifiScanner.WIFI_BAND_5_GHZ, 136,
94             5700, WifiScanner.WIFI_BAND_5_GHZ, 140,
95             /* 144 is supported by a subset of WiFi chips. */
96             5720, WifiScanner.WIFI_BAND_5_GHZ, 144,
97             5745, WifiScanner.WIFI_BAND_5_GHZ, 149,
98             5765, WifiScanner.WIFI_BAND_5_GHZ, 153,
99             5785, WifiScanner.WIFI_BAND_5_GHZ, 157,
100             5805, WifiScanner.WIFI_BAND_5_GHZ, 161,
101             5825, WifiScanner.WIFI_BAND_5_GHZ, 165,
102             5845, WifiScanner.WIFI_BAND_5_GHZ, 169,
103             5865, WifiScanner.WIFI_BAND_5_GHZ, 173,
104             /* Now some 6GHz channels */
105             5945, WifiScanner.WIFI_BAND_6_GHZ, 1,
106             5960, WifiScanner.WIFI_BAND_6_GHZ, 4,
107             6100, WifiScanner.WIFI_BAND_6_GHZ, 32
108     };
109 
110     /**
111      * Setup before tests.
112      */
113     @Before
setUp()114     public void setUp() throws Exception {
115         MockitoAnnotations.initMocks(this);
116     }
117 
118     /**
119      * Clean up after tests.
120      */
121     @After
cleanup()122     public void cleanup() {
123         validateMockitoUsage();
124     }
125 
126     /**
127      * Verify parcel read/write for ScanResult.
128      */
129     @Test
verifyScanResultParcelWithoutRadioChainInfo()130     public void verifyScanResultParcelWithoutRadioChainInfo() throws Exception {
131         ScanResult writeScanResult = createScanResult();
132         ScanResult readScanResult = parcelReadWrite(writeScanResult);
133         assertScanResultEquals(writeScanResult, readScanResult);
134     }
135 
136     /**
137      * Verify parcel read/write for ScanResult.
138      */
139     @Test
verifyScanResultParcelWithZeroRadioChainInfo()140     public void verifyScanResultParcelWithZeroRadioChainInfo() throws Exception {
141         ScanResult writeScanResult = createScanResult();
142         writeScanResult.radioChainInfos = new ScanResult.RadioChainInfo[0];
143         ScanResult readScanResult = parcelReadWrite(writeScanResult);
144         assertNull(readScanResult.radioChainInfos);
145     }
146 
147     /**
148      * Verify parcel read/write for ScanResult.
149      */
150     @Test
verifyScanResultParcelWithRadioChainInfo()151     public void verifyScanResultParcelWithRadioChainInfo() throws Exception {
152         ScanResult writeScanResult = createScanResult();
153         writeScanResult.radioChainInfos = new ScanResult.RadioChainInfo[2];
154         writeScanResult.radioChainInfos[0] = new ScanResult.RadioChainInfo();
155         writeScanResult.radioChainInfos[0].id = 0;
156         writeScanResult.radioChainInfos[0].level = -45;
157         writeScanResult.radioChainInfos[1] = new ScanResult.RadioChainInfo();
158         writeScanResult.radioChainInfos[1].id = 1;
159         writeScanResult.radioChainInfos[1].level = -54;
160         ScanResult readScanResult = parcelReadWrite(writeScanResult);
161         assertScanResultEquals(writeScanResult, readScanResult);
162     }
163 
164     /**
165      * Verify copy constructor for ScanResult.
166      */
167     @Test
verifyScanResultCopyWithoutRadioChainInfo()168     public void verifyScanResultCopyWithoutRadioChainInfo() throws Exception {
169         ScanResult scanResult = createScanResult();
170         ScanResult copyScanResult = new ScanResult(scanResult);
171         assertScanResultEquals(scanResult, copyScanResult);
172     }
173 
174     /**
175      * Verify copy constructor for ScanResult.
176      */
177     @Test
verifyScanResultCopyWithRadioChainInfo()178     public void verifyScanResultCopyWithRadioChainInfo() throws Exception {
179         ScanResult scanResult = createScanResult();
180         scanResult.radioChainInfos = new ScanResult.RadioChainInfo[2];
181         scanResult.radioChainInfos[0] = new ScanResult.RadioChainInfo();
182         scanResult.radioChainInfos[0].id = 0;
183         scanResult.radioChainInfos[0].level = -45;
184         scanResult.radioChainInfos[1] = new ScanResult.RadioChainInfo();
185         scanResult.radioChainInfos[1].id = 1;
186         scanResult.radioChainInfos[1].level = -54;
187         ScanResult copyScanResult = new ScanResult(scanResult);
188         assertScanResultEquals(scanResult, copyScanResult);
189     }
190 
191     /**
192      * Verify parcel read/write for ScanResult with Information Element
193      */
194     @Test
verifyScanResultParcelWithInformationElement()195     public void verifyScanResultParcelWithInformationElement() throws Exception {
196         ScanResult writeScanResult = createScanResult();
197         writeScanResult.informationElements = new ScanResult.InformationElement[2];
198         writeScanResult.informationElements[0] = new ScanResult.InformationElement();
199         writeScanResult.informationElements[0].id = InformationElement.EID_HT_OPERATION;
200         writeScanResult.informationElements[0].idExt = 0;
201         writeScanResult.informationElements[0].bytes = new byte[]{0x11, 0x22, 0x33};
202         writeScanResult.informationElements[1] = new ScanResult.InformationElement();
203         writeScanResult.informationElements[1].id = InformationElement.EID_EXTENSION_PRESENT;
204         writeScanResult.informationElements[1].idExt = InformationElement.EID_EXT_HE_OPERATION;
205         writeScanResult.informationElements[1].bytes = new byte[]{0x44, 0x55, 0x66};
206         ScanResult readScanResult = new ScanResult(writeScanResult);
207         assertScanResultEquals(writeScanResult, readScanResult);
208     }
209 
210     /**
211      * Verify toString for ScanResult.
212      */
213     @Test
verifyScanResultToStringWithoutRadioChainInfo()214     public void verifyScanResultToStringWithoutRadioChainInfo() throws Exception {
215         ScanResult scanResult = createScanResult();
216         assertEquals("SSID: \"test_ssid\", BSSID: 04:ac:fe:45:34:10, capabilities: CCMP, "
217                 + "level: -56, frequency: 2412, timestamp: 2480, "
218                 + "distance: 0(cm), distanceSd: 0(cm), "
219                 + "passpoint: no, ChannelBandwidth: 0, centerFreq0: 0, centerFreq1: 0, "
220                 + "standard: 11ac, "
221                 + "80211mcResponder: is not supported, "
222                 + "Radio Chain Infos: null", scanResult.toString());
223     }
224 
225     /**
226      * Verify toString for ScanResult.
227      */
228     @Test
verifyScanResultToStringWithRadioChainInfo()229     public void verifyScanResultToStringWithRadioChainInfo() throws Exception {
230         ScanResult scanResult = createScanResult();
231         scanResult.radioChainInfos = new ScanResult.RadioChainInfo[2];
232         scanResult.radioChainInfos[0] = new ScanResult.RadioChainInfo();
233         scanResult.radioChainInfos[0].id = 0;
234         scanResult.radioChainInfos[0].level = -45;
235         scanResult.radioChainInfos[1] = new ScanResult.RadioChainInfo();
236         scanResult.radioChainInfos[1].id = 1;
237         scanResult.radioChainInfos[1].level = -54;
238         assertEquals("SSID: \"test_ssid\", BSSID: 04:ac:fe:45:34:10, capabilities: CCMP, "
239                 + "level: -56, frequency: 2412, timestamp: 2480, distance: 0(cm), "
240                 + "distanceSd: 0(cm), "
241                 + "passpoint: no, ChannelBandwidth: 0, centerFreq0: 0, centerFreq1: 0, "
242                 + "standard: 11ac, "
243                 + "80211mcResponder: is not supported, "
244                 + "Radio Chain Infos: [RadioChainInfo: id=0, level=-45, "
245                 + "RadioChainInfo: id=1, level=-54]", scanResult.toString());
246     }
247 
248     /**
249      * verify frequency to channel conversion for all possible frequencies.
250      */
251     @Test
convertFrequencyToChannel()252     public void convertFrequencyToChannel() throws Exception {
253         for (int i = 0; i < FREQUENCY_TO_CHANNEL_MAP.length; i += 3) {
254             assertEquals(FREQUENCY_TO_CHANNEL_MAP[i + 2],
255                     ScanResult.convertFrequencyMhzToChannel(FREQUENCY_TO_CHANNEL_MAP[i]));
256         }
257     }
258 
259     /**
260      * Verify frequency to channel conversion failed for an invalid frequency.
261      */
262     @Test
convertFrequencyToChannelWithInvalidFreq()263     public void convertFrequencyToChannelWithInvalidFreq() throws Exception {
264         assertEquals(-1, ScanResult.convertFrequencyMhzToChannel(8000));
265     }
266 
267     /**
268      * Write the provided {@link ScanResult} to a parcel and deserialize it.
269      */
parcelReadWrite(ScanResult writeResult)270     private static ScanResult parcelReadWrite(ScanResult writeResult) throws Exception {
271         Parcel parcel = Parcel.obtain();
272         writeResult.writeToParcel(parcel, 0);
273         parcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
274         return ScanResult.CREATOR.createFromParcel(parcel);
275     }
276 
createScanResult()277     private static ScanResult createScanResult() {
278         ScanResult result = new ScanResult();
279         result.wifiSsid = WifiSsid.createFromAsciiEncoded(TEST_SSID);
280         result.BSSID = TEST_BSSID;
281         result.capabilities = TEST_CAPS;
282         result.level = TEST_LEVEL;
283         result.frequency = TEST_FREQUENCY;
284         result.timestamp = TEST_TSF;
285         result.setWifiStandard(TEST_WIFI_STANDARD);
286         return result;
287     }
288 
assertScanResultEquals(ScanResult expected, ScanResult actual)289     private static void assertScanResultEquals(ScanResult expected, ScanResult actual) {
290         assertEquals(expected.SSID, actual.SSID);
291         assertEquals(expected.BSSID, actual.BSSID);
292         assertEquals(expected.capabilities, actual.capabilities);
293         assertEquals(expected.level, actual.level);
294         assertEquals(expected.frequency, actual.frequency);
295         assertEquals(expected.timestamp, actual.timestamp);
296         assertEquals(expected.getWifiStandard(), actual.getWifiStandard());
297         assertArrayEquals(expected.radioChainInfos, actual.radioChainInfos);
298         assertArrayEquals(expected.informationElements, actual.informationElements);
299     }
300 }
301