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