1 /*
2  * Copyright (C) 2020 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.nl80211.cts;
18 
19 import static android.net.wifi.nl80211.WifiNl80211Manager.OemSecurityType;
20 
21 import static com.google.common.truth.Truth.assertThat;
22 
23 import static org.junit.Assert.assertFalse;
24 import static org.junit.Assert.assertNotNull;
25 import static org.junit.Assert.fail;
26 import static org.junit.Assume.assumeTrue;
27 
28 import android.content.Context;
29 import android.net.wifi.ScanResult;
30 import android.net.wifi.WifiManager;
31 import android.net.wifi.WifiScanner;
32 import android.net.wifi.nl80211.WifiNl80211Manager;
33 import android.os.Binder;
34 import android.os.Build;
35 import android.os.IBinder;
36 import android.platform.test.annotations.AppModeFull;
37 
38 import androidx.test.ext.junit.runners.AndroidJUnit4;
39 import androidx.test.filters.SdkSuppress;
40 import androidx.test.filters.SmallTest;
41 import androidx.test.platform.app.InstrumentationRegistry;
42 
43 import org.junit.Before;
44 import org.junit.Test;
45 import org.junit.runner.RunWith;
46 
47 import java.util.Arrays;
48 import java.util.concurrent.ConcurrentLinkedQueue;
49 import java.util.concurrent.Executor;
50 
51 
52 /** CTS tests for {@link WifiNl80211Manager}. */
53 @SmallTest
54 @RunWith(AndroidJUnit4.class)
55 @AppModeFull(reason = "Cannot get WifiManager/WifiNl80211Manager in instant app mode")
56 public class WifiNl80211ManagerTest {
57 
58     private Context mContext;
59 
60     private static class TestExecutor implements Executor {
61         private ConcurrentLinkedQueue<Runnable> tasks = new ConcurrentLinkedQueue<>();
62 
63         @Override
execute(Runnable task)64         public void execute(Runnable task) {
65             tasks.add(task);
66         }
67 
runAll()68         private void runAll() {
69             Runnable task = tasks.poll();
70             while (task != null) {
71                 task.run();
72                 task = tasks.poll();
73             }
74         }
75     }
76 
77     private class TestCountryCodeChangeListener implements
78             WifiNl80211Manager.CountryCodeChangedListener {
79         private String mCurrentCountryCode;
80 
getCurrentCountryCode()81         public String getCurrentCountryCode() {
82             return mCurrentCountryCode;
83         }
84 
85         @Override
onCountryCodeChanged(String country)86         public void onCountryCodeChanged(String country) {
87             mCurrentCountryCode = country;
88         }
89     }
90 
91     private class NormalScanEventCallback implements WifiNl80211Manager.ScanEventCallback {
92         private String mIfaceName;
93 
NormalScanEventCallback(String ifaceName)94         NormalScanEventCallback(String ifaceName) {
95             mIfaceName = ifaceName;
96         }
97 
98         @Override
onScanResultReady()99         public void onScanResultReady() {
100         }
101 
102         @Override
onScanFailed()103         public void onScanFailed() {
104         }
105 
106         @Override
onScanFailed(int errorCode)107         public void onScanFailed(int errorCode) {
108         }
109     }
110 
111     private class PnoScanEventCallback implements WifiNl80211Manager.ScanEventCallback {
112         private String mIfaceName;
113 
PnoScanEventCallback(String ifaceName)114         PnoScanEventCallback(String ifaceName) {
115             mIfaceName = ifaceName;
116         }
117 
118         @Override
onScanResultReady()119         public void onScanResultReady() {
120         }
121 
122         @Override
onScanFailed()123         public void onScanFailed() {
124         }
125     }
126 
127     @Before
setUp()128     public void setUp() {
129         mContext = InstrumentationRegistry.getInstrumentation().getContext();
130         // skip tests if Wifi is not supported
131         assumeTrue(WifiFeature.isWifiSupported(mContext));
132     }
133 
134     @Test
testOemSecurityTypeConstructor()135     public void testOemSecurityTypeConstructor() {
136         OemSecurityType securityType = new OemSecurityType(
137                 ScanResult.PROTOCOL_WPA,
138                 Arrays.asList(ScanResult.KEY_MGMT_PSK, ScanResult.KEY_MGMT_SAE),
139                 Arrays.asList(ScanResult.CIPHER_NONE, ScanResult.CIPHER_TKIP),
140                 ScanResult.CIPHER_CCMP);
141 
142         assertThat(securityType.protocol).isEqualTo(ScanResult.PROTOCOL_WPA);
143         assertThat(securityType.keyManagement)
144                 .isEqualTo(Arrays.asList(ScanResult.KEY_MGMT_PSK, ScanResult.KEY_MGMT_SAE));
145         assertThat(securityType.pairwiseCipher)
146                 .isEqualTo(Arrays.asList(ScanResult.CIPHER_NONE, ScanResult.CIPHER_TKIP));
147         assertThat(securityType.groupCipher).isEqualTo(ScanResult.CIPHER_CCMP);
148     }
149 
150     @Test
testSendMgmtFrame()151     public void testSendMgmtFrame() {
152         try {
153             WifiNl80211Manager manager = mContext.getSystemService(WifiNl80211Manager.class);
154             manager.sendMgmtFrame("wlan0", new byte[]{}, -1, Runnable::run,
155                     new WifiNl80211Manager.SendMgmtFrameCallback() {
156                         @Override
157                         public void onAck(int elapsedTimeMs) {}
158 
159                         @Override
160                         public void onFailure(int reason) {}
161                     });
162         } catch (Exception ignore) {}
163     }
164 
165     @Test
testGetTxPacketCounters()166     public void testGetTxPacketCounters() {
167         try {
168             WifiNl80211Manager manager = mContext.getSystemService(WifiNl80211Manager.class);
169             manager.getTxPacketCounters("wlan0");
170         } catch (Exception ignore) {}
171     }
172 
173     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
174     @Test
testGetMaxSsidsPerScan()175     public void testGetMaxSsidsPerScan() {
176         try {
177             WifiNl80211Manager manager = mContext.getSystemService(WifiNl80211Manager.class);
178             manager.getMaxSsidsPerScan("wlan0");
179         } catch (Exception ignore) { }
180     }
181 
182     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
183     @Test
testStartScan2()184     public void testStartScan2() {
185         try {
186             WifiNl80211Manager manager = mContext.getSystemService(WifiNl80211Manager.class);
187             manager.startScan2("wlan0", WifiScanner.SCAN_TYPE_HIGH_ACCURACY,
188                     null, null, null);
189         } catch (Exception ignore) { }
190     }
191 
192     @Test
testSetOnServiceDeadCallback()193     public void testSetOnServiceDeadCallback() {
194         try {
195             WifiNl80211Manager manager = mContext.getSystemService(WifiNl80211Manager.class);
196             manager.setOnServiceDeadCallback(() -> {});
197         } catch (Exception ignore) {}
198     }
199 
200     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.S)
201     @Test
testCountryCodeChangeListener()202     public void testCountryCodeChangeListener() {
203         TestCountryCodeChangeListener testCountryCodeChangeListener =
204                 new TestCountryCodeChangeListener();
205         TestExecutor executor = new TestExecutor();
206         WifiManager wifiManager = mContext.getSystemService(WifiManager.class);
207         // Enable wifi to trigger country code change
208         wifiManager.setWifiEnabled(true);
209         WifiNl80211Manager manager = mContext.getSystemService(WifiNl80211Manager.class);
210         // Register listener and unregister listener for API coverage only.
211         // Since current cts don't have sufficient permission to call WifiNl80211Manager API.
212         // Assert register fail because the CTS don't have sufficient permission to call
213         // WifiNl80211Manager API which is guarded by selinux.
214         assertFalse(manager.registerCountryCodeChangedListener(executor,
215                 testCountryCodeChangeListener));
216         manager.unregisterCountryCodeChangedListener(testCountryCodeChangeListener);
217     }
218 
219     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
220     @Test
testNotifyCountryCodeChanged()221     public void testNotifyCountryCodeChanged() {
222         WifiNl80211Manager manager = mContext.getSystemService(WifiNl80211Manager.class);
223         // Assert fail because the CTS don't have sufficient permission to call
224         // WifiNl80211Manager API which is guarded by selinux.
225         try {
226             manager.notifyCountryCodeChanged("US");
227             fail("notifyCountryCodeChanged doesn't throws RuntimeException");
228         } catch (RuntimeException re) {
229         }
230     }
231 
232     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
233     @Test
testWifiNl80211ManagerConstructor()234     public void testWifiNl80211ManagerConstructor() {
235         IBinder testBinder = new Binder();
236         WifiNl80211Manager manager = new WifiNl80211Manager(mContext, testBinder);
237         assertNotNull(manager);
238     }
239 
240     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
241     @Test
testScanEventCallback()242     public void testScanEventCallback() {
243         try {
244             WifiNl80211Manager manager = mContext.getSystemService(WifiNl80211Manager.class);
245             manager.setupInterfaceForClientMode("wlan0", Runnable::run,
246                     new NormalScanEventCallback("wlan0"),
247                     new PnoScanEventCallback("wlan0"));
248         } catch (Exception ignore) { }
249     }
250 }
251