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
17package com.android.server.wifi;
18
19import static org.junit.Assert.assertEquals;
20import static org.junit.Assert.assertNull;
21import static org.mockito.Mockito.anyInt;
22import static org.mockito.Mockito.when;
23
24import android.content.pm.UserInfo;
25import android.net.wifi.WifiConfiguration;
26import android.os.UserHandle;
27import android.os.UserManager;
28import android.test.suitebuilder.annotation.SmallTest;
29import android.util.SparseArray;
30
31import com.android.server.wifi.MockAnswerUtil.AnswerWithArguments;
32
33import org.junit.Before;
34import org.junit.Test;
35import org.mockito.Mock;
36import org.mockito.MockitoAnnotations;
37
38import java.util.ArrayList;
39import java.util.Arrays;
40import java.util.HashSet;
41import java.util.List;
42import java.util.Set;
43
44/**
45 * Unit tests for {@link com.android.server.wifi.ConfigurationMapTest}.
46 */
47@SmallTest
48public class ConfigurationMapTest {
49    private static final List<WifiConfiguration> CONFIGS = Arrays.asList(
50            WifiConfigurationTestUtil.generateWifiConfig(
51                    0, 1000000, "\"red\"", true, true, null, null),
52            WifiConfigurationTestUtil.generateWifiConfig(
53                    1, 1000001, "\"green\"", true, false, "example.com", "Green"),
54            WifiConfigurationTestUtil.generateWifiConfig(
55                    2, 1200000, "\"blue\"", false, true, null, null),
56            WifiConfigurationTestUtil.generateWifiConfig(
57                    3, 1100000, "\"cyan\"", true, true, null, null),
58            WifiConfigurationTestUtil.generateWifiConfig(
59                    4, 1100001, "\"yellow\"", true, true, "example.org", "Yellow"),
60            WifiConfigurationTestUtil.generateWifiConfig(
61                    5, 1100002, "\"magenta\"", false, false, null, null));
62
63    private static final SparseArray<List<UserInfo>> USER_PROFILES = new SparseArray<>();
64    static {
65        USER_PROFILES.put(UserHandle.USER_SYSTEM, Arrays.asList(
66                new UserInfo(UserHandle.USER_SYSTEM, "Owner", 0),
67                new UserInfo(12, "Managed Profile", 0)));
68        USER_PROFILES.put(10, Arrays.asList(new UserInfo(10, "Alice", 0)));
69        USER_PROFILES.put(11, Arrays.asList(new UserInfo(11, "Bob", 0)));
70    }
71
72    @Mock UserManager mUserManager;
73
74    private int mCurrentUserId = UserHandle.USER_SYSTEM;
75    private ConfigurationMap mConfigs;
76
77    /**
78     * Sets up the test harness before running a test.
79     */
80    @Before
81    public void setUp() {
82        MockitoAnnotations.initMocks(this);
83
84        when(mUserManager.getProfiles(anyInt()))
85                .then(new AnswerWithArguments() {
86                    public List<UserInfo> answer(int userId) {
87                        return USER_PROFILES.get(userId);
88                    }
89                });
90        mConfigs = new ConfigurationMap(mUserManager);
91    }
92
93    public void switchUser(int newUserId) {
94        Set<WifiConfiguration> hiddenConfigurations = new HashSet<>();
95        for (WifiConfiguration config : mConfigs.valuesForAllUsers()) {
96            if (WifiConfigurationUtil.isVisibleToAnyProfile(config,
97                    USER_PROFILES.get(mCurrentUserId))
98                    && !WifiConfigurationUtil.isVisibleToAnyProfile(config,
99                            USER_PROFILES.get(newUserId))) {
100                hiddenConfigurations.add(config);
101            }
102        }
103
104        mCurrentUserId = newUserId;
105        assertEquals(hiddenConfigurations, new HashSet<>(mConfigs.handleUserSwitch(newUserId)));
106    }
107
108    public void verifyGetters(List<WifiConfiguration> configs) {
109        final Set<WifiConfiguration> configsForCurrentUser = new HashSet<>();
110        final Set<WifiConfiguration> enabledConfigsForCurrentUser = new HashSet<>();
111        final List<WifiConfiguration> configsNotForCurrentUser = new ArrayList<>();
112
113        // Find out which network configurations should be / should not be visible to the current
114        // user. Also, check that *ForAllUsers() methods can be used to access all network
115        // configurations, irrespective of their visibility to the current user.
116        for (WifiConfiguration config : configs) {
117            if (WifiConfigurationUtil.isVisibleToAnyProfile(config,
118                    USER_PROFILES.get(mCurrentUserId))) {
119                configsForCurrentUser.add(config);
120                if (config.status != WifiConfiguration.Status.DISABLED) {
121                    enabledConfigsForCurrentUser.add(config);
122                }
123            } else {
124                configsNotForCurrentUser.add(config);
125            }
126
127            assertEquals(config, mConfigs.getForAllUsers(config.networkId));
128            assertEquals(config,
129                    mConfigs.getByConfigKeyIDForAllUsers(config.configKey().hashCode()));
130        }
131
132        // Verify that *ForCurrentUser() methods can be used to access network configurations
133        // visible to the current user.
134        for (WifiConfiguration config : configsForCurrentUser) {
135            assertEquals(config, mConfigs.getForCurrentUser(config.networkId));
136            if (config.FQDN != null) {
137                assertEquals(config, mConfigs.getByFQDNForCurrentUser(config.FQDN));
138            }
139            assertEquals(config, mConfigs.getByConfigKeyForCurrentUser(config.configKey()));
140            final boolean wasEphemeral = config.ephemeral;
141            config.ephemeral = false;
142            assertNull(mConfigs.getEphemeralForCurrentUser(config.SSID));
143            config.ephemeral = true;
144            assertEquals(config, mConfigs.getEphemeralForCurrentUser(config.SSID));
145            config.ephemeral = wasEphemeral;
146        }
147
148        // Verify that *ForCurrentUser() methods cannot be used to access network configurations not
149        // visible to the current user.
150        for (WifiConfiguration config : configsNotForCurrentUser) {
151            assertNull(mConfigs.getForCurrentUser(config.networkId));
152            if (config.FQDN != null) {
153                assertNull(mConfigs.getByFQDNForCurrentUser(config.FQDN));
154            }
155            assertNull(mConfigs.getByConfigKeyForCurrentUser(config.configKey()));
156            final boolean wasEphemeral = config.ephemeral;
157            config.ephemeral = false;
158            assertNull(mConfigs.getEphemeralForCurrentUser(config.SSID));
159            config.ephemeral = true;
160            assertNull(mConfigs.getEphemeralForCurrentUser(config.SSID));
161            config.ephemeral = wasEphemeral;
162        }
163
164        // Verify that the methods which refer to more than one network configuration return the
165        // correct sets of networks.
166        assertEquals(configs.size(), mConfigs.sizeForAllUsers());
167        assertEquals(configsForCurrentUser.size(), mConfigs.sizeForCurrentUser());
168        assertEquals(enabledConfigsForCurrentUser,
169                new HashSet<WifiConfiguration>(mConfigs.getEnabledNetworksForCurrentUser()));
170        assertEquals(new HashSet<>(configs),
171                new HashSet<WifiConfiguration>(mConfigs.valuesForAllUsers()));
172    }
173
174    /**
175     * Verifies that all getters return the correct network configurations, taking into account the
176     * current user. Also verifies that handleUserSwitch() returns the list of network
177     * configurations that are no longer visible.
178     */
179    @Test
180    public void testGettersAndHandleUserSwitch() {
181        for (WifiConfiguration config : CONFIGS) {
182            assertNull(mConfigs.put(config));
183        }
184
185        verifyGetters(CONFIGS);
186
187        switchUser(10);
188        verifyGetters(CONFIGS);
189
190        switchUser(11);
191        verifyGetters(CONFIGS);
192    }
193
194    /**
195     * Verifies put(), remove() and clear().
196     */
197    @Test
198    public void testPutRemoveClear() {
199        final List<WifiConfiguration> configs = new ArrayList<>();
200        final WifiConfiguration config1 = CONFIGS.get(0);
201
202        // Verify that there are no network configurations to start with.
203        switchUser(UserHandle.getUserId(config1.creatorUid));
204        verifyGetters(configs);
205
206        // Add |config1|.
207        assertNull(mConfigs.put(config1));
208        // Verify that the getters return |config1|.
209        configs.add(config1);
210        verifyGetters(configs);
211
212        // Overwrite |config1| with |config2|.
213        final WifiConfiguration config2 = CONFIGS.get(1);
214        config2.networkId = config1.networkId;
215        assertEquals(config1, mConfigs.put(config2));
216        // Verify that the getters return |config2| only.
217        configs.clear();
218        configs.add(config2);
219        verifyGetters(configs);
220
221        // Add |config3|, which belongs to a managed profile of the current user.
222        final WifiConfiguration config3 = CONFIGS.get(2);
223        assertNull(mConfigs.put(config3));
224        // Verify that the getters return |config2| and |config3|.
225        configs.add(config3);
226        verifyGetters(configs);
227
228        // Remove |config2|.
229        assertEquals(config2, mConfigs.remove(config2.networkId));
230        // Verify that the getters return |config3| only.
231        configs.remove(config2);
232        verifyGetters(configs);
233
234        // Clear all network configurations.
235        mConfigs.clear();
236        // Verify that the getters do not return any network configurations.
237        configs.clear();
238        verifyGetters(configs);
239    }
240}
241