• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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 com.android.server.wifi;
18 
19 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
20 import static com.android.server.wifi.TestUtil.createCapabilityBitset;
21 
22 import static org.junit.Assert.assertEquals;
23 import static org.junit.Assert.assertNotNull;
24 import static org.junit.Assert.assertNull;
25 import static org.mockito.Mockito.anyInt;
26 import static org.mockito.Mockito.lenient;
27 import static org.mockito.Mockito.when;
28 
29 import android.content.pm.UserInfo;
30 import android.net.wifi.ScanResult;
31 import android.net.wifi.WifiConfiguration;
32 import android.net.wifi.WifiManager;
33 import android.os.UserHandle;
34 import android.util.SparseArray;
35 
36 import androidx.test.filters.SmallTest;
37 
38 import com.android.server.wifi.util.WifiPermissionsUtil;
39 
40 import org.junit.After;
41 import org.junit.Before;
42 import org.junit.Test;
43 import org.mockito.Mock;
44 import org.mockito.MockitoAnnotations;
45 import org.mockito.MockitoSession;
46 import org.mockito.stubbing.Answer;
47 
48 import java.util.ArrayList;
49 import java.util.Arrays;
50 import java.util.Collection;
51 import java.util.HashSet;
52 import java.util.List;
53 import java.util.Set;
54 
55 /**
56  * Unit tests for {@link com.android.server.wifi.ConfigurationMapTest}.
57  */
58 @SmallTest
59 public class ConfigurationMapTest extends WifiBaseTest {
60     private static final int SYSTEM_MANAGE_PROFILE_USER_ID = 12;
61     private static final String TEST_BSSID = "0a:08:5c:67:89:01";
62     private static final List<WifiConfiguration> CONFIGS = Arrays.asList(
63             WifiConfigurationTestUtil.generateWifiConfig(
64                     0, 1000000, "\"red\"", true, true, null, null,
65                     WifiConfigurationTestUtil.SECURITY_NONE),
66             WifiConfigurationTestUtil.generateWifiConfig(
67                     1, 1000001, "\"green\"", true, false, "example.com", "Green",
68                     WifiConfigurationTestUtil.SECURITY_NONE),
69             WifiConfigurationTestUtil.generateWifiConfig(
70                     2, 1200000, "\"blue\"", false, true, null, null,
71                     WifiConfigurationTestUtil.SECURITY_NONE),
72             WifiConfigurationTestUtil.generateWifiConfig(
73                     3, 1100000, "\"cyan\"", true, true, null, null,
74                     WifiConfigurationTestUtil.SECURITY_NONE),
75             WifiConfigurationTestUtil.generateWifiConfig(
76                     4, 1100001, "\"yellow\"", true, true, "example.org", "Yellow",
77                     WifiConfigurationTestUtil.SECURITY_NONE),
78             WifiConfigurationTestUtil.generateWifiConfig(
79                     5, 1100002, "\"magenta\"", false, false, null, null,
80                     WifiConfigurationTestUtil.SECURITY_NONE));
81 
82     private static final SparseArray<List<UserInfo>> USER_PROFILES = new SparseArray<>();
83     static {
USER_PROFILES.put(UserHandle.USER_SYSTEM, Arrays.asList( new UserInfo(UserHandle.USER_SYSTEM, "Owner", 0), new UserInfo(SYSTEM_MANAGE_PROFILE_USER_ID, "Managed Profile", 0)))84         USER_PROFILES.put(UserHandle.USER_SYSTEM, Arrays.asList(
85                 new UserInfo(UserHandle.USER_SYSTEM, "Owner", 0),
86                 new UserInfo(SYSTEM_MANAGE_PROFILE_USER_ID, "Managed Profile", 0)));
87         USER_PROFILES.put(10, Arrays.asList(new UserInfo(10, "Alice", 0)));
88         USER_PROFILES.put(11, Arrays.asList(new UserInfo(11, "Bob", 0)));
89     }
90 
91     @Mock WifiPermissionsUtil mWifiPermissionsUtil;
92     @Mock WifiInjector mWifiInjector;
93     @Mock ActiveModeWarden mActiveModeWarden;
94     @Mock ClientModeManager mPrimaryClientModeManager;
95     @Mock WifiGlobals mWifiGlobals;
96     private MockitoSession mStaticMockSession = null;
97 
98     private int mCurrentUserId = UserHandle.USER_SYSTEM;
99     private ConfigurationMap mConfigs;
100 
101     /**
102      * Sets up the test harness before running a test.
103      */
104     @Before
setUp()105     public void setUp() {
106         MockitoAnnotations.initMocks(this);
107         mStaticMockSession = mockitoSession()
108                 .mockStatic(WifiInjector.class)
109                 .startMocking();
110         lenient().when(WifiInjector.getInstance()).thenReturn(mWifiInjector);
111         when(mWifiInjector.getActiveModeWarden()).thenReturn(mActiveModeWarden);
112         when(mWifiInjector.getWifiGlobals()).thenReturn(mWifiGlobals);
113         when(mActiveModeWarden.getPrimaryClientModeManager()).thenReturn(mPrimaryClientModeManager);
114         when(mPrimaryClientModeManager.getSupportedFeaturesBitSet()).thenReturn(
115                 createCapabilityBitset(
116                         WifiManager.WIFI_FEATURE_WPA3_SAE, WifiManager.WIFI_FEATURE_OWE));
117         when(mWifiGlobals.isWpa3SaeUpgradeEnabled()).thenReturn(true);
118         when(mWifiGlobals.isOweUpgradeEnabled()).thenReturn(true);
119 
120         when(mWifiPermissionsUtil.doesUidBelongToCurrentUserOrDeviceOwner(anyInt()))
121                 .thenAnswer((Answer<Boolean>) invocation -> {
122                     Object[] args = invocation.getArguments();
123                     int userId = UserHandle.getUserId((int) args[0]);
124                     // Current userId matches input userId
125                     if (userId == mCurrentUserId) {
126                         return true;
127                     }
128                     // Current userId and input userId belong to the same profile group
129                     if (userId == UserHandle.USER_SYSTEM
130                             && mCurrentUserId == SYSTEM_MANAGE_PROFILE_USER_ID) {
131                         return true;
132                     }
133                     if (userId == SYSTEM_MANAGE_PROFILE_USER_ID
134                             && mCurrentUserId == UserHandle.USER_SYSTEM) {
135                         return true;
136                     }
137                     return false;
138                 });
139         mConfigs = new ConfigurationMap(mWifiPermissionsUtil);
140     }
141 
142     @After
cleanUp()143     public void cleanUp() throws Exception {
144         if (null != mStaticMockSession) {
145             mStaticMockSession.finishMocking();
146         }
147     }
148 
switchUser(int newUserId)149     private void switchUser(int newUserId) {
150         mCurrentUserId = newUserId;
151         mConfigs.setNewUser(newUserId);
152         mConfigs.clear();
153     }
154 
getEnabledNetworksForCurrentUser()155     private Collection<WifiConfiguration> getEnabledNetworksForCurrentUser() {
156         List<WifiConfiguration> list = new ArrayList<>();
157         for (WifiConfiguration config : mConfigs.valuesForCurrentUser()) {
158             if (config.status != WifiConfiguration.Status.DISABLED) {
159                 list.add(config);
160             }
161         }
162         return list;
163     }
164 
getEphemeralForCurrentUser(String ssid)165     private WifiConfiguration getEphemeralForCurrentUser(String ssid) {
166         for (WifiConfiguration config : mConfigs.valuesForCurrentUser()) {
167             if (ssid.equals(config.SSID) && config.ephemeral) {
168                 return config;
169             }
170         }
171         return null;
172     }
173 
addNetworks(List<WifiConfiguration> configs)174     private void addNetworks(List<WifiConfiguration> configs) {
175         for (WifiConfiguration config : configs) {
176             assertNull(mConfigs.put(config));
177         }
178     }
179 
verifyGetters(List<WifiConfiguration> configs)180     private void verifyGetters(List<WifiConfiguration> configs) {
181         final Set<WifiConfiguration> configsForCurrentUser = new HashSet<>();
182         final Set<WifiConfiguration> enabledConfigsForCurrentUser = new HashSet<>();
183         final List<WifiConfiguration> configsNotForCurrentUser = new ArrayList<>();
184 
185         // Find out which network configurations should be / should not be visible to the current
186         // user. Also, check that *ForAllUsers() methods can be used to access all network
187         // configurations, irrespective of their visibility to the current user.
188         for (WifiConfiguration config : configs) {
189             if (config.shared || mWifiPermissionsUtil
190                     .doesUidBelongToCurrentUserOrDeviceOwner(config.creatorUid)) {
191                 configsForCurrentUser.add(config);
192                 if (config.status != WifiConfiguration.Status.DISABLED) {
193                     enabledConfigsForCurrentUser.add(config);
194                 }
195             } else {
196                 configsNotForCurrentUser.add(config);
197             }
198 
199             assertEquals(config, mConfigs.getForAllUsers(config.networkId));
200         }
201 
202         // Verify that *ForCurrentUser() methods can be used to access network configurations
203         // visible to the current user.
204         for (WifiConfiguration config : configsForCurrentUser) {
205             assertEquals(config, mConfigs.getForCurrentUser(config.networkId));
206             assertEquals(config, mConfigs.getByConfigKeyForCurrentUser(
207                     config.getProfileKey()));
208             final boolean wasEphemeral = config.ephemeral;
209             config.ephemeral = false;
210             assertNull(getEphemeralForCurrentUser(config.SSID));
211             config.ephemeral = true;
212             assertEquals(config, getEphemeralForCurrentUser(config.SSID));
213             config.ephemeral = wasEphemeral;
214         }
215 
216         // Verify that *ForCurrentUser() methods cannot be used to access network configurations not
217         // visible to the current user.
218         for (WifiConfiguration config : configsNotForCurrentUser) {
219             assertNull(mConfigs.getForCurrentUser(config.networkId));
220             assertNull(mConfigs.getByConfigKeyForCurrentUser(config.getProfileKey()));
221             final boolean wasEphemeral = config.ephemeral;
222             config.ephemeral = false;
223             assertNull(getEphemeralForCurrentUser(config.SSID));
224             config.ephemeral = true;
225             assertNull(getEphemeralForCurrentUser(config.SSID));
226             config.ephemeral = wasEphemeral;
227         }
228 
229         // Verify that the methods which refer to more than one network configuration return the
230         // correct sets of networks.
231         assertEquals(configs.size(), mConfigs.sizeForAllUsers());
232         assertEquals(configsForCurrentUser.size(), mConfigs.sizeForCurrentUser());
233         assertEquals(enabledConfigsForCurrentUser,
234                 new HashSet<WifiConfiguration>(getEnabledNetworksForCurrentUser()));
235         assertEquals(new HashSet<>(configs),
236                 new HashSet<WifiConfiguration>(mConfigs.valuesForAllUsers()));
237     }
238 
createScanResultForNetwork(WifiConfiguration config)239     private ScanResult createScanResultForNetwork(WifiConfiguration config) {
240         return WifiConfigurationTestUtil.createScanDetailForNetwork(config, TEST_BSSID, 0, 0, 0, 0)
241                 .getScanResult();
242     }
243 
244     /**
245      * Helper function to create a scan result matching the network and ensuring that
246      * {@link ConfigurationMap#getByScanResultForCurrentUser(ScanResult)} can match that network.
247      */
verifyScanResultMatchWithNetwork(WifiConfiguration config)248     private void verifyScanResultMatchWithNetwork(WifiConfiguration config) {
249         mConfigs.put(config);
250         ScanResult scanResult = createScanResultForNetwork(config);
251         WifiConfiguration retrievedConfig =
252                 mConfigs.getByScanResultForCurrentUser(scanResult);
253         assertNotNull(retrievedConfig);
254         assertEquals(config.getProfileKey(), retrievedConfig.getProfileKey());
255     }
256 
257     /**
258      * Verifies that all getters return the correct network configurations, taking into account the
259      * current user. Also verifies that handleUserSwitch() returns the list of network
260      * configurations that are no longer visible.
261      */
262     @Test
testGettersAndHandleUserSwitch()263     public void testGettersAndHandleUserSwitch() {
264         addNetworks(CONFIGS);
265         verifyGetters(CONFIGS);
266 
267         switchUser(10);
268         addNetworks(CONFIGS);
269         verifyGetters(CONFIGS);
270 
271         switchUser(11);
272         addNetworks(CONFIGS);
273         verifyGetters(CONFIGS);
274     }
275 
276     /**
277      * Verifies put(), remove() and clear().
278      */
279     @Test
testPutRemoveClear()280     public void testPutRemoveClear() {
281         final List<WifiConfiguration> configs = new ArrayList<>();
282         final WifiConfiguration config1 = CONFIGS.get(0);
283 
284         // Verify that there are no network configurations to start with.
285         switchUser(UserHandle.getUserHandleForUid(config1.creatorUid).getIdentifier());
286         verifyGetters(configs);
287 
288         // Add |config1|.
289         assertNull(mConfigs.put(config1));
290         // Verify that the getters return |config1|.
291         configs.add(config1);
292         verifyGetters(configs);
293 
294         // Overwrite |config1| with |config2|.
295         final WifiConfiguration config2 = CONFIGS.get(1);
296         config2.networkId = config1.networkId;
297         assertEquals(config1, mConfigs.put(config2));
298         // Verify that the getters return |config2| only.
299         configs.clear();
300         configs.add(config2);
301         verifyGetters(configs);
302 
303         // Add |config3|, which belongs to a managed profile of the current user.
304         final WifiConfiguration config3 = CONFIGS.get(2);
305         assertNull(mConfigs.put(config3));
306         // Verify that the getters return |config2| and |config3|.
307         configs.add(config3);
308         verifyGetters(configs);
309 
310         // Remove |config2|.
311         assertEquals(config2, mConfigs.remove(config2.networkId));
312         // Verify that the getters return |config3| only.
313         configs.remove(config2);
314         verifyGetters(configs);
315 
316         // Clear all network configurations.
317         mConfigs.clear();
318         // Verify that the getters do not return any network configurations.
319         configs.clear();
320         verifyGetters(configs);
321     }
322 
323     /**
324      * Verifies that {@link ConfigurationMap#getByScanResultForCurrentUser(ScanResult)} can
325      * positively match the corresponding networks.
326      */
327     @Test
testScanResultDoesMatchCorrespondingNetworks()328     public void testScanResultDoesMatchCorrespondingNetworks() {
329         verifyScanResultMatchWithNetwork(WifiConfigurationTestUtil.createOpenNetwork());
330         verifyScanResultMatchWithNetwork(WifiConfigurationTestUtil.createPskNetwork());
331         verifyScanResultMatchWithNetwork(WifiConfigurationTestUtil.createWepNetwork());
332         verifyScanResultMatchWithNetwork(WifiConfigurationTestUtil.createEapNetwork());
333     }
334 
335     /**
336      * Verifies that {@link ConfigurationMap#getByScanResultForCurrentUser(ScanResult)} does not
337      * match other networks.
338      */
339     @Test
testScanResultDoesNotMatchWithOtherNetworks()340     public void testScanResultDoesNotMatchWithOtherNetworks() {
341         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
342         ScanResult scanResult = createScanResultForNetwork(config);
343         // Change the network security type and the old scan result should not match now.
344         config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK);
345         mConfigs.put(config);
346         assertNull(mConfigs.getByScanResultForCurrentUser(scanResult));
347     }
348 
349     /**
350      * Verifies that {@link ConfigurationMap#getByScanResultForCurrentUser(ScanResult)} does not
351      * match networks which have been removed.
352      */
353     @Test
testScanResultDoesNotMatchAfterNetworkRemove()354     public void testScanResultDoesNotMatchAfterNetworkRemove() {
355         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
356         ScanResult scanResult = createScanResultForNetwork(config);
357         config.networkId = 5;
358         mConfigs.put(config);
359         // Create another network in the map.
360         mConfigs.put(WifiConfigurationTestUtil.createPskNetwork());
361         assertNotNull(mConfigs.getByScanResultForCurrentUser(scanResult));
362 
363         mConfigs.remove(config.networkId);
364         assertNull(mConfigs.getByScanResultForCurrentUser(scanResult));
365     }
366 
367     /**
368      * Verifies that {@link ConfigurationMap#getByScanResultForCurrentUser(ScanResult)} does not
369      * match networks after clear.
370      */
371     @Test
testScanResultDoesNotMatchAfterClear()372     public void testScanResultDoesNotMatchAfterClear() {
373         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
374         ScanResult scanResult = createScanResultForNetwork(config);
375         config.networkId = 5;
376         mConfigs.put(config);
377         // Create another network in the map.
378         mConfigs.put(WifiConfigurationTestUtil.createPskNetwork());
379         assertNotNull(mConfigs.getByScanResultForCurrentUser(scanResult));
380 
381         mConfigs.clear();
382         assertNull(mConfigs.getByScanResultForCurrentUser(scanResult));
383     }
384 
385     @Test
testScanResultDoesNotMatchForWifiNetworkSpecifier()386     public void testScanResultDoesNotMatchForWifiNetworkSpecifier() {
387         // Add regular saved network, this should create a scan result match info cache entry.
388         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
389         ScanResult scanResult = createScanResultForNetwork(config);
390         config.networkId = 5;
391         mConfigs.put(config);
392         assertNotNull(mConfigs.getByScanResultForCurrentUser(scanResult));
393 
394         mConfigs.clear();
395 
396         // Create WifiNetworkSpecifier network, this should not create a scan result match info
397         // cache entry.
398         config.ephemeral = true;
399         config.fromWifiNetworkSpecifier = true;
400         mConfigs.put(config);
401         assertNull(mConfigs.getByScanResultForCurrentUser(scanResult));
402     }
403 
404     @Test
testScanResultDoesNotMatchForWifiNetworkSuggestion()405     public void testScanResultDoesNotMatchForWifiNetworkSuggestion() {
406         // Add regular saved network, this should create a scan result match info cache entry.
407         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
408         ScanResult scanResult = createScanResultForNetwork(config);
409         config.networkId = 5;
410         mConfigs.put(config);
411         assertNotNull(mConfigs.getByScanResultForCurrentUser(scanResult));
412 
413         mConfigs.clear();
414 
415         // Create WifiNetworkSuggestion network, this should not create a scan result match info
416         // cache entry.
417         config.ephemeral = true;
418         config.fromWifiNetworkSuggestion = true;
419         mConfigs.put(config);
420         assertNull(mConfigs.getByScanResultForCurrentUser(scanResult));
421     }
422 
423     @Test
testScanResultDoesNotMatchForPasspoint()424     public void testScanResultDoesNotMatchForPasspoint() {
425         // Add passpoint network, this should not create a scan result match info cache entry.
426         WifiConfiguration config = WifiConfigurationTestUtil.createPasspointNetwork();
427         ScanResult scanResult = createScanResultForNetwork(config);
428         config.networkId = 5;
429         mConfigs.put(config);
430         assertNull(mConfigs.getByScanResultForCurrentUser(scanResult));
431     }
432 }
433