Home | History | Annotate | Download | only in wifi
      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 org.junit.Assert.assertEquals;
     20 import static org.junit.Assert.assertNotNull;
     21 import static org.junit.Assert.assertNull;
     22 import static org.mockito.Mockito.anyInt;
     23 import static org.mockito.Mockito.when;
     24 
     25 import android.app.test.MockAnswerUtil.AnswerWithArguments;
     26 import android.content.pm.UserInfo;
     27 import android.net.wifi.ScanResult;
     28 import android.net.wifi.WifiConfiguration;
     29 import android.os.UserHandle;
     30 import android.os.UserManager;
     31 import android.support.test.filters.SmallTest;
     32 import android.util.SparseArray;
     33 
     34 import org.junit.Before;
     35 import org.junit.Test;
     36 import org.mockito.Mock;
     37 import org.mockito.MockitoAnnotations;
     38 
     39 import java.util.ArrayList;
     40 import java.util.Arrays;
     41 import java.util.Collection;
     42 import java.util.HashSet;
     43 import java.util.List;
     44 import java.util.Set;
     45 
     46 /**
     47  * Unit tests for {@link com.android.server.wifi.ConfigurationMapTest}.
     48  */
     49 @SmallTest
     50 public class ConfigurationMapTest {
     51     private static final List<WifiConfiguration> CONFIGS = Arrays.asList(
     52             WifiConfigurationTestUtil.generateWifiConfig(
     53                     0, 1000000, "\"red\"", true, true, null, null),
     54             WifiConfigurationTestUtil.generateWifiConfig(
     55                     1, 1000001, "\"green\"", true, false, "example.com", "Green"),
     56             WifiConfigurationTestUtil.generateWifiConfig(
     57                     2, 1200000, "\"blue\"", false, true, null, null),
     58             WifiConfigurationTestUtil.generateWifiConfig(
     59                     3, 1100000, "\"cyan\"", true, true, null, null),
     60             WifiConfigurationTestUtil.generateWifiConfig(
     61                     4, 1100001, "\"yellow\"", true, true, "example.org", "Yellow"),
     62             WifiConfigurationTestUtil.generateWifiConfig(
     63                     5, 1100002, "\"magenta\"", false, false, null, null));
     64 
     65     private static final SparseArray<List<UserInfo>> USER_PROFILES = new SparseArray<>();
     66     static {
     67         USER_PROFILES.put(UserHandle.USER_SYSTEM, Arrays.asList(
     68                 new UserInfo(UserHandle.USER_SYSTEM, "Owner", 0),
     69                 new UserInfo(12, "Managed Profile", 0)));
     70         USER_PROFILES.put(10, Arrays.asList(new UserInfo(10, "Alice", 0)));
     71         USER_PROFILES.put(11, Arrays.asList(new UserInfo(11, "Bob", 0)));
     72     }
     73 
     74     @Mock UserManager mUserManager;
     75 
     76     private int mCurrentUserId = UserHandle.USER_SYSTEM;
     77     private ConfigurationMap mConfigs;
     78 
     79     /**
     80      * Sets up the test harness before running a test.
     81      */
     82     @Before
     83     public void setUp() {
     84         MockitoAnnotations.initMocks(this);
     85 
     86         when(mUserManager.getProfiles(anyInt()))
     87                 .then(new AnswerWithArguments() {
     88                     public List<UserInfo> answer(int userId) {
     89                         return USER_PROFILES.get(userId);
     90                     }
     91                 });
     92         mConfigs = new ConfigurationMap(mUserManager);
     93     }
     94 
     95     private void switchUser(int newUserId) {
     96         mCurrentUserId = newUserId;
     97         mConfigs.setNewUser(newUserId);
     98         mConfigs.clear();
     99     }
    100 
    101     private Collection<WifiConfiguration> getEnabledNetworksForCurrentUser() {
    102         List<WifiConfiguration> list = new ArrayList<>();
    103         for (WifiConfiguration config : mConfigs.valuesForCurrentUser()) {
    104             if (config.status != WifiConfiguration.Status.DISABLED) {
    105                 list.add(config);
    106             }
    107         }
    108         return list;
    109     }
    110 
    111     private WifiConfiguration getEphemeralForCurrentUser(String ssid) {
    112         for (WifiConfiguration config : mConfigs.valuesForCurrentUser()) {
    113             if (ssid.equals(config.SSID) && config.ephemeral) {
    114                 return config;
    115             }
    116         }
    117         return null;
    118     }
    119 
    120     private void addNetworks(List<WifiConfiguration> configs) {
    121         for (WifiConfiguration config : configs) {
    122             assertNull(mConfigs.put(config));
    123         }
    124     }
    125 
    126     private void verifyGetters(List<WifiConfiguration> configs) {
    127         final Set<WifiConfiguration> configsForCurrentUser = new HashSet<>();
    128         final Set<WifiConfiguration> enabledConfigsForCurrentUser = new HashSet<>();
    129         final List<WifiConfiguration> configsNotForCurrentUser = new ArrayList<>();
    130 
    131         // Find out which network configurations should be / should not be visible to the current
    132         // user. Also, check that *ForAllUsers() methods can be used to access all network
    133         // configurations, irrespective of their visibility to the current user.
    134         for (WifiConfiguration config : configs) {
    135             if (WifiConfigurationUtil.isVisibleToAnyProfile(config,
    136                     USER_PROFILES.get(mCurrentUserId))) {
    137                 configsForCurrentUser.add(config);
    138                 if (config.status != WifiConfiguration.Status.DISABLED) {
    139                     enabledConfigsForCurrentUser.add(config);
    140                 }
    141             } else {
    142                 configsNotForCurrentUser.add(config);
    143             }
    144 
    145             assertEquals(config, mConfigs.getForAllUsers(config.networkId));
    146         }
    147 
    148         // Verify that *ForCurrentUser() methods can be used to access network configurations
    149         // visible to the current user.
    150         for (WifiConfiguration config : configsForCurrentUser) {
    151             assertEquals(config, mConfigs.getForCurrentUser(config.networkId));
    152             assertEquals(config, mConfigs.getByConfigKeyForCurrentUser(config.configKey()));
    153             final boolean wasEphemeral = config.ephemeral;
    154             config.ephemeral = false;
    155             assertNull(getEphemeralForCurrentUser(config.SSID));
    156             config.ephemeral = true;
    157             assertEquals(config, getEphemeralForCurrentUser(config.SSID));
    158             config.ephemeral = wasEphemeral;
    159         }
    160 
    161         // Verify that *ForCurrentUser() methods cannot be used to access network configurations not
    162         // visible to the current user.
    163         for (WifiConfiguration config : configsNotForCurrentUser) {
    164             assertNull(mConfigs.getForCurrentUser(config.networkId));
    165             assertNull(mConfigs.getByConfigKeyForCurrentUser(config.configKey()));
    166             final boolean wasEphemeral = config.ephemeral;
    167             config.ephemeral = false;
    168             assertNull(getEphemeralForCurrentUser(config.SSID));
    169             config.ephemeral = true;
    170             assertNull(getEphemeralForCurrentUser(config.SSID));
    171             config.ephemeral = wasEphemeral;
    172         }
    173 
    174         // Verify that the methods which refer to more than one network configuration return the
    175         // correct sets of networks.
    176         assertEquals(configs.size(), mConfigs.sizeForAllUsers());
    177         assertEquals(configsForCurrentUser.size(), mConfigs.sizeForCurrentUser());
    178         assertEquals(enabledConfigsForCurrentUser,
    179                 new HashSet<WifiConfiguration>(getEnabledNetworksForCurrentUser()));
    180         assertEquals(new HashSet<>(configs),
    181                 new HashSet<WifiConfiguration>(mConfigs.valuesForAllUsers()));
    182     }
    183 
    184     private ScanResult createScanResultForNetwork(WifiConfiguration config) {
    185         return WifiConfigurationTestUtil.createScanDetailForNetwork(config, "", 0, 0, 0, 0)
    186                 .getScanResult();
    187     }
    188 
    189     /**
    190      * Helper function to create a scan result matching the network and ensuring that
    191      * {@link ConfigurationMap#getByScanResultForCurrentUser(ScanResult)} can match that network.
    192      */
    193     private void verifyScanResultMatchWithNetwork(WifiConfiguration config) {
    194         mConfigs.put(config);
    195         ScanResult scanResult = createScanResultForNetwork(config);
    196         WifiConfiguration retrievedConfig =
    197                 mConfigs.getByScanResultForCurrentUser(scanResult);
    198         assertNotNull(retrievedConfig);
    199         assertEquals(config.configKey(), retrievedConfig.configKey());
    200     }
    201 
    202     /**
    203      * Verifies that all getters return the correct network configurations, taking into account the
    204      * current user. Also verifies that handleUserSwitch() returns the list of network
    205      * configurations that are no longer visible.
    206      */
    207     @Test
    208     public void testGettersAndHandleUserSwitch() {
    209         addNetworks(CONFIGS);
    210         verifyGetters(CONFIGS);
    211 
    212         switchUser(10);
    213         addNetworks(CONFIGS);
    214         verifyGetters(CONFIGS);
    215 
    216         switchUser(11);
    217         addNetworks(CONFIGS);
    218         verifyGetters(CONFIGS);
    219     }
    220 
    221     /**
    222      * Verifies put(), remove() and clear().
    223      */
    224     @Test
    225     public void testPutRemoveClear() {
    226         final List<WifiConfiguration> configs = new ArrayList<>();
    227         final WifiConfiguration config1 = CONFIGS.get(0);
    228 
    229         // Verify that there are no network configurations to start with.
    230         switchUser(UserHandle.getUserId(config1.creatorUid));
    231         verifyGetters(configs);
    232 
    233         // Add |config1|.
    234         assertNull(mConfigs.put(config1));
    235         // Verify that the getters return |config1|.
    236         configs.add(config1);
    237         verifyGetters(configs);
    238 
    239         // Overwrite |config1| with |config2|.
    240         final WifiConfiguration config2 = CONFIGS.get(1);
    241         config2.networkId = config1.networkId;
    242         assertEquals(config1, mConfigs.put(config2));
    243         // Verify that the getters return |config2| only.
    244         configs.clear();
    245         configs.add(config2);
    246         verifyGetters(configs);
    247 
    248         // Add |config3|, which belongs to a managed profile of the current user.
    249         final WifiConfiguration config3 = CONFIGS.get(2);
    250         assertNull(mConfigs.put(config3));
    251         // Verify that the getters return |config2| and |config3|.
    252         configs.add(config3);
    253         verifyGetters(configs);
    254 
    255         // Remove |config2|.
    256         assertEquals(config2, mConfigs.remove(config2.networkId));
    257         // Verify that the getters return |config3| only.
    258         configs.remove(config2);
    259         verifyGetters(configs);
    260 
    261         // Clear all network configurations.
    262         mConfigs.clear();
    263         // Verify that the getters do not return any network configurations.
    264         configs.clear();
    265         verifyGetters(configs);
    266     }
    267 
    268     /**
    269      * Verifies that {@link ConfigurationMap#getByScanResultForCurrentUser(ScanResult)} can
    270      * positively match the corresponding networks.
    271      */
    272     @Test
    273     public void testScanResultDoesMatchCorrespondingNetworks() {
    274         verifyScanResultMatchWithNetwork(WifiConfigurationTestUtil.createOpenNetwork());
    275         verifyScanResultMatchWithNetwork(WifiConfigurationTestUtil.createPskNetwork());
    276         verifyScanResultMatchWithNetwork(WifiConfigurationTestUtil.createWepNetwork());
    277         verifyScanResultMatchWithNetwork(WifiConfigurationTestUtil.createEapNetwork());
    278     }
    279 
    280     /**
    281      * Verifies that {@link ConfigurationMap#getByScanResultForCurrentUser(ScanResult)} does not
    282      * match other networks.
    283      */
    284     @Test
    285     public void testScanResultDoesNotMatchWithOtherNetworks() {
    286         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
    287         ScanResult scanResult = createScanResultForNetwork(config);
    288         // Change the network security type and the old scan result should not match now.
    289         config.allowedKeyManagement.clear();
    290         config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
    291         mConfigs.put(config);
    292         assertNull(mConfigs.getByScanResultForCurrentUser(scanResult));
    293     }
    294 
    295     /**
    296      * Verifies that {@link ConfigurationMap#getByScanResultForCurrentUser(ScanResult)} does not
    297      * match networks which have been removed.
    298      */
    299     @Test
    300     public void testScanResultDoesNotMatchAfterNetworkRemove() {
    301         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
    302         ScanResult scanResult = createScanResultForNetwork(config);
    303         config.networkId = 5;
    304         mConfigs.put(config);
    305         // Create another network in the map.
    306         mConfigs.put(WifiConfigurationTestUtil.createPskNetwork());
    307         assertNotNull(mConfigs.getByScanResultForCurrentUser(scanResult));
    308 
    309         mConfigs.remove(config.networkId);
    310         assertNull(mConfigs.getByScanResultForCurrentUser(scanResult));
    311     }
    312 
    313     /**
    314      * Verifies that {@link ConfigurationMap#getByScanResultForCurrentUser(ScanResult)} does not
    315      * match networks after clear.
    316      */
    317     @Test
    318     public void testScanResultDoesNotMatchAfterClear() {
    319         WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork();
    320         ScanResult scanResult = createScanResultForNetwork(config);
    321         config.networkId = 5;
    322         mConfigs.put(config);
    323         // Create another network in the map.
    324         mConfigs.put(WifiConfigurationTestUtil.createPskNetwork());
    325         assertNotNull(mConfigs.getByScanResultForCurrentUser(scanResult));
    326 
    327         mConfigs.clear();
    328         assertNull(mConfigs.getByScanResultForCurrentUser(scanResult));
    329     }
    330 }
    331