WifiConfigManagerTest.java revision 23ed63d91b8af8f1d3569371daedc4162e323cc0
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.*;
20import static org.mockito.Mockito.*;
21
22import android.app.admin.DeviceAdminInfo;
23import android.app.admin.DevicePolicyManagerInternal;
24import android.app.test.MockAnswerUtil.AnswerWithArguments;
25import android.content.Context;
26import android.content.Intent;
27import android.content.pm.ApplicationInfo;
28import android.content.pm.PackageManager;
29import android.content.pm.UserInfo;
30import android.net.IpConfiguration;
31import android.net.wifi.ScanResult;
32import android.net.wifi.WifiConfiguration;
33import android.net.wifi.WifiConfiguration.NetworkSelectionStatus;
34import android.net.wifi.WifiEnterpriseConfig;
35import android.net.wifi.WifiManager;
36import android.net.wifi.WifiScanner;
37import android.net.wifi.WifiSsid;
38import android.os.UserHandle;
39import android.os.UserManager;
40import android.telephony.TelephonyManager;
41import android.test.suitebuilder.annotation.SmallTest;
42import android.text.TextUtils;
43
44import com.android.internal.R;
45import com.android.server.wifi.WifiConfigStoreLegacy.WifiConfigStoreDataLegacy;
46import com.android.server.wifi.util.WifiPermissionsWrapper;
47
48import org.junit.After;
49import org.junit.Before;
50import org.junit.Test;
51import org.mockito.ArgumentCaptor;
52import org.mockito.InOrder;
53import org.mockito.Mock;
54import org.mockito.MockitoAnnotations;
55
56import java.io.FileDescriptor;
57import java.io.PrintWriter;
58import java.io.StringWriter;
59import java.util.ArrayList;
60import java.util.Arrays;
61import java.util.HashSet;
62import java.util.List;
63import java.util.Set;
64
65/**
66 * Unit tests for {@link com.android.server.wifi.WifiConfigManager}.
67 */
68@SmallTest
69public class WifiConfigManagerTest {
70
71    private static final String TEST_BSSID = "0a:08:5c:67:89:00";
72    private static final long TEST_WALLCLOCK_CREATION_TIME_MILLIS = 9845637;
73    private static final long TEST_WALLCLOCK_UPDATE_TIME_MILLIS = 75455637;
74    private static final long TEST_ELAPSED_UPDATE_NETWORK_SELECTION_TIME_MILLIS = 29457631;
75    private static final int TEST_CREATOR_UID = WifiConfigurationTestUtil.TEST_UID;
76    private static final int TEST_NO_PERM_UID = 7;
77    private static final int TEST_UPDATE_UID = 4;
78    private static final int TEST_SYSUI_UID = 56;
79    private static final int TEST_DEFAULT_USER = UserHandle.USER_SYSTEM;
80    private static final int TEST_MAX_NUM_ACTIVE_CHANNELS_FOR_PARTIAL_SCAN = 5;
81    private static final Integer[] TEST_FREQ_LIST = {2400, 2450, 5150, 5175, 5650};
82    private static final String TEST_CREATOR_NAME = "com.wificonfigmanager.creator";
83    private static final String TEST_UPDATE_NAME = "com.wificonfigmanager.update";
84    private static final String TEST_NO_PERM_NAME = "com.wificonfigmanager.noperm";
85    private static final String TEST_DEFAULT_GW_MAC_ADDRESS = "0f:67:ad:ef:09:34";
86    private static final String TEST_STATIC_PROXY_HOST_1 = "192.168.48.1";
87    private static final int    TEST_STATIC_PROXY_PORT_1 = 8000;
88    private static final String TEST_STATIC_PROXY_EXCLUSION_LIST_1 = "";
89    private static final String TEST_PAC_PROXY_LOCATION_1 = "http://bleh";
90    private static final String TEST_STATIC_PROXY_HOST_2 = "192.168.1.1";
91    private static final int    TEST_STATIC_PROXY_PORT_2 = 3000;
92    private static final String TEST_STATIC_PROXY_EXCLUSION_LIST_2 = "";
93    private static final String TEST_PAC_PROXY_LOCATION_2 = "http://blah";
94
95    @Mock private Context mContext;
96    @Mock private FrameworkFacade mFrameworkFacade;
97    @Mock private Clock mClock;
98    @Mock private UserManager mUserManager;
99    @Mock private TelephonyManager mTelephonyManager;
100    @Mock private WifiKeyStore mWifiKeyStore;
101    @Mock private WifiConfigStore mWifiConfigStore;
102    @Mock private WifiConfigStoreLegacy mWifiConfigStoreLegacy;
103    @Mock private PackageManager mPackageManager;
104    @Mock private DevicePolicyManagerInternal mDevicePolicyManagerInternal;
105    @Mock private WifiPermissionsWrapper mWifiPermissionsWrapper;
106
107    private MockResources mResources;
108    private InOrder mContextConfigStoreMockOrder;
109    private WifiConfigManager mWifiConfigManager;
110
111    /**
112     * Setup the mocks and an instance of WifiConfigManager before each test.
113     */
114    @Before
115    public void setUp() throws Exception {
116        MockitoAnnotations.initMocks(this);
117
118        // Set up the inorder for verifications. This is needed to verify that the broadcasts,
119        // store writes for network updates followed by network additions are in the expected order.
120        mContextConfigStoreMockOrder = inOrder(mContext, mWifiConfigStore);
121
122        // Set up the package name stuff & permission override.
123        when(mContext.getPackageManager()).thenReturn(mPackageManager);
124        mResources = new MockResources();
125        mResources.setBoolean(
126                R.bool.config_wifi_only_link_same_credential_configurations, true);
127        mResources.setInteger(
128                R.integer.config_wifi_framework_associated_partial_scan_max_num_active_channels,
129                TEST_MAX_NUM_ACTIVE_CHANNELS_FOR_PARTIAL_SCAN);
130        when(mContext.getResources()).thenReturn(mResources);
131
132        // Setup UserManager profiles for the default user.
133        setupUserProfiles(TEST_DEFAULT_USER);
134
135        doAnswer(new AnswerWithArguments() {
136            public String answer(int uid) throws Exception {
137                if (uid == TEST_CREATOR_UID) {
138                    return TEST_CREATOR_NAME;
139                } else if (uid == TEST_UPDATE_UID) {
140                    return TEST_UPDATE_NAME;
141                } else if (uid == TEST_SYSUI_UID) {
142                    return WifiConfigManager.SYSUI_PACKAGE_NAME;
143                } else if (uid == TEST_NO_PERM_UID) {
144                    return TEST_NO_PERM_NAME;
145                }
146                fail("Unexpected UID: " + uid);
147                return "";
148            }
149        }).when(mPackageManager).getNameForUid(anyInt());
150        doAnswer(new AnswerWithArguments() {
151            public int answer(String packageName, int flags, int userId) throws Exception {
152                if (packageName.equals(WifiConfigManager.SYSUI_PACKAGE_NAME)) {
153                    return TEST_SYSUI_UID;
154                } else {
155                    return 0;
156                }
157            }
158        }).when(mPackageManager).getPackageUidAsUser(anyString(), anyInt(), anyInt());
159
160        // Both the UID's in the test have the configuration override permission granted by
161        // default. This maybe modified for particular tests if needed.
162        doAnswer(new AnswerWithArguments() {
163            public int answer(String permName, int uid) throws Exception {
164                if (uid == TEST_CREATOR_UID || uid == TEST_UPDATE_UID || uid == TEST_SYSUI_UID) {
165                    return PackageManager.PERMISSION_GRANTED;
166                }
167                return PackageManager.PERMISSION_DENIED;
168            }
169        }).when(mFrameworkFacade).checkUidPermission(anyString(), anyInt());
170
171        when(mWifiKeyStore
172                .updateNetworkKeys(any(WifiConfiguration.class), any(WifiConfiguration.class)))
173                .thenReturn(true);
174
175        when(mWifiConfigStore.areStoresPresent()).thenReturn(true);
176        when(mWifiConfigStore.read())
177                .thenReturn(new WifiConfigStoreData(new ArrayList<WifiConfiguration>(),
178                        new ArrayList<WifiConfiguration>(), new HashSet<String>()));
179
180        when(mDevicePolicyManagerInternal.isActiveAdminWithPolicy(anyInt(), anyInt()))
181                .thenReturn(false);
182        when(mWifiPermissionsWrapper.getDevicePolicyManagerInternal())
183                .thenReturn(mDevicePolicyManagerInternal);
184        createWifiConfigManager();
185    }
186
187    /**
188     * Called after each test
189     */
190    @After
191    public void cleanup() {
192        validateMockitoUsage();
193    }
194
195    /**
196     * Verifies that network retrieval via
197     * {@link WifiConfigManager#getConfiguredNetworks()} and
198     * {@link WifiConfigManager#getConfiguredNetworksWithPasswords()} works even if we have not
199     * yet loaded data from store.
200     */
201    @Test
202    public void testGetConfiguredNetworksBeforeLoadFromStore() {
203        assertTrue(mWifiConfigManager.getConfiguredNetworks().isEmpty());
204        assertTrue(mWifiConfigManager.getConfiguredNetworksWithPasswords().isEmpty());
205    }
206
207    /**
208     * Verifies the addition of a single network using
209     * {@link WifiConfigManager#addOrUpdateNetwork(WifiConfiguration, int)}
210     */
211    @Test
212    public void testAddSingleOpenNetwork() {
213        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
214        List<WifiConfiguration> networks = new ArrayList<>();
215        networks.add(openNetwork);
216
217        verifyAddNetworkToWifiConfigManager(openNetwork);
218
219        List<WifiConfiguration> retrievedNetworks =
220                mWifiConfigManager.getConfiguredNetworksWithPasswords();
221        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
222                networks, retrievedNetworks);
223        // Ensure that the newly added network is disabled.
224        assertEquals(WifiConfiguration.Status.DISABLED, retrievedNetworks.get(0).status);
225    }
226
227    /**
228     * Verifies the modification of a single network using
229     * {@link WifiConfigManager#addOrUpdateNetwork(WifiConfiguration, int)}
230     */
231    @Test
232    public void testUpdateSingleOpenNetwork() {
233        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
234        List<WifiConfiguration> networks = new ArrayList<>();
235        networks.add(openNetwork);
236
237        verifyAddNetworkToWifiConfigManager(openNetwork);
238
239        // Now change BSSID for the network.
240        assertAndSetNetworkBSSID(openNetwork, TEST_BSSID);
241        verifyUpdateNetworkToWifiConfigManagerWithoutIpChange(openNetwork);
242
243        // Now verify that the modification has been effective.
244        List<WifiConfiguration> retrievedNetworks =
245                mWifiConfigManager.getConfiguredNetworksWithPasswords();
246        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
247                networks, retrievedNetworks);
248    }
249
250    /**
251     * Verifies the addition of a single ephemeral network using
252     * {@link WifiConfigManager#addOrUpdateNetwork(WifiConfiguration, int)} and verifies that
253     * the {@link WifiConfigManager#getSavedNetworks()} does not return this network.
254     */
255    @Test
256    public void testAddSingleEphemeralNetwork() throws Exception {
257        WifiConfiguration ephemeralNetwork = WifiConfigurationTestUtil.createOpenNetwork();
258        ephemeralNetwork.ephemeral = true;
259        List<WifiConfiguration> networks = new ArrayList<>();
260        networks.add(ephemeralNetwork);
261
262        verifyAddEphemeralNetworkToWifiConfigManager(ephemeralNetwork);
263
264        List<WifiConfiguration> retrievedNetworks =
265                mWifiConfigManager.getConfiguredNetworksWithPasswords();
266        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
267                networks, retrievedNetworks);
268
269        // Ensure that this is not returned in the saved network list.
270        assertTrue(mWifiConfigManager.getSavedNetworks().isEmpty());
271    }
272
273    /**
274     * Verifies the addition of 2 networks (1 normal and 1 ephemeral) using
275     * {@link WifiConfigManager#addOrUpdateNetwork(WifiConfiguration, int)} and ensures that
276     * the ephemeral network configuration is not persisted in config store.
277     */
278    @Test
279    public void testAddMultipleNetworksAndEnsureEphemeralNetworkNotPersisted() {
280        WifiConfiguration ephemeralNetwork = WifiConfigurationTestUtil.createOpenNetwork();
281        ephemeralNetwork.ephemeral = true;
282        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
283
284        assertTrue(addNetworkToWifiConfigManager(ephemeralNetwork).isSuccess());
285        assertTrue(addNetworkToWifiConfigManager(openNetwork).isSuccess());
286
287        // The open network addition should trigger a store write.
288        WifiConfigStoreData storeData = captureWriteStoreData();
289        assertFalse(isNetworkInConfigStoreData(ephemeralNetwork, storeData));
290        assertTrue(isNetworkInConfigStoreData(openNetwork, storeData));
291    }
292
293    /**
294     * Verifies that the modification of a single open network using
295     * {@link WifiConfigManager#addOrUpdateNetwork(WifiConfiguration, int)} with a UID which
296     * has no permission to modify the network fails.
297     */
298    @Test
299    public void testUpdateSingleOpenNetworkFailedDueToPermissionDenied() throws Exception {
300        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
301        List<WifiConfiguration> networks = new ArrayList<>();
302        networks.add(openNetwork);
303
304        verifyAddNetworkToWifiConfigManager(openNetwork);
305
306        // Now change BSSID of the network.
307        assertAndSetNetworkBSSID(openNetwork, TEST_BSSID);
308
309        // Deny permission for |UPDATE_UID|.
310        doAnswer(new AnswerWithArguments() {
311            public int answer(String permName, int uid) throws Exception {
312                if (uid == TEST_CREATOR_UID) {
313                    return PackageManager.PERMISSION_GRANTED;
314                }
315                return PackageManager.PERMISSION_DENIED;
316            }
317        }).when(mFrameworkFacade).checkUidPermission(anyString(), anyInt());
318
319        // Update the same configuration and ensure that the operation failed.
320        NetworkUpdateResult result = updateNetworkToWifiConfigManager(openNetwork);
321        assertTrue(result.getNetworkId() == WifiConfiguration.INVALID_NETWORK_ID);
322    }
323
324    /**
325     * Verifies that the modification of a single open network using
326     * {@link WifiConfigManager#addOrUpdateNetwork(WifiConfiguration, int)} with the creator UID
327     * should always succeed.
328     */
329    @Test
330    public void testUpdateSingleOpenNetworkSuccessWithCreatorUID() throws Exception {
331        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
332        List<WifiConfiguration> networks = new ArrayList<>();
333        networks.add(openNetwork);
334
335        verifyAddNetworkToWifiConfigManager(openNetwork);
336
337        // Now change BSSID of the network.
338        assertAndSetNetworkBSSID(openNetwork, TEST_BSSID);
339
340        // Deny permission for all UIDs.
341        doAnswer(new AnswerWithArguments() {
342            public int answer(String permName, int uid) throws Exception {
343                return PackageManager.PERMISSION_DENIED;
344            }
345        }).when(mFrameworkFacade).checkUidPermission(anyString(), anyInt());
346
347        // Update the same configuration using the creator UID.
348        NetworkUpdateResult result =
349                mWifiConfigManager.addOrUpdateNetwork(openNetwork, TEST_CREATOR_UID);
350        assertTrue(result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID);
351
352        // Now verify that the modification has been effective.
353        List<WifiConfiguration> retrievedNetworks =
354                mWifiConfigManager.getConfiguredNetworksWithPasswords();
355        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
356                networks, retrievedNetworks);
357    }
358
359    /**
360     * Verifies the addition of a single PSK network using
361     * {@link WifiConfigManager#addOrUpdateNetwork(WifiConfiguration, int)} and verifies that
362     * {@link WifiConfigManager#getSavedNetworks()} masks the password.
363     */
364    @Test
365    public void testAddSinglePskNetwork() {
366        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
367        List<WifiConfiguration> networks = new ArrayList<>();
368        networks.add(pskNetwork);
369
370        verifyAddNetworkToWifiConfigManager(pskNetwork);
371
372        List<WifiConfiguration> retrievedNetworks =
373                mWifiConfigManager.getConfiguredNetworksWithPasswords();
374        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
375                networks, retrievedNetworks);
376
377        List<WifiConfiguration> retrievedSavedNetworks = mWifiConfigManager.getSavedNetworks();
378        assertEquals(retrievedSavedNetworks.size(), 1);
379        assertEquals(retrievedSavedNetworks.get(0).configKey(), pskNetwork.configKey());
380        assertPasswordsMaskedInWifiConfiguration(retrievedSavedNetworks.get(0));
381    }
382
383    /**
384     * Verifies the addition of a single WEP network using
385     * {@link WifiConfigManager#addOrUpdateNetwork(WifiConfiguration, int)} and verifies that
386     * {@link WifiConfigManager#getSavedNetworks()} masks the password.
387     */
388    @Test
389    public void testAddSingleWepNetwork() {
390        WifiConfiguration wepNetwork = WifiConfigurationTestUtil.createWepNetwork();
391        List<WifiConfiguration> networks = new ArrayList<>();
392        networks.add(wepNetwork);
393
394        verifyAddNetworkToWifiConfigManager(wepNetwork);
395
396        List<WifiConfiguration> retrievedNetworks =
397                mWifiConfigManager.getConfiguredNetworksWithPasswords();
398        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
399                networks, retrievedNetworks);
400
401        List<WifiConfiguration> retrievedSavedNetworks = mWifiConfigManager.getSavedNetworks();
402        assertEquals(retrievedSavedNetworks.size(), 1);
403        assertEquals(retrievedSavedNetworks.get(0).configKey(), wepNetwork.configKey());
404        assertPasswordsMaskedInWifiConfiguration(retrievedSavedNetworks.get(0));
405    }
406
407    /**
408     * Verifies the modification of an IpConfiguration using
409     * {@link WifiConfigManager#addOrUpdateNetwork(WifiConfiguration, int)}
410     */
411    @Test
412    public void testUpdateIpConfiguration() {
413        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
414        List<WifiConfiguration> networks = new ArrayList<>();
415        networks.add(openNetwork);
416
417        verifyAddNetworkToWifiConfigManager(openNetwork);
418
419        // Now change BSSID of the network.
420        assertAndSetNetworkBSSID(openNetwork, TEST_BSSID);
421
422        // Update the same configuration and ensure that the IP configuration change flags
423        // are not set.
424        verifyUpdateNetworkToWifiConfigManagerWithoutIpChange(openNetwork);
425
426        // Configure mock DevicePolicyManager to give Profile Owner permission so that we can modify
427        // proxy settings on a configuration
428        when(mDevicePolicyManagerInternal.isActiveAdminWithPolicy(anyInt(),
429                eq(DeviceAdminInfo.USES_POLICY_PROFILE_OWNER))).thenReturn(true);
430
431        // Change the IpConfiguration now and ensure that the IP configuration flags are set now.
432        assertAndSetNetworkIpConfiguration(
433                openNetwork,
434                WifiConfigurationTestUtil.createStaticIpConfigurationWithStaticProxy());
435        verifyUpdateNetworkToWifiConfigManagerWithIpChange(openNetwork);
436
437        // Now verify that all the modifications have been effective.
438        List<WifiConfiguration> retrievedNetworks =
439                mWifiConfigManager.getConfiguredNetworksWithPasswords();
440        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
441                networks, retrievedNetworks);
442    }
443
444    /**
445     * Verifies the removal of a single network using
446     * {@link WifiConfigManager#removeNetwork(int)}
447     */
448    @Test
449    public void testRemoveSingleOpenNetwork() {
450        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
451
452        verifyAddNetworkToWifiConfigManager(openNetwork);
453        // Ensure that configured network list is not empty.
454        assertFalse(mWifiConfigManager.getConfiguredNetworks().isEmpty());
455
456        verifyRemoveNetworkFromWifiConfigManager(openNetwork);
457        // Ensure that configured network list is empty now.
458        assertTrue(mWifiConfigManager.getConfiguredNetworks().isEmpty());
459    }
460
461    /**
462     * Verifies the removal of an ephemeral network using
463     * {@link WifiConfigManager#removeNetwork(int)}
464     */
465    @Test
466    public void testRemoveSingleEphemeralNetwork() throws Exception {
467        WifiConfiguration ephemeralNetwork = WifiConfigurationTestUtil.createOpenNetwork();
468        ephemeralNetwork.ephemeral = true;
469
470        verifyAddEphemeralNetworkToWifiConfigManager(ephemeralNetwork);
471        // Ensure that configured network list is not empty.
472        assertFalse(mWifiConfigManager.getConfiguredNetworks().isEmpty());
473
474        verifyRemoveEphemeralNetworkFromWifiConfigManager(ephemeralNetwork);
475        // Ensure that configured network list is empty now.
476        assertTrue(mWifiConfigManager.getConfiguredNetworks().isEmpty());
477    }
478
479    /**
480     * Verifies the addition & update of multiple networks using
481     * {@link WifiConfigManager#addOrUpdateNetwork(WifiConfiguration, int)} and the
482     * removal of networks using
483     * {@link WifiConfigManager#removeNetwork(int)}
484     */
485    @Test
486    public void testAddUpdateRemoveMultipleNetworks() {
487        List<WifiConfiguration> networks = new ArrayList<>();
488        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
489        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
490        WifiConfiguration wepNetwork = WifiConfigurationTestUtil.createWepNetwork();
491        networks.add(openNetwork);
492        networks.add(pskNetwork);
493        networks.add(wepNetwork);
494
495        verifyAddNetworkToWifiConfigManager(openNetwork);
496        verifyAddNetworkToWifiConfigManager(pskNetwork);
497        verifyAddNetworkToWifiConfigManager(wepNetwork);
498
499        // Now verify that all the additions has been effective.
500        List<WifiConfiguration> retrievedNetworks =
501                mWifiConfigManager.getConfiguredNetworksWithPasswords();
502        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
503                networks, retrievedNetworks);
504
505        // Modify all the 3 configurations and update it to WifiConfigManager.
506        assertAndSetNetworkBSSID(openNetwork, TEST_BSSID);
507        assertAndSetNetworkBSSID(pskNetwork, TEST_BSSID);
508        assertAndSetNetworkIpConfiguration(
509                wepNetwork,
510                WifiConfigurationTestUtil.createStaticIpConfigurationWithPacProxy());
511
512        // Configure mock DevicePolicyManager to give Profile Owner permission so that we can modify
513        // proxy settings on a configuration
514        when(mDevicePolicyManagerInternal.isActiveAdminWithPolicy(anyInt(),
515                eq(DeviceAdminInfo.USES_POLICY_PROFILE_OWNER))).thenReturn(true);
516
517        verifyUpdateNetworkToWifiConfigManagerWithoutIpChange(openNetwork);
518        verifyUpdateNetworkToWifiConfigManagerWithoutIpChange(pskNetwork);
519        verifyUpdateNetworkToWifiConfigManagerWithIpChange(wepNetwork);
520        // Now verify that all the modifications has been effective.
521        retrievedNetworks = mWifiConfigManager.getConfiguredNetworksWithPasswords();
522        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
523                networks, retrievedNetworks);
524
525        // Now remove all 3 networks.
526        verifyRemoveNetworkFromWifiConfigManager(openNetwork);
527        verifyRemoveNetworkFromWifiConfigManager(pskNetwork);
528        verifyRemoveNetworkFromWifiConfigManager(wepNetwork);
529
530        // Ensure that configured network list is empty now.
531        assertTrue(mWifiConfigManager.getConfiguredNetworks().isEmpty());
532    }
533
534    /**
535     * Verifies the update of network status using
536     * {@link WifiConfigManager#updateNetworkSelectionStatus(int, int)}.
537     */
538    @Test
539    public void testNetworkSelectionStatus() {
540        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
541
542        NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(openNetwork);
543
544        // First set it to enabled.
545        verifyUpdateNetworkSelectionStatus(
546                result.getNetworkId(), NetworkSelectionStatus.NETWORK_SELECTION_ENABLE, 0);
547
548        // Now set it to temporarily disabled. The threshold for association rejection is 5, so
549        // disable it 5 times to actually mark it temporarily disabled.
550        int assocRejectReason = NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION;
551        int assocRejectThreshold =
552                WifiConfigManager.NETWORK_SELECTION_DISABLE_THRESHOLD[assocRejectReason];
553        for (int i = 1; i <= assocRejectThreshold; i++) {
554            verifyUpdateNetworkSelectionStatus(result.getNetworkId(), assocRejectReason, i);
555        }
556
557        // Now set it to permanently disabled.
558        verifyUpdateNetworkSelectionStatus(
559                result.getNetworkId(), NetworkSelectionStatus.DISABLED_BY_WIFI_MANAGER, 0);
560
561        // Now set it back to enabled.
562        verifyUpdateNetworkSelectionStatus(
563                result.getNetworkId(), NetworkSelectionStatus.NETWORK_SELECTION_ENABLE, 0);
564    }
565
566    /**
567     * Verifies the update of network status using
568     * {@link WifiConfigManager#updateNetworkSelectionStatus(int, int)} and ensures that
569     * enabling a network clears out all the temporary disable counters.
570     */
571    @Test
572    public void testNetworkSelectionStatusEnableClearsDisableCounters() {
573        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
574
575        NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(openNetwork);
576
577        // First set it to enabled.
578        verifyUpdateNetworkSelectionStatus(
579                result.getNetworkId(), NetworkSelectionStatus.NETWORK_SELECTION_ENABLE, 0);
580
581        // Now set it to temporarily disabled 2 times for 2 different reasons.
582        verifyUpdateNetworkSelectionStatus(
583                result.getNetworkId(), NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION, 1);
584        verifyUpdateNetworkSelectionStatus(
585                result.getNetworkId(), NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION, 2);
586        verifyUpdateNetworkSelectionStatus(
587                result.getNetworkId(), NetworkSelectionStatus.DISABLED_AUTHENTICATION_FAILURE, 1);
588        verifyUpdateNetworkSelectionStatus(
589                result.getNetworkId(), NetworkSelectionStatus.DISABLED_AUTHENTICATION_FAILURE, 2);
590
591        // Now set it back to enabled.
592        verifyUpdateNetworkSelectionStatus(
593                result.getNetworkId(), NetworkSelectionStatus.NETWORK_SELECTION_ENABLE, 0);
594
595        // Ensure that the counters have all been reset now.
596        verifyUpdateNetworkSelectionStatus(
597                result.getNetworkId(), NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION, 1);
598        verifyUpdateNetworkSelectionStatus(
599                result.getNetworkId(), NetworkSelectionStatus.DISABLED_AUTHENTICATION_FAILURE, 1);
600    }
601
602    /**
603     * Verifies the enabling of temporarily disabled network using
604     * {@link WifiConfigManager#tryEnableNetwork(int)}.
605     */
606    @Test
607    public void testTryEnableNetwork() {
608        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
609
610        NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(openNetwork);
611
612        // First set it to enabled.
613        verifyUpdateNetworkSelectionStatus(
614                result.getNetworkId(), NetworkSelectionStatus.NETWORK_SELECTION_ENABLE, 0);
615
616        // Now set it to temporarily disabled. The threshold for association rejection is 5, so
617        // disable it 5 times to actually mark it temporarily disabled.
618        int assocRejectReason = NetworkSelectionStatus.DISABLED_ASSOCIATION_REJECTION;
619        int assocRejectThreshold =
620                WifiConfigManager.NETWORK_SELECTION_DISABLE_THRESHOLD[assocRejectReason];
621        for (int i = 1; i <= assocRejectThreshold; i++) {
622            verifyUpdateNetworkSelectionStatus(result.getNetworkId(), assocRejectReason, i);
623        }
624
625        // Now let's try enabling this network without changing the time, this should fail and the
626        // status remains temporarily disabled.
627        assertFalse(mWifiConfigManager.tryEnableNetwork(result.getNetworkId()));
628        NetworkSelectionStatus retrievedStatus =
629                mWifiConfigManager.getConfiguredNetwork(result.getNetworkId())
630                        .getNetworkSelectionStatus();
631        assertTrue(retrievedStatus.isNetworkTemporaryDisabled());
632
633        // Now advance time by the timeout for association rejection and ensure that the network
634        // is now enabled.
635        int assocRejectTimeout =
636                WifiConfigManager.NETWORK_SELECTION_DISABLE_TIMEOUT_MS[assocRejectReason];
637        when(mClock.getElapsedSinceBootMillis())
638                .thenReturn(TEST_ELAPSED_UPDATE_NETWORK_SELECTION_TIME_MILLIS + assocRejectTimeout);
639
640        assertTrue(mWifiConfigManager.tryEnableNetwork(result.getNetworkId()));
641        retrievedStatus =
642                mWifiConfigManager.getConfiguredNetwork(result.getNetworkId())
643                        .getNetworkSelectionStatus();
644        assertTrue(retrievedStatus.isNetworkEnabled());
645    }
646
647    /**
648     * Verifies the enabling of network using
649     * {@link WifiConfigManager#enableNetwork(int, boolean, int)} and
650     * {@link WifiConfigManager#disableNetwork(int, int)}.
651     */
652    @Test
653    public void testEnableDisableNetwork() {
654        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
655
656        NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(openNetwork);
657
658        assertTrue(mWifiConfigManager.enableNetwork(
659                result.getNetworkId(), false, TEST_CREATOR_UID));
660        WifiConfiguration retrievedNetwork =
661                mWifiConfigManager.getConfiguredNetwork(result.getNetworkId());
662        NetworkSelectionStatus retrievedStatus = retrievedNetwork.getNetworkSelectionStatus();
663        assertTrue(retrievedStatus.isNetworkEnabled());
664        verifyUpdateNetworkStatus(retrievedNetwork, WifiConfiguration.Status.ENABLED);
665
666        // Now set it disabled.
667        assertTrue(mWifiConfigManager.disableNetwork(result.getNetworkId(), TEST_CREATOR_UID));
668        retrievedNetwork = mWifiConfigManager.getConfiguredNetwork(result.getNetworkId());
669        retrievedStatus = retrievedNetwork.getNetworkSelectionStatus();
670        assertTrue(retrievedStatus.isNetworkPermanentlyDisabled());
671        verifyUpdateNetworkStatus(retrievedNetwork, WifiConfiguration.Status.DISABLED);
672    }
673
674    /**
675     * Verifies the enabling of network using
676     * {@link WifiConfigManager#enableNetwork(int, boolean, int)} with a UID which
677     * has no permission to modify the network fails..
678     */
679    @Test
680    public void testEnableDisableNetworkFailedDueToPermissionDenied() throws Exception {
681        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
682
683        NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(openNetwork);
684
685        assertTrue(mWifiConfigManager.enableNetwork(
686                result.getNetworkId(), false, TEST_CREATOR_UID));
687        WifiConfiguration retrievedNetwork =
688                mWifiConfigManager.getConfiguredNetwork(result.getNetworkId());
689        NetworkSelectionStatus retrievedStatus = retrievedNetwork.getNetworkSelectionStatus();
690        assertTrue(retrievedStatus.isNetworkEnabled());
691        verifyUpdateNetworkStatus(retrievedNetwork, WifiConfiguration.Status.ENABLED);
692
693        // Deny permission for |UPDATE_UID|.
694        doAnswer(new AnswerWithArguments() {
695            public int answer(String permName, int uid) throws Exception {
696                if (uid == TEST_CREATOR_UID) {
697                    return PackageManager.PERMISSION_GRANTED;
698                }
699                return PackageManager.PERMISSION_DENIED;
700            }
701        }).when(mFrameworkFacade).checkUidPermission(anyString(), anyInt());
702
703        // Now try to set it disabled with |TEST_UPDATE_UID|, it should fail and the network
704        // should remain enabled.
705        assertFalse(mWifiConfigManager.disableNetwork(result.getNetworkId(), TEST_UPDATE_UID));
706        retrievedStatus =
707                mWifiConfigManager.getConfiguredNetwork(result.getNetworkId())
708                        .getNetworkSelectionStatus();
709        assertTrue(retrievedStatus.isNetworkEnabled());
710        assertEquals(WifiConfiguration.Status.ENABLED, retrievedNetwork.status);
711    }
712
713    /**
714     * Verifies the updation of network's connectUid using
715     * {@link WifiConfigManager#checkAndUpdateLastConnectUid(int, int)}.
716     */
717    @Test
718    public void testUpdateLastConnectUid() throws Exception {
719        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
720
721        NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(openNetwork);
722
723        assertTrue(
724                mWifiConfigManager.checkAndUpdateLastConnectUid(
725                        result.getNetworkId(), TEST_CREATOR_UID));
726        WifiConfiguration retrievedNetwork =
727                mWifiConfigManager.getConfiguredNetwork(result.getNetworkId());
728        assertEquals(TEST_CREATOR_UID, retrievedNetwork.lastConnectUid);
729
730        // Deny permission for |UPDATE_UID|.
731        doAnswer(new AnswerWithArguments() {
732            public int answer(String permName, int uid) throws Exception {
733                if (uid == TEST_CREATOR_UID) {
734                    return PackageManager.PERMISSION_GRANTED;
735                }
736                return PackageManager.PERMISSION_DENIED;
737            }
738        }).when(mFrameworkFacade).checkUidPermission(anyString(), anyInt());
739
740        // Now try to update the last connect UID with |TEST_UPDATE_UID|, it should fail and
741        // the lastConnectUid should remain the same.
742        assertFalse(
743                mWifiConfigManager.checkAndUpdateLastConnectUid(
744                        result.getNetworkId(), TEST_UPDATE_UID));
745        retrievedNetwork = mWifiConfigManager.getConfiguredNetwork(result.getNetworkId());
746        assertEquals(TEST_CREATOR_UID, retrievedNetwork.lastConnectUid);
747    }
748
749    /**
750     * Verifies that any configuration update attempt with an null config is gracefully
751     * handled.
752     * This invokes {@link WifiConfigManager#addOrUpdateNetwork(WifiConfiguration, int)}.
753     */
754    @Test
755    public void testAddOrUpdateNetworkWithNullConfig() {
756        NetworkUpdateResult result = mWifiConfigManager.addOrUpdateNetwork(null, TEST_CREATOR_UID);
757        assertFalse(result.isSuccess());
758    }
759
760    /**
761     * Verifies that any configuration removal attempt with an invalid networkID is gracefully
762     * handled.
763     * This invokes {@link WifiConfigManager#removeNetwork(int)}.
764     */
765    @Test
766    public void testRemoveNetworkWithInvalidNetworkId() {
767        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
768
769        verifyAddNetworkToWifiConfigManager(openNetwork);
770
771        // Change the networkID to an invalid one.
772        openNetwork.networkId++;
773        assertFalse(mWifiConfigManager.removeNetwork(openNetwork.networkId, TEST_CREATOR_UID));
774    }
775
776    /**
777     * Verifies that any configuration update attempt with an invalid networkID is gracefully
778     * handled.
779     * This invokes {@link WifiConfigManager#enableNetwork(int, boolean, int)},
780     * {@link WifiConfigManager#disableNetwork(int, int)},
781     * {@link WifiConfigManager#updateNetworkSelectionStatus(int, int)} and
782     * {@link WifiConfigManager#checkAndUpdateLastConnectUid(int, int)}.
783     */
784    @Test
785    public void testChangeConfigurationWithInvalidNetworkId() {
786        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
787
788        NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(openNetwork);
789
790        assertFalse(mWifiConfigManager.enableNetwork(
791                result.getNetworkId() + 1, false, TEST_CREATOR_UID));
792        assertFalse(mWifiConfigManager.disableNetwork(result.getNetworkId() + 1, TEST_CREATOR_UID));
793        assertFalse(mWifiConfigManager.updateNetworkSelectionStatus(
794                result.getNetworkId() + 1, NetworkSelectionStatus.DISABLED_BY_WIFI_MANAGER));
795        assertFalse(mWifiConfigManager.checkAndUpdateLastConnectUid(
796                result.getNetworkId() + 1, TEST_CREATOR_UID));
797    }
798
799    /**
800     * Verifies multiple modification of a single network using
801     * {@link WifiConfigManager#addOrUpdateNetwork(WifiConfiguration, int)}.
802     * This test is basically checking if the apps can reset some of the fields of the config after
803     * addition. The fields being reset in this test are the |preSharedKey| and |wepKeys|.
804     * 1. Create an open network initially.
805     * 2. Modify the added network config to a WEP network config with all the 4 keys set.
806     * 3. Modify the added network config to a WEP network config with only 1 key set.
807     * 4. Modify the added network config to a PSK network config.
808     */
809    @Test
810    public void testMultipleUpdatesSingleNetwork() {
811        WifiConfiguration network = WifiConfigurationTestUtil.createOpenNetwork();
812        verifyAddNetworkToWifiConfigManager(network);
813
814        // Now add |wepKeys| to the network. We don't need to update the |allowedKeyManagement|
815        // fields for open to WEP conversion.
816        String[] wepKeys =
817                Arrays.copyOf(WifiConfigurationTestUtil.TEST_WEP_KEYS,
818                        WifiConfigurationTestUtil.TEST_WEP_KEYS.length);
819        int wepTxKeyIdx = WifiConfigurationTestUtil.TEST_WEP_TX_KEY_INDEX;
820        assertAndSetNetworkWepKeysAndTxIndex(network, wepKeys, wepTxKeyIdx);
821
822        verifyUpdateNetworkToWifiConfigManagerWithoutIpChange(network);
823        WifiConfigurationTestUtil.assertConfigurationEqualForConfigManagerAddOrUpdate(
824                network, mWifiConfigManager.getConfiguredNetworkWithPassword(network.networkId));
825
826        // Now empty out 3 of the |wepKeys[]| and ensure that those keys have been reset correctly.
827        for (int i = 1; i < network.wepKeys.length; i++) {
828            wepKeys[i] = "";
829        }
830        wepTxKeyIdx = 0;
831        assertAndSetNetworkWepKeysAndTxIndex(network, wepKeys, wepTxKeyIdx);
832
833        verifyUpdateNetworkToWifiConfigManagerWithoutIpChange(network);
834        WifiConfigurationTestUtil.assertConfigurationEqualForConfigManagerAddOrUpdate(
835                network, mWifiConfigManager.getConfiguredNetworkWithPassword(network.networkId));
836
837        // Now change the config to a PSK network config by resetting the remaining |wepKey[0]|
838        // field and setting the |preSharedKey| and |allowedKeyManagement| fields.
839        wepKeys[0] = "";
840        wepTxKeyIdx = -1;
841        assertAndSetNetworkWepKeysAndTxIndex(network, wepKeys, wepTxKeyIdx);
842        network.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
843        assertAndSetNetworkPreSharedKey(network, WifiConfigurationTestUtil.TEST_PSK);
844
845        verifyUpdateNetworkToWifiConfigManagerWithoutIpChange(network);
846        WifiConfigurationTestUtil.assertConfigurationEqualForConfigManagerAddOrUpdate(
847                network, mWifiConfigManager.getConfiguredNetworkWithPassword(network.networkId));
848    }
849
850    /**
851     * Verifies the modification of a WifiEnteriseConfig using
852     * {@link WifiConfigManager#addOrUpdateNetwork(WifiConfiguration, int)}.
853     */
854    @Test
855    public void testUpdateWifiEnterpriseConfig() {
856        WifiConfiguration network = WifiConfigurationTestUtil.createEapNetwork();
857        verifyAddNetworkToWifiConfigManager(network);
858
859        // Set the |password| field in WifiEnterpriseConfig and modify the config to PEAP/GTC.
860        network.enterpriseConfig =
861                WifiConfigurationTestUtil.createPEAPWifiEnterpriseConfigWithGTCPhase2();
862        assertAndSetNetworkEnterprisePassword(network, "test");
863
864        verifyUpdateNetworkToWifiConfigManagerWithoutIpChange(network);
865        WifiConfigurationTestUtil.assertConfigurationEqualForConfigManagerAddOrUpdate(
866                network, mWifiConfigManager.getConfiguredNetworkWithPassword(network.networkId));
867
868        // Reset the |password| field in WifiEnterpriseConfig and modify the config to TLS/None.
869        network.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
870        network.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.NONE);
871        assertAndSetNetworkEnterprisePassword(network, "");
872
873        verifyUpdateNetworkToWifiConfigManagerWithoutIpChange(network);
874        WifiConfigurationTestUtil.assertConfigurationEqualForConfigManagerAddOrUpdate(
875                network, mWifiConfigManager.getConfiguredNetworkWithPassword(network.networkId));
876    }
877
878    /**
879     * Verifies the modification of a single network using
880     * {@link WifiConfigManager#addOrUpdateNetwork(WifiConfiguration, int)} by passing in nulls
881     * in all the publicly exposed fields.
882     */
883    @Test
884    public void testUpdateSingleNetworkWithNullValues() {
885        WifiConfiguration network = WifiConfigurationTestUtil.createEapNetwork();
886        verifyAddNetworkToWifiConfigManager(network);
887
888        // Save a copy of the original network for comparison.
889        WifiConfiguration originalNetwork = new WifiConfiguration(network);
890
891        // Now set all the public fields to null and try updating the network.
892        network.allowedAuthAlgorithms.clear();
893        network.allowedProtocols.clear();
894        network.allowedKeyManagement.clear();
895        network.allowedPairwiseCiphers.clear();
896        network.allowedGroupCiphers.clear();
897        network.setIpConfiguration(null);
898        network.enterpriseConfig = null;
899
900        // Update the network.
901        NetworkUpdateResult result = updateNetworkToWifiConfigManager(network);
902        assertTrue(result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID);
903        assertFalse(result.isNewNetwork());
904
905        // Verify no changes to the original network configuration.
906        verifyNetworkUpdateBroadcast(originalNetwork);
907        verifyNetworkInConfigStoreData(originalNetwork);
908        assertFalse(result.hasIpChanged());
909        assertFalse(result.hasProxyChanged());
910
911        // Copy over the updated debug params to the original network config before comparison.
912        originalNetwork.lastUpdateUid = network.lastUpdateUid;
913        originalNetwork.lastUpdateName = network.lastUpdateName;
914        originalNetwork.updateTime = network.updateTime;
915
916        // Now verify that there was no change to the network configurations.
917        WifiConfigurationTestUtil.assertConfigurationEqualForConfigManagerAddOrUpdate(
918                originalNetwork,
919                mWifiConfigManager.getConfiguredNetworkWithPassword(originalNetwork.networkId));
920    }
921
922    /**
923     * Verifies that the modification of a single network using
924     * {@link WifiConfigManager#addOrUpdateNetwork(WifiConfiguration, int)} does not modify
925     * existing configuration if there is a failure.
926     */
927    @Test
928    public void testUpdateSingleNetworkFailureDoesNotModifyOriginal() {
929        WifiConfiguration network = WifiConfigurationTestUtil.createEapNetwork();
930        network.enterpriseConfig =
931                WifiConfigurationTestUtil.createPEAPWifiEnterpriseConfigWithGTCPhase2();
932        verifyAddNetworkToWifiConfigManager(network);
933
934        // Save a copy of the original network for comparison.
935        WifiConfiguration originalNetwork = new WifiConfiguration(network);
936
937        // Now modify the network's EAP method.
938        network.enterpriseConfig =
939                WifiConfigurationTestUtil.createTLSWifiEnterpriseConfigWithNonePhase2();
940
941        // Fail this update because of cert installation failure.
942        when(mWifiKeyStore
943                .updateNetworkKeys(any(WifiConfiguration.class), any(WifiConfiguration.class)))
944                .thenReturn(false);
945        NetworkUpdateResult result =
946                mWifiConfigManager.addOrUpdateNetwork(network, TEST_UPDATE_UID);
947        assertTrue(result.getNetworkId() == WifiConfiguration.INVALID_NETWORK_ID);
948
949        // Now verify that there was no change to the network configurations.
950        WifiConfigurationTestUtil.assertConfigurationEqualForConfigManagerAddOrUpdate(
951                originalNetwork,
952                mWifiConfigManager.getConfiguredNetworkWithPassword(originalNetwork.networkId));
953    }
954
955    /**
956     * Verifies the matching of networks with different encryption types with the
957     * corresponding scan detail using
958     * {@link WifiConfigManager#getSavedNetworkForScanDetailAndCache(ScanDetail)}.
959     * The test also verifies that the provided scan detail was cached,
960     */
961    @Test
962    public void testMatchScanDetailToNetworksAndCache() {
963        // Create networks of different types and ensure that they're all matched using
964        // the corresponding ScanDetail correctly.
965        verifyAddSingleNetworkAndMatchScanDetailToNetworkAndCache(
966                WifiConfigurationTestUtil.createOpenNetwork());
967        verifyAddSingleNetworkAndMatchScanDetailToNetworkAndCache(
968                WifiConfigurationTestUtil.createWepNetwork());
969        verifyAddSingleNetworkAndMatchScanDetailToNetworkAndCache(
970                WifiConfigurationTestUtil.createPskNetwork());
971        verifyAddSingleNetworkAndMatchScanDetailToNetworkAndCache(
972                WifiConfigurationTestUtil.createEapNetwork());
973    }
974
975    /**
976     * Verifies that scan details with wrong SSID/authentication types are not matched using
977     * {@link WifiConfigManager#getSavedNetworkForScanDetailAndCache(ScanDetail)}
978     * to the added networks.
979     */
980    @Test
981    public void testNoMatchScanDetailToNetwork() {
982        // First create networks of different types.
983        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
984        WifiConfiguration wepNetwork = WifiConfigurationTestUtil.createWepNetwork();
985        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
986        WifiConfiguration eapNetwork = WifiConfigurationTestUtil.createEapNetwork();
987
988        // Now add them to WifiConfigManager.
989        verifyAddNetworkToWifiConfigManager(openNetwork);
990        verifyAddNetworkToWifiConfigManager(wepNetwork);
991        verifyAddNetworkToWifiConfigManager(pskNetwork);
992        verifyAddNetworkToWifiConfigManager(eapNetwork);
993
994        // Now create dummy scan detail corresponding to the networks.
995        ScanDetail openNetworkScanDetail = createScanDetailForNetwork(openNetwork);
996        ScanDetail wepNetworkScanDetail = createScanDetailForNetwork(wepNetwork);
997        ScanDetail pskNetworkScanDetail = createScanDetailForNetwork(pskNetwork);
998        ScanDetail eapNetworkScanDetail = createScanDetailForNetwork(eapNetwork);
999
1000        // Now mix and match parameters from different scan details.
1001        openNetworkScanDetail.getScanResult().SSID =
1002                wepNetworkScanDetail.getScanResult().SSID;
1003        wepNetworkScanDetail.getScanResult().capabilities =
1004                pskNetworkScanDetail.getScanResult().capabilities;
1005        pskNetworkScanDetail.getScanResult().capabilities =
1006                eapNetworkScanDetail.getScanResult().capabilities;
1007        eapNetworkScanDetail.getScanResult().capabilities =
1008                openNetworkScanDetail.getScanResult().capabilities;
1009
1010        // Try to lookup a saved network using the modified scan details. All of these should fail.
1011        assertNull(mWifiConfigManager.getSavedNetworkForScanDetailAndCache(openNetworkScanDetail));
1012        assertNull(mWifiConfigManager.getSavedNetworkForScanDetailAndCache(wepNetworkScanDetail));
1013        assertNull(mWifiConfigManager.getSavedNetworkForScanDetailAndCache(pskNetworkScanDetail));
1014        assertNull(mWifiConfigManager.getSavedNetworkForScanDetailAndCache(eapNetworkScanDetail));
1015
1016        // All the cache's should be empty as well.
1017        assertNull(mWifiConfigManager.getScanDetailCacheForNetwork(openNetwork.networkId));
1018        assertNull(mWifiConfigManager.getScanDetailCacheForNetwork(wepNetwork.networkId));
1019        assertNull(mWifiConfigManager.getScanDetailCacheForNetwork(pskNetwork.networkId));
1020        assertNull(mWifiConfigManager.getScanDetailCacheForNetwork(eapNetwork.networkId));
1021    }
1022
1023    /**
1024     * Verifies that scan detail cache is trimmed down when the size of the cache for a network
1025     * exceeds {@link WifiConfigManager#SCAN_CACHE_ENTRIES_MAX_SIZE}.
1026     */
1027    @Test
1028    public void testScanDetailCacheTrimForNetwork() {
1029        // Add a single network.
1030        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
1031        verifyAddNetworkToWifiConfigManager(openNetwork);
1032
1033        ScanDetailCache scanDetailCache;
1034        String testBssidPrefix = "00:a5:b8:c9:45:";
1035
1036        // Modify |BSSID| field in the scan result and add copies of scan detail
1037        // |SCAN_CACHE_ENTRIES_MAX_SIZE| times.
1038        int scanDetailNum = 1;
1039        for (; scanDetailNum <= WifiConfigManager.SCAN_CACHE_ENTRIES_MAX_SIZE; scanDetailNum++) {
1040            // Create dummy scan detail caches with different BSSID for the network.
1041            ScanDetail scanDetail =
1042                    createScanDetailForNetwork(
1043                            openNetwork, String.format("%s%02x", testBssidPrefix, scanDetailNum));
1044            assertNotNull(
1045                    mWifiConfigManager.getSavedNetworkForScanDetailAndCache(scanDetail));
1046
1047            // The size of scan detail cache should keep growing until it hits
1048            // |SCAN_CACHE_ENTRIES_MAX_SIZE|.
1049            scanDetailCache =
1050                    mWifiConfigManager.getScanDetailCacheForNetwork(openNetwork.networkId);
1051            assertEquals(scanDetailNum, scanDetailCache.size());
1052        }
1053
1054        // Now add the |SCAN_CACHE_ENTRIES_MAX_SIZE + 1| entry. This should trigger the trim.
1055        ScanDetail scanDetail =
1056                createScanDetailForNetwork(
1057                        openNetwork, String.format("%s%02x", testBssidPrefix, scanDetailNum));
1058        assertNotNull(mWifiConfigManager.getSavedNetworkForScanDetailAndCache(scanDetail));
1059
1060        // Retrieve the scan detail cache and ensure that the size was trimmed down to
1061        // |SCAN_CACHE_ENTRIES_TRIM_SIZE + 1|. The "+1" is to account for the new entry that
1062        // was added after the trim.
1063        scanDetailCache = mWifiConfigManager.getScanDetailCacheForNetwork(openNetwork.networkId);
1064        assertEquals(WifiConfigManager.SCAN_CACHE_ENTRIES_TRIM_SIZE + 1, scanDetailCache.size());
1065    }
1066
1067    /**
1068     * Verifies that hasEverConnected is false for a newly added network.
1069     */
1070    @Test
1071    public void testAddNetworkHasEverConnectedFalse() {
1072        verifyAddNetworkHasEverConnectedFalse(WifiConfigurationTestUtil.createOpenNetwork());
1073    }
1074
1075    /**
1076     * Verifies that hasEverConnected is false for a newly added network even when new config has
1077     * mistakenly set HasEverConnected to true.
1078     */
1079    @Test
1080    public void testAddNetworkOverridesHasEverConnectedWhenTrueInNewConfig() {
1081        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
1082        openNetwork.getNetworkSelectionStatus().setHasEverConnected(true);
1083        verifyAddNetworkHasEverConnectedFalse(openNetwork);
1084    }
1085
1086    /**
1087     * Verify that the |HasEverConnected| is set when
1088     * {@link WifiConfigManager#updateNetworkAfterConnect(int)} is invoked.
1089     */
1090    @Test
1091    public void testUpdateConfigAfterConnectHasEverConnectedTrue() {
1092        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
1093        verifyAddNetworkHasEverConnectedFalse(openNetwork);
1094        verifyUpdateNetworkAfterConnectHasEverConnectedTrue(openNetwork.networkId);
1095    }
1096
1097    /**
1098     * Verifies that hasEverConnected is cleared when a network config |preSharedKey| is updated.
1099     */
1100    @Test
1101    public void testUpdatePreSharedKeyClearsHasEverConnected() {
1102        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
1103        verifyAddNetworkHasEverConnectedFalse(pskNetwork);
1104        verifyUpdateNetworkAfterConnectHasEverConnectedTrue(pskNetwork.networkId);
1105
1106        // Now update the same network with a different psk.
1107        assertFalse(pskNetwork.preSharedKey.equals("newpassword"));
1108        pskNetwork.preSharedKey = "newpassword";
1109        verifyUpdateNetworkWithCredentialChangeHasEverConnectedFalse(pskNetwork);
1110    }
1111
1112    /**
1113     * Verifies that hasEverConnected is cleared when a network config |wepKeys| is updated.
1114     */
1115    @Test
1116    public void testUpdateWepKeysClearsHasEverConnected() {
1117        WifiConfiguration wepNetwork = WifiConfigurationTestUtil.createWepNetwork();
1118        verifyAddNetworkHasEverConnectedFalse(wepNetwork);
1119        verifyUpdateNetworkAfterConnectHasEverConnectedTrue(wepNetwork.networkId);
1120
1121        // Now update the same network with a different wep.
1122        assertFalse(wepNetwork.wepKeys[0].equals("newpassword"));
1123        wepNetwork.wepKeys[0] = "newpassword";
1124        verifyUpdateNetworkWithCredentialChangeHasEverConnectedFalse(wepNetwork);
1125    }
1126
1127    /**
1128     * Verifies that hasEverConnected is cleared when a network config |wepTxKeyIndex| is updated.
1129     */
1130    @Test
1131    public void testUpdateWepTxKeyClearsHasEverConnected() {
1132        WifiConfiguration wepNetwork = WifiConfigurationTestUtil.createWepNetwork();
1133        verifyAddNetworkHasEverConnectedFalse(wepNetwork);
1134        verifyUpdateNetworkAfterConnectHasEverConnectedTrue(wepNetwork.networkId);
1135
1136        // Now update the same network with a different wep.
1137        assertFalse(wepNetwork.wepTxKeyIndex == 3);
1138        wepNetwork.wepTxKeyIndex = 3;
1139        verifyUpdateNetworkWithCredentialChangeHasEverConnectedFalse(wepNetwork);
1140    }
1141
1142    /**
1143     * Verifies that hasEverConnected is cleared when a network config |allowedKeyManagement| is
1144     * updated.
1145     */
1146    @Test
1147    public void testUpdateAllowedKeyManagementClearsHasEverConnected() {
1148        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
1149        verifyAddNetworkHasEverConnectedFalse(pskNetwork);
1150        verifyUpdateNetworkAfterConnectHasEverConnectedTrue(pskNetwork.networkId);
1151
1152        assertFalse(pskNetwork.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.IEEE8021X));
1153        pskNetwork.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
1154        verifyUpdateNetworkWithCredentialChangeHasEverConnectedFalse(pskNetwork);
1155    }
1156
1157    /**
1158     * Verifies that hasEverConnected is cleared when a network config |allowedProtocol| is
1159     * updated.
1160     */
1161    @Test
1162    public void testUpdateProtocolsClearsHasEverConnected() {
1163        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
1164        verifyAddNetworkHasEverConnectedFalse(pskNetwork);
1165        verifyUpdateNetworkAfterConnectHasEverConnectedTrue(pskNetwork.networkId);
1166
1167        assertFalse(pskNetwork.allowedProtocols.get(WifiConfiguration.Protocol.OSEN));
1168        pskNetwork.allowedProtocols.set(WifiConfiguration.Protocol.OSEN);
1169        verifyUpdateNetworkWithCredentialChangeHasEverConnectedFalse(pskNetwork);
1170    }
1171
1172    /**
1173     * Verifies that hasEverConnected is cleared when a network config |allowedAuthAlgorithms| is
1174     * updated.
1175     */
1176    @Test
1177    public void testUpdateAllowedAuthAlgorithmsClearsHasEverConnected() {
1178        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
1179        verifyAddNetworkHasEverConnectedFalse(pskNetwork);
1180        verifyUpdateNetworkAfterConnectHasEverConnectedTrue(pskNetwork.networkId);
1181
1182        assertFalse(pskNetwork.allowedAuthAlgorithms.get(WifiConfiguration.AuthAlgorithm.LEAP));
1183        pskNetwork.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.LEAP);
1184        verifyUpdateNetworkWithCredentialChangeHasEverConnectedFalse(pskNetwork);
1185    }
1186
1187    /**
1188     * Verifies that hasEverConnected is cleared when a network config |allowedPairwiseCiphers| is
1189     * updated.
1190     */
1191    @Test
1192    public void testUpdateAllowedPairwiseCiphersClearsHasEverConnected() {
1193        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
1194        verifyAddNetworkHasEverConnectedFalse(pskNetwork);
1195        verifyUpdateNetworkAfterConnectHasEverConnectedTrue(pskNetwork.networkId);
1196
1197        assertFalse(pskNetwork.allowedPairwiseCiphers.get(WifiConfiguration.PairwiseCipher.NONE));
1198        pskNetwork.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.NONE);
1199        verifyUpdateNetworkWithCredentialChangeHasEverConnectedFalse(pskNetwork);
1200    }
1201
1202    /**
1203     * Verifies that hasEverConnected is cleared when a network config |allowedGroup| is
1204     * updated.
1205     */
1206    @Test
1207    public void testUpdateAllowedGroupCiphersClearsHasEverConnected() {
1208        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
1209        verifyAddNetworkHasEverConnectedFalse(pskNetwork);
1210        verifyUpdateNetworkAfterConnectHasEverConnectedTrue(pskNetwork.networkId);
1211
1212        assertTrue(pskNetwork.allowedGroupCiphers.get(WifiConfiguration.GroupCipher.WEP104));
1213        pskNetwork.allowedGroupCiphers.clear(WifiConfiguration.GroupCipher.WEP104);
1214        verifyUpdateNetworkWithCredentialChangeHasEverConnectedFalse(pskNetwork);
1215    }
1216
1217    /**
1218     * Verifies that hasEverConnected is cleared when a network config |hiddenSSID| is
1219     * updated.
1220     */
1221    @Test
1222    public void testUpdateHiddenSSIDClearsHasEverConnected() {
1223        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
1224        verifyAddNetworkHasEverConnectedFalse(pskNetwork);
1225        verifyUpdateNetworkAfterConnectHasEverConnectedTrue(pskNetwork.networkId);
1226
1227        assertFalse(pskNetwork.hiddenSSID);
1228        pskNetwork.hiddenSSID = true;
1229        verifyUpdateNetworkWithCredentialChangeHasEverConnectedFalse(pskNetwork);
1230    }
1231
1232    /**
1233     * Verifies that hasEverConnected is not cleared when a network config |requirePMF| is
1234     * updated.
1235     */
1236    @Test
1237    public void testUpdateRequirePMFDoesNotClearHasEverConnected() {
1238        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
1239        verifyAddNetworkHasEverConnectedFalse(pskNetwork);
1240        verifyUpdateNetworkAfterConnectHasEverConnectedTrue(pskNetwork.networkId);
1241
1242        assertFalse(pskNetwork.requirePMF);
1243        pskNetwork.requirePMF = true;
1244
1245        NetworkUpdateResult result =
1246                verifyUpdateNetworkToWifiConfigManagerWithoutIpChange(pskNetwork);
1247        WifiConfiguration retrievedNetwork =
1248                mWifiConfigManager.getConfiguredNetwork(result.getNetworkId());
1249        assertTrue("Updating network non-credentials config should not clear hasEverConnected.",
1250                retrievedNetwork.getNetworkSelectionStatus().getHasEverConnected());
1251    }
1252
1253    /**
1254     * Verifies that hasEverConnected is cleared when a network config |enterpriseConfig| is
1255     * updated.
1256     */
1257    @Test
1258    public void testUpdateEnterpriseConfigClearsHasEverConnected() {
1259        WifiConfiguration eapNetwork = WifiConfigurationTestUtil.createEapNetwork();
1260        eapNetwork.enterpriseConfig =
1261                WifiConfigurationTestUtil.createPEAPWifiEnterpriseConfigWithGTCPhase2();
1262        verifyAddNetworkHasEverConnectedFalse(eapNetwork);
1263        verifyUpdateNetworkAfterConnectHasEverConnectedTrue(eapNetwork.networkId);
1264
1265        assertFalse(eapNetwork.enterpriseConfig.getEapMethod() == WifiEnterpriseConfig.Eap.TLS);
1266        eapNetwork.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
1267        verifyUpdateNetworkWithCredentialChangeHasEverConnectedFalse(eapNetwork);
1268    }
1269
1270    /**
1271     * Verifies the ordering of network list generated using
1272     * {@link WifiConfigManager#retrievePnoNetworkList()}.
1273     */
1274    @Test
1275    public void testRetrievePnoList() {
1276        // Create and add 3 networks.
1277        WifiConfiguration network1 = WifiConfigurationTestUtil.createEapNetwork();
1278        WifiConfiguration network2 = WifiConfigurationTestUtil.createPskNetwork();
1279        WifiConfiguration network3 = WifiConfigurationTestUtil.createOpenHiddenNetwork();
1280        verifyAddNetworkToWifiConfigManager(network1);
1281        verifyAddNetworkToWifiConfigManager(network2);
1282        verifyAddNetworkToWifiConfigManager(network3);
1283
1284        // Enable all of them.
1285        assertTrue(mWifiConfigManager.enableNetwork(network1.networkId, false, TEST_CREATOR_UID));
1286        assertTrue(mWifiConfigManager.enableNetwork(network2.networkId, false, TEST_CREATOR_UID));
1287        assertTrue(mWifiConfigManager.enableNetwork(network3.networkId, false, TEST_CREATOR_UID));
1288
1289        // Now set scan results in 2 of them to set the corresponding
1290        // {@link NetworkSelectionStatus#mSeenInLastQualifiedNetworkSelection} field.
1291        assertTrue(mWifiConfigManager.setNetworkCandidateScanResult(
1292                network1.networkId, createScanDetailForNetwork(network1).getScanResult(), 54));
1293        assertTrue(mWifiConfigManager.setNetworkCandidateScanResult(
1294                network3.networkId, createScanDetailForNetwork(network3).getScanResult(), 54));
1295
1296        // Now increment |network3|'s association count. This should ensure that this network
1297        // is preferred over |network1|.
1298        assertTrue(mWifiConfigManager.updateNetworkAfterConnect(network3.networkId));
1299
1300        // Retrieve the Pno network list & verify the order of the networks returned.
1301        List<WifiScanner.PnoSettings.PnoNetwork> pnoNetworks =
1302                mWifiConfigManager.retrievePnoNetworkList();
1303        assertEquals(3, pnoNetworks.size());
1304        assertEquals(network3.SSID, pnoNetworks.get(0).ssid);
1305        assertEquals(network1.SSID, pnoNetworks.get(1).ssid);
1306        assertEquals(network2.SSID, pnoNetworks.get(2).ssid);
1307
1308        // Now permanently disable |network3|. This should remove network 3 from the list.
1309        assertTrue(mWifiConfigManager.disableNetwork(network3.networkId, TEST_CREATOR_UID));
1310
1311        // Retrieve the Pno network list again & verify the order of the networks returned.
1312        pnoNetworks = mWifiConfigManager.retrievePnoNetworkList();
1313        assertEquals(2, pnoNetworks.size());
1314        assertEquals(network1.SSID, pnoNetworks.get(0).ssid);
1315        assertEquals(network2.SSID, pnoNetworks.get(1).ssid);
1316    }
1317
1318    /**
1319     * Verifies the linking of networks when they have the same default GW Mac address in
1320     * {@link WifiConfigManager#getOrCreateScanDetailCacheForNetwork(WifiConfiguration)}.
1321     */
1322    @Test
1323    public void testNetworkLinkUsingGwMacAddress() {
1324        WifiConfiguration network1 = WifiConfigurationTestUtil.createPskNetwork();
1325        WifiConfiguration network2 = WifiConfigurationTestUtil.createPskNetwork();
1326        WifiConfiguration network3 = WifiConfigurationTestUtil.createPskNetwork();
1327        verifyAddNetworkToWifiConfigManager(network1);
1328        verifyAddNetworkToWifiConfigManager(network2);
1329        verifyAddNetworkToWifiConfigManager(network3);
1330
1331        // Set the same default GW mac address for all of the networks.
1332        assertTrue(mWifiConfigManager.setNetworkDefaultGwMacAddress(
1333                network1.networkId, TEST_DEFAULT_GW_MAC_ADDRESS));
1334        assertTrue(mWifiConfigManager.setNetworkDefaultGwMacAddress(
1335                network2.networkId, TEST_DEFAULT_GW_MAC_ADDRESS));
1336        assertTrue(mWifiConfigManager.setNetworkDefaultGwMacAddress(
1337                network3.networkId, TEST_DEFAULT_GW_MAC_ADDRESS));
1338
1339        // Now create dummy scan detail corresponding to the networks.
1340        ScanDetail networkScanDetail1 = createScanDetailForNetwork(network1);
1341        ScanDetail networkScanDetail2 = createScanDetailForNetwork(network2);
1342        ScanDetail networkScanDetail3 = createScanDetailForNetwork(network3);
1343
1344        // Now save all these scan details corresponding to each of this network and expect
1345        // all of these networks to be linked with each other.
1346        assertNotNull(mWifiConfigManager.getSavedNetworkForScanDetailAndCache(networkScanDetail1));
1347        assertNotNull(mWifiConfigManager.getSavedNetworkForScanDetailAndCache(networkScanDetail2));
1348        assertNotNull(mWifiConfigManager.getSavedNetworkForScanDetailAndCache(networkScanDetail3));
1349
1350        List<WifiConfiguration> retrievedNetworks =
1351                mWifiConfigManager.getConfiguredNetworks();
1352        for (WifiConfiguration network : retrievedNetworks) {
1353            assertEquals(2, network.linkedConfigurations.size());
1354            for (WifiConfiguration otherNetwork : retrievedNetworks) {
1355                if (otherNetwork == network) {
1356                    continue;
1357                }
1358                assertNotNull(network.linkedConfigurations.get(otherNetwork.configKey()));
1359            }
1360        }
1361    }
1362
1363    /**
1364     * Verifies the linking of networks when they have scan results with same first 16 ASCII of
1365     * bssid in
1366     * {@link WifiConfigManager#getOrCreateScanDetailCacheForNetwork(WifiConfiguration)}.
1367     */
1368    @Test
1369    public void testNetworkLinkUsingBSSIDMatch() {
1370        WifiConfiguration network1 = WifiConfigurationTestUtil.createPskNetwork();
1371        WifiConfiguration network2 = WifiConfigurationTestUtil.createPskNetwork();
1372        WifiConfiguration network3 = WifiConfigurationTestUtil.createPskNetwork();
1373        verifyAddNetworkToWifiConfigManager(network1);
1374        verifyAddNetworkToWifiConfigManager(network2);
1375        verifyAddNetworkToWifiConfigManager(network3);
1376
1377        // Create scan results with bssid which is different in only the last char.
1378        ScanDetail networkScanDetail1 = createScanDetailForNetwork(network1, "af:89:56:34:56:67");
1379        ScanDetail networkScanDetail2 = createScanDetailForNetwork(network2, "af:89:56:34:56:68");
1380        ScanDetail networkScanDetail3 = createScanDetailForNetwork(network3, "af:89:56:34:56:69");
1381
1382        // Now save all these scan details corresponding to each of this network and expect
1383        // all of these networks to be linked with each other.
1384        assertNotNull(mWifiConfigManager.getSavedNetworkForScanDetailAndCache(networkScanDetail1));
1385        assertNotNull(mWifiConfigManager.getSavedNetworkForScanDetailAndCache(networkScanDetail2));
1386        assertNotNull(mWifiConfigManager.getSavedNetworkForScanDetailAndCache(networkScanDetail3));
1387
1388        List<WifiConfiguration> retrievedNetworks =
1389                mWifiConfigManager.getConfiguredNetworks();
1390        for (WifiConfiguration network : retrievedNetworks) {
1391            assertEquals(2, network.linkedConfigurations.size());
1392            for (WifiConfiguration otherNetwork : retrievedNetworks) {
1393                if (otherNetwork == network) {
1394                    continue;
1395                }
1396                assertNotNull(network.linkedConfigurations.get(otherNetwork.configKey()));
1397            }
1398        }
1399    }
1400
1401    /**
1402     * Verifies the linking of networks does not happen for non WPA networks when they have scan
1403     * results with same first 16 ASCII of bssid in
1404     * {@link WifiConfigManager#getOrCreateScanDetailCacheForNetwork(WifiConfiguration)}.
1405     */
1406    @Test
1407    public void testNoNetworkLinkUsingBSSIDMatchForNonWpaNetworks() {
1408        WifiConfiguration network1 = WifiConfigurationTestUtil.createOpenNetwork();
1409        WifiConfiguration network2 = WifiConfigurationTestUtil.createPskNetwork();
1410        verifyAddNetworkToWifiConfigManager(network1);
1411        verifyAddNetworkToWifiConfigManager(network2);
1412
1413        // Create scan results with bssid which is different in only the last char.
1414        ScanDetail networkScanDetail1 = createScanDetailForNetwork(network1, "af:89:56:34:56:67");
1415        ScanDetail networkScanDetail2 = createScanDetailForNetwork(network2, "af:89:56:34:56:68");
1416
1417        assertNotNull(mWifiConfigManager.getSavedNetworkForScanDetailAndCache(networkScanDetail1));
1418        assertNotNull(mWifiConfigManager.getSavedNetworkForScanDetailAndCache(networkScanDetail2));
1419
1420        List<WifiConfiguration> retrievedNetworks =
1421                mWifiConfigManager.getConfiguredNetworks();
1422        for (WifiConfiguration network : retrievedNetworks) {
1423            assertNull(network.linkedConfigurations);
1424        }
1425    }
1426
1427    /**
1428     * Verifies the linking of networks does not happen for networks with more than
1429     * {@link WifiConfigManager#LINK_CONFIGURATION_MAX_SCAN_CACHE_ENTRIES} scan
1430     * results with same first 16 ASCII of bssid in
1431     * {@link WifiConfigManager#getOrCreateScanDetailCacheForNetwork(WifiConfiguration)}.
1432     */
1433    @Test
1434    public void testNoNetworkLinkUsingBSSIDMatchForNetworksWithHighScanDetailCacheSize() {
1435        WifiConfiguration network1 = WifiConfigurationTestUtil.createPskNetwork();
1436        WifiConfiguration network2 = WifiConfigurationTestUtil.createPskNetwork();
1437        verifyAddNetworkToWifiConfigManager(network1);
1438        verifyAddNetworkToWifiConfigManager(network2);
1439
1440        // Create 7 scan results with bssid which is different in only the last char.
1441        String test_bssid_base = "af:89:56:34:56:6";
1442        int scan_result_num = 0;
1443        for (; scan_result_num < WifiConfigManager.LINK_CONFIGURATION_MAX_SCAN_CACHE_ENTRIES + 1;
1444             scan_result_num++) {
1445            ScanDetail networkScanDetail =
1446                    createScanDetailForNetwork(
1447                            network1, test_bssid_base + Integer.toString(scan_result_num));
1448            assertNotNull(
1449                    mWifiConfigManager.getSavedNetworkForScanDetailAndCache(networkScanDetail));
1450        }
1451
1452        // Now add 1 scan result to the other network with bssid which is different in only the
1453        // last char.
1454        ScanDetail networkScanDetail2 =
1455                createScanDetailForNetwork(
1456                        network2, test_bssid_base + Integer.toString(scan_result_num++));
1457        assertNotNull(mWifiConfigManager.getSavedNetworkForScanDetailAndCache(networkScanDetail2));
1458
1459        List<WifiConfiguration> retrievedNetworks =
1460                mWifiConfigManager.getConfiguredNetworks();
1461        for (WifiConfiguration network : retrievedNetworks) {
1462            assertNull(network.linkedConfigurations);
1463        }
1464    }
1465
1466    /**
1467     * Verifies the linking of networks when they have scan results with same first 16 ASCII of
1468     * bssid in {@link WifiConfigManager#getOrCreateScanDetailCacheForNetwork(WifiConfiguration)}
1469     * and then subsequently delinked when the networks have default gateway set which do not match.
1470     */
1471    @Test
1472    public void testNetworkLinkUsingBSSIDMatchAndThenUnlinkDueToGwMacAddress() {
1473        WifiConfiguration network1 = WifiConfigurationTestUtil.createPskNetwork();
1474        WifiConfiguration network2 = WifiConfigurationTestUtil.createPskNetwork();
1475        verifyAddNetworkToWifiConfigManager(network1);
1476        verifyAddNetworkToWifiConfigManager(network2);
1477
1478        // Create scan results with bssid which is different in only the last char.
1479        ScanDetail networkScanDetail1 = createScanDetailForNetwork(network1, "af:89:56:34:56:67");
1480        ScanDetail networkScanDetail2 = createScanDetailForNetwork(network2, "af:89:56:34:56:68");
1481
1482        // Now save all these scan details corresponding to each of this network and expect
1483        // all of these networks to be linked with each other.
1484        assertNotNull(mWifiConfigManager.getSavedNetworkForScanDetailAndCache(networkScanDetail1));
1485        assertNotNull(mWifiConfigManager.getSavedNetworkForScanDetailAndCache(networkScanDetail2));
1486
1487        List<WifiConfiguration> retrievedNetworks =
1488                mWifiConfigManager.getConfiguredNetworks();
1489        for (WifiConfiguration network : retrievedNetworks) {
1490            assertEquals(1, network.linkedConfigurations.size());
1491            for (WifiConfiguration otherNetwork : retrievedNetworks) {
1492                if (otherNetwork == network) {
1493                    continue;
1494                }
1495                assertNotNull(network.linkedConfigurations.get(otherNetwork.configKey()));
1496            }
1497        }
1498
1499        // Now Set different GW mac address for both the networks and ensure they're unlinked.
1500        assertTrue(mWifiConfigManager.setNetworkDefaultGwMacAddress(
1501                network1.networkId, "de:ad:fe:45:23:34"));
1502        assertTrue(mWifiConfigManager.setNetworkDefaultGwMacAddress(
1503                network2.networkId, "ad:de:fe:45:23:34"));
1504
1505        // Add some dummy scan results again to re-evaluate the linking of networks.
1506        assertNotNull(mWifiConfigManager.getSavedNetworkForScanDetailAndCache(
1507                createScanDetailForNetwork(network1, "af:89:56:34:45:67")));
1508        assertNotNull(mWifiConfigManager.getSavedNetworkForScanDetailAndCache(
1509                createScanDetailForNetwork(network1, "af:89:56:34:45:68")));
1510
1511        retrievedNetworks = mWifiConfigManager.getConfiguredNetworks();
1512        for (WifiConfiguration network : retrievedNetworks) {
1513            assertNull(network.linkedConfigurations);
1514        }
1515    }
1516
1517    /**
1518     * Verifies the creation of channel list using
1519     * {@link WifiConfigManager#fetchChannelSetForNetworkForPartialScan(int, long, int)}.
1520     */
1521    @Test
1522    public void testFetchChannelSetForNetwork() {
1523        WifiConfiguration network = WifiConfigurationTestUtil.createPskNetwork();
1524        verifyAddNetworkToWifiConfigManager(network);
1525
1526        // Create 5 scan results with different bssid's & frequencies.
1527        String test_bssid_base = "af:89:56:34:56:6";
1528        for (int i = 0; i < TEST_FREQ_LIST.length; i++) {
1529            ScanDetail networkScanDetail =
1530                    createScanDetailForNetwork(
1531                            network, test_bssid_base + Integer.toString(i), 0, TEST_FREQ_LIST[i]);
1532            assertNotNull(
1533                    mWifiConfigManager.getSavedNetworkForScanDetailAndCache(networkScanDetail));
1534
1535        }
1536        assertEquals(new HashSet<Integer>(Arrays.asList(TEST_FREQ_LIST)),
1537                mWifiConfigManager.fetchChannelSetForNetworkForPartialScan(network.networkId, 1,
1538                        TEST_FREQ_LIST[4]));
1539    }
1540
1541    /**
1542     * Verifies the creation of channel list using
1543     * {@link WifiConfigManager#fetchChannelSetForNetworkForPartialScan(int, long, int)} and
1544     * ensures that the frequenecy of the currently connected network is in the returned
1545     * channel set.
1546     */
1547    @Test
1548    public void testFetchChannelSetForNetworkIncludeCurrentNetwork() {
1549        WifiConfiguration network = WifiConfigurationTestUtil.createPskNetwork();
1550        verifyAddNetworkToWifiConfigManager(network);
1551
1552        // Create 5 scan results with different bssid's & frequencies.
1553        String test_bssid_base = "af:89:56:34:56:6";
1554        for (int i = 0; i < TEST_FREQ_LIST.length; i++) {
1555            ScanDetail networkScanDetail =
1556                    createScanDetailForNetwork(
1557                            network, test_bssid_base + Integer.toString(i), 0, TEST_FREQ_LIST[i]);
1558            assertNotNull(
1559                    mWifiConfigManager.getSavedNetworkForScanDetailAndCache(networkScanDetail));
1560
1561        }
1562
1563        // Currently connected network frequency 2427 is not in the TEST_FREQ_LIST
1564        Set<Integer> freqs = mWifiConfigManager.fetchChannelSetForNetworkForPartialScan(
1565                network.networkId, 1, 2427);
1566
1567        assertEquals(true, freqs.contains(2427));
1568    }
1569
1570    /**
1571     * Verifies the creation of channel list using
1572     * {@link WifiConfigManager#fetchChannelSetForNetworkForPartialScan(int, long, int)} and
1573     * ensures that scan results which have a timestamp  beyond the provided age are not used
1574     * in the channel list.
1575     */
1576    @Test
1577    public void testFetchChannelSetForNetworkIgnoresStaleScanResults() {
1578        WifiConfiguration network = WifiConfigurationTestUtil.createPskNetwork();
1579        verifyAddNetworkToWifiConfigManager(network);
1580
1581        long wallClockBase = 0;
1582        // Create 5 scan results with different bssid's & frequencies.
1583        String test_bssid_base = "af:89:56:34:56:6";
1584        for (int i = 0; i < TEST_FREQ_LIST.length; i++) {
1585            // Increment the seen value in the scan results for each of them.
1586            when(mClock.getWallClockMillis()).thenReturn(wallClockBase + i);
1587            ScanDetail networkScanDetail =
1588                    createScanDetailForNetwork(
1589                            network, test_bssid_base + Integer.toString(i), 0, TEST_FREQ_LIST[i]);
1590            assertNotNull(
1591                    mWifiConfigManager.getSavedNetworkForScanDetailAndCache(networkScanDetail));
1592
1593        }
1594        int ageInMillis = 4;
1595        // Now fetch only scan results which are 4 millis stale. This should ignore the first
1596        // scan result.
1597        assertEquals(
1598                new HashSet<>(Arrays.asList(
1599                        Arrays.copyOfRange(
1600                                TEST_FREQ_LIST,
1601                                TEST_FREQ_LIST.length - ageInMillis, TEST_FREQ_LIST.length))),
1602                mWifiConfigManager.fetchChannelSetForNetworkForPartialScan(
1603                        network.networkId, ageInMillis, TEST_FREQ_LIST[4]));
1604    }
1605
1606    /**
1607     * Verifies the creation of channel list using
1608     * {@link WifiConfigManager#fetchChannelSetForNetworkForPartialScan(int, long, int)} and
1609     * ensures that the list size does not exceed the max configured for the device.
1610     */
1611    @Test
1612    public void testFetchChannelSetForNetworkIsLimitedToConfiguredSize() {
1613        // Need to recreate the WifiConfigManager instance for this test to modify the config
1614        // value which is read only in the constructor.
1615        int maxListSize = 3;
1616        mResources.setInteger(
1617                R.integer.config_wifi_framework_associated_partial_scan_max_num_active_channels,
1618                maxListSize);
1619        createWifiConfigManager();
1620
1621        WifiConfiguration network = WifiConfigurationTestUtil.createPskNetwork();
1622        verifyAddNetworkToWifiConfigManager(network);
1623
1624        // Create 5 scan results with different bssid's & frequencies.
1625        String test_bssid_base = "af:89:56:34:56:6";
1626        for (int i = 0; i < TEST_FREQ_LIST.length; i++) {
1627            ScanDetail networkScanDetail =
1628                    createScanDetailForNetwork(
1629                            network, test_bssid_base + Integer.toString(i), 0, TEST_FREQ_LIST[i]);
1630            assertNotNull(
1631                    mWifiConfigManager.getSavedNetworkForScanDetailAndCache(networkScanDetail));
1632
1633        }
1634        // Ensure that the fetched list size is limited.
1635        assertEquals(maxListSize,
1636                mWifiConfigManager.fetchChannelSetForNetworkForPartialScan(
1637                        network.networkId, 1, TEST_FREQ_LIST[4]).size());
1638    }
1639
1640    /**
1641     * Verifies the creation of channel list using
1642     * {@link WifiConfigManager#fetchChannelSetForNetworkForPartialScan(int, long, int)} and
1643     * ensures that scan results from linked networks are used in the channel list.
1644     */
1645    @Test
1646    public void testFetchChannelSetForNetworkIncludesLinkedNetworks() {
1647        WifiConfiguration network1 = WifiConfigurationTestUtil.createPskNetwork();
1648        WifiConfiguration network2 = WifiConfigurationTestUtil.createPskNetwork();
1649        verifyAddNetworkToWifiConfigManager(network1);
1650        verifyAddNetworkToWifiConfigManager(network2);
1651
1652        String test_bssid_base = "af:89:56:34:56:6";
1653        int TEST_FREQ_LISTIdx = 0;
1654        // Create 3 scan results with different bssid's & frequencies for network 1.
1655        for (; TEST_FREQ_LISTIdx < TEST_FREQ_LIST.length / 2; TEST_FREQ_LISTIdx++) {
1656            ScanDetail networkScanDetail =
1657                    createScanDetailForNetwork(
1658                            network1, test_bssid_base + Integer.toString(TEST_FREQ_LISTIdx), 0,
1659                            TEST_FREQ_LIST[TEST_FREQ_LISTIdx]);
1660            assertNotNull(
1661                    mWifiConfigManager.getSavedNetworkForScanDetailAndCache(networkScanDetail));
1662
1663        }
1664        // Create 3 scan results with different bssid's & frequencies for network 2.
1665        for (; TEST_FREQ_LISTIdx < TEST_FREQ_LIST.length; TEST_FREQ_LISTIdx++) {
1666            ScanDetail networkScanDetail =
1667                    createScanDetailForNetwork(
1668                            network2, test_bssid_base + Integer.toString(TEST_FREQ_LISTIdx), 0,
1669                            TEST_FREQ_LIST[TEST_FREQ_LISTIdx]);
1670            assertNotNull(
1671                    mWifiConfigManager.getSavedNetworkForScanDetailAndCache(networkScanDetail));
1672        }
1673
1674        // Link the 2 configurations together using the GwMacAddress.
1675        assertTrue(mWifiConfigManager.setNetworkDefaultGwMacAddress(
1676                network1.networkId, TEST_DEFAULT_GW_MAC_ADDRESS));
1677        assertTrue(mWifiConfigManager.setNetworkDefaultGwMacAddress(
1678                network2.networkId, TEST_DEFAULT_GW_MAC_ADDRESS));
1679
1680        // The channel list fetched should include scan results from both the linked networks.
1681        assertEquals(new HashSet<Integer>(Arrays.asList(TEST_FREQ_LIST)),
1682                mWifiConfigManager.fetchChannelSetForNetworkForPartialScan(network1.networkId, 1,
1683                        TEST_FREQ_LIST[0]));
1684        assertEquals(new HashSet<Integer>(Arrays.asList(TEST_FREQ_LIST)),
1685                mWifiConfigManager.fetchChannelSetForNetworkForPartialScan(network2.networkId, 1,
1686                        TEST_FREQ_LIST[0]));
1687    }
1688
1689    /**
1690     * Verifies the creation of channel list using
1691     * {@link WifiConfigManager#fetchChannelSetForNetworkForPartialScan(int, long, int)} and
1692     * ensures that scan results from linked networks are used in the channel list and that the
1693     * list size does not exceed the max configured for the device.
1694     */
1695    @Test
1696    public void testFetchChannelSetForNetworkIncludesLinkedNetworksIsLimitedToConfiguredSize() {
1697        // Need to recreate the WifiConfigManager instance for this test to modify the config
1698        // value which is read only in the constructor.
1699        int maxListSize = 3;
1700        mResources.setInteger(
1701                R.integer.config_wifi_framework_associated_partial_scan_max_num_active_channels,
1702                maxListSize);
1703
1704        createWifiConfigManager();
1705        WifiConfiguration network1 = WifiConfigurationTestUtil.createPskNetwork();
1706        WifiConfiguration network2 = WifiConfigurationTestUtil.createPskNetwork();
1707        verifyAddNetworkToWifiConfigManager(network1);
1708        verifyAddNetworkToWifiConfigManager(network2);
1709
1710        String test_bssid_base = "af:89:56:34:56:6";
1711        int TEST_FREQ_LISTIdx = 0;
1712        // Create 3 scan results with different bssid's & frequencies for network 1.
1713        for (; TEST_FREQ_LISTIdx < TEST_FREQ_LIST.length / 2; TEST_FREQ_LISTIdx++) {
1714            ScanDetail networkScanDetail =
1715                    createScanDetailForNetwork(
1716                            network1, test_bssid_base + Integer.toString(TEST_FREQ_LISTIdx), 0,
1717                            TEST_FREQ_LIST[TEST_FREQ_LISTIdx]);
1718            assertNotNull(
1719                    mWifiConfigManager.getSavedNetworkForScanDetailAndCache(networkScanDetail));
1720
1721        }
1722        // Create 3 scan results with different bssid's & frequencies for network 2.
1723        for (; TEST_FREQ_LISTIdx < TEST_FREQ_LIST.length; TEST_FREQ_LISTIdx++) {
1724            ScanDetail networkScanDetail =
1725                    createScanDetailForNetwork(
1726                            network2, test_bssid_base + Integer.toString(TEST_FREQ_LISTIdx), 0,
1727                            TEST_FREQ_LIST[TEST_FREQ_LISTIdx]);
1728            assertNotNull(
1729                    mWifiConfigManager.getSavedNetworkForScanDetailAndCache(networkScanDetail));
1730        }
1731
1732        // Link the 2 configurations together using the GwMacAddress.
1733        assertTrue(mWifiConfigManager.setNetworkDefaultGwMacAddress(
1734                network1.networkId, TEST_DEFAULT_GW_MAC_ADDRESS));
1735        assertTrue(mWifiConfigManager.setNetworkDefaultGwMacAddress(
1736                network2.networkId, TEST_DEFAULT_GW_MAC_ADDRESS));
1737
1738        // Ensure that the fetched list size is limited.
1739        assertEquals(maxListSize,
1740                mWifiConfigManager.fetchChannelSetForNetworkForPartialScan(
1741                        network1.networkId, 1, TEST_FREQ_LIST[0]).size());
1742        assertEquals(maxListSize,
1743                mWifiConfigManager.fetchChannelSetForNetworkForPartialScan(
1744                        network2.networkId, 1, TEST_FREQ_LIST[0]).size());
1745    }
1746
1747    /**
1748     * Verifies the foreground user switch using {@link WifiConfigManager#handleUserSwitch(int)}
1749     * and ensures that any shared private networks networkId is not changed.
1750     * Test scenario:
1751     * 1. Load the shared networks from shared store and user 1 store.
1752     * 2. Switch to user 2 and ensure that the shared network's Id is not changed.
1753     */
1754    @Test
1755    public void testHandleUserSwitchDoesNotChangeSharedNetworksId() throws Exception {
1756        int user1 = TEST_DEFAULT_USER;
1757        int user2 = TEST_DEFAULT_USER + 1;
1758        setupUserProfiles(user2);
1759
1760        int appId = 674;
1761
1762        // Create 3 networks. 1 for user1, 1 for user2 and 1 shared.
1763        final WifiConfiguration user1Network = WifiConfigurationTestUtil.createPskNetwork();
1764        user1Network.shared = false;
1765        user1Network.creatorUid = UserHandle.getUid(user1, appId);
1766        final WifiConfiguration user2Network = WifiConfigurationTestUtil.createPskNetwork();
1767        user2Network.shared = false;
1768        user2Network.creatorUid = UserHandle.getUid(user2, appId);
1769        final WifiConfiguration sharedNetwork1 = WifiConfigurationTestUtil.createPskNetwork();
1770        final WifiConfiguration sharedNetwork2 = WifiConfigurationTestUtil.createPskNetwork();
1771
1772        // Set up the store data that is loaded initially.
1773        List<WifiConfiguration> sharedNetworks = new ArrayList<WifiConfiguration>() {
1774            {
1775                add(sharedNetwork1);
1776                add(sharedNetwork2);
1777            }
1778        };
1779        List<WifiConfiguration> user1Networks = new ArrayList<WifiConfiguration>() {
1780            {
1781                add(user1Network);
1782            }
1783        };
1784        WifiConfigStoreData loadStoreData =
1785                new WifiConfigStoreData(sharedNetworks, user1Networks, new HashSet<String>());
1786        when(mWifiConfigStore.read()).thenReturn(loadStoreData);
1787        assertTrue(mWifiConfigManager.loadFromStore());
1788
1789        // Fetch the network ID's assigned to the shared networks initially.
1790        int sharedNetwork1Id = WifiConfiguration.INVALID_NETWORK_ID;
1791        int sharedNetwork2Id = WifiConfiguration.INVALID_NETWORK_ID;
1792        List<WifiConfiguration> retrievedNetworks =
1793                mWifiConfigManager.getConfiguredNetworksWithPasswords();
1794        for (WifiConfiguration network : retrievedNetworks) {
1795            if (network.configKey().equals(sharedNetwork1.configKey())) {
1796                sharedNetwork1Id = network.networkId;
1797            } else if (network.configKey().equals(sharedNetwork2.configKey())) {
1798                sharedNetwork2Id = network.networkId;
1799            }
1800        }
1801        assertTrue(sharedNetwork1Id != WifiConfiguration.INVALID_NETWORK_ID);
1802        assertTrue(sharedNetwork2Id != WifiConfiguration.INVALID_NETWORK_ID);
1803
1804        // Set up the user 2 store data that is loaded at user switch.
1805        List<WifiConfiguration> user2Networks = new ArrayList<WifiConfiguration>() {
1806            {
1807                add(user2Network);
1808            }
1809        };
1810        WifiConfigStoreData newUserStoreData =
1811                new WifiConfigStoreData(new ArrayList<WifiConfiguration>(), user2Networks,
1812                        new HashSet<String>());
1813        when(mWifiConfigStore.switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class)))
1814                .thenReturn(newUserStoreData);
1815        // Now switch the user to user 2 and ensure that shared network's IDs have not changed.
1816        when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(true);
1817        mWifiConfigManager.handleUserSwitch(user2);
1818
1819        // Again fetch the network ID's assigned to the shared networks and ensure they have not
1820        // changed.
1821        int updatedSharedNetwork1Id = WifiConfiguration.INVALID_NETWORK_ID;
1822        int updatedSharedNetwork2Id = WifiConfiguration.INVALID_NETWORK_ID;
1823        retrievedNetworks = mWifiConfigManager.getConfiguredNetworksWithPasswords();
1824        for (WifiConfiguration network : retrievedNetworks) {
1825            if (network.configKey().equals(sharedNetwork1.configKey())) {
1826                updatedSharedNetwork1Id = network.networkId;
1827            } else if (network.configKey().equals(sharedNetwork2.configKey())) {
1828                updatedSharedNetwork2Id = network.networkId;
1829            }
1830        }
1831        assertEquals(sharedNetwork1Id, updatedSharedNetwork1Id);
1832        assertEquals(sharedNetwork2Id, updatedSharedNetwork2Id);
1833    }
1834
1835    /**
1836     * Verifies the foreground user switch using {@link WifiConfigManager#handleUserSwitch(int)}
1837     * and ensures that any old user private networks are not visible anymore.
1838     * Test scenario:
1839     * 1. Load the shared networks from shared store and user 1 store.
1840     * 2. Switch to user 2 and ensure that the user 1's private network has been removed.
1841     */
1842    @Test
1843    public void testHandleUserSwitchRemovesOldUserPrivateNetworks() throws Exception {
1844        int user1 = TEST_DEFAULT_USER;
1845        int user2 = TEST_DEFAULT_USER + 1;
1846        setupUserProfiles(user2);
1847
1848        int appId = 674;
1849
1850        // Create 3 networks. 1 for user1, 1 for user2 and 1 shared.
1851        final WifiConfiguration user1Network = WifiConfigurationTestUtil.createPskNetwork();
1852        user1Network.shared = false;
1853        user1Network.creatorUid = UserHandle.getUid(user1, appId);
1854        final WifiConfiguration user2Network = WifiConfigurationTestUtil.createPskNetwork();
1855        user2Network.shared = false;
1856        user2Network.creatorUid = UserHandle.getUid(user2, appId);
1857        final WifiConfiguration sharedNetwork = WifiConfigurationTestUtil.createPskNetwork();
1858
1859        // Set up the store data that is loaded initially.
1860        List<WifiConfiguration> sharedNetworks = new ArrayList<WifiConfiguration>() {
1861            {
1862                add(sharedNetwork);
1863            }
1864        };
1865        List<WifiConfiguration> user1Networks = new ArrayList<WifiConfiguration>() {
1866            {
1867                add(user1Network);
1868            }
1869        };
1870        WifiConfigStoreData loadStoreData =
1871                new WifiConfigStoreData(sharedNetworks, user1Networks, new HashSet<String>());
1872        when(mWifiConfigStore.read()).thenReturn(loadStoreData);
1873        assertTrue(mWifiConfigManager.loadFromStore());
1874
1875        // Fetch the network ID assigned to the user 1 network initially.
1876        int user1NetworkId = WifiConfiguration.INVALID_NETWORK_ID;
1877        List<WifiConfiguration> retrievedNetworks =
1878                mWifiConfigManager.getConfiguredNetworksWithPasswords();
1879        for (WifiConfiguration network : retrievedNetworks) {
1880            if (network.configKey().equals(user1Network.configKey())) {
1881                user1NetworkId = network.networkId;
1882            }
1883        }
1884
1885        // Set up the user 2 store data that is loaded at user switch.
1886        List<WifiConfiguration> user2Networks = new ArrayList<WifiConfiguration>() {
1887            {
1888                add(user2Network);
1889            }
1890        };
1891        WifiConfigStoreData newUserStoreData =
1892                new WifiConfigStoreData(new ArrayList<WifiConfiguration>(), user2Networks,
1893                        new HashSet<String>());
1894        when(mWifiConfigStore.switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class)))
1895                .thenReturn(newUserStoreData);
1896        // Now switch the user to user 2 and ensure that user 1's private network has been removed.
1897        when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(true);
1898        Set<Integer> removedNetworks = mWifiConfigManager.handleUserSwitch(user2);
1899        assertTrue((removedNetworks.size() == 1) && (removedNetworks.contains(user1NetworkId)));
1900
1901        // Set the expected networks to be |sharedNetwork| and |user2Network|.
1902        List<WifiConfiguration> expectedNetworks = new ArrayList<WifiConfiguration>() {
1903            {
1904                add(sharedNetwork);
1905                add(user2Network);
1906            }
1907        };
1908        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
1909                expectedNetworks, mWifiConfigManager.getConfiguredNetworksWithPasswords());
1910
1911        // Send another user switch  indication with the same user 2. This should be ignored and
1912        // hence should not remove any new networks.
1913        when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(true);
1914        removedNetworks = mWifiConfigManager.handleUserSwitch(user2);
1915        assertTrue(removedNetworks.isEmpty());
1916    }
1917
1918    /**
1919     * Verifies the foreground user switch using {@link WifiConfigManager#handleUserSwitch(int)}
1920     * and ensures that user switch from a user with no private networks is handled.
1921     * Test scenario:
1922     * 1. Load the shared networks from shared store and emptu user 1 store.
1923     * 2. Switch to user 2 and ensure that no private networks were removed.
1924     */
1925    @Test
1926    public void testHandleUserSwitchWithNoOldUserPrivateNetworks() throws Exception {
1927        int user1 = TEST_DEFAULT_USER;
1928        int user2 = TEST_DEFAULT_USER + 1;
1929        setupUserProfiles(user2);
1930
1931        int appId = 674;
1932
1933        // Create 2 networks. 1 for user2 and 1 shared.
1934        final WifiConfiguration user2Network = WifiConfigurationTestUtil.createPskNetwork();
1935        user2Network.shared = false;
1936        user2Network.creatorUid = UserHandle.getUid(user2, appId);
1937        final WifiConfiguration sharedNetwork = WifiConfigurationTestUtil.createPskNetwork();
1938
1939        // Set up the store data that is loaded initially.
1940        List<WifiConfiguration> sharedNetworks = new ArrayList<WifiConfiguration>() {
1941            {
1942                add(sharedNetwork);
1943            }
1944        };
1945        WifiConfigStoreData loadStoreData =
1946                new WifiConfigStoreData(sharedNetworks, new ArrayList<WifiConfiguration>(),
1947                        new HashSet<String>());
1948        when(mWifiConfigStore.read()).thenReturn(loadStoreData);
1949        assertTrue(mWifiConfigManager.loadFromStore());
1950
1951        // Set up the user 2 store data that is loaded at user switch.
1952        List<WifiConfiguration> user2Networks = new ArrayList<WifiConfiguration>() {
1953            {
1954                add(user2Network);
1955            }
1956        };
1957        WifiConfigStoreData newUserStoreData =
1958                new WifiConfigStoreData(new ArrayList<WifiConfiguration>(), user2Networks,
1959                        new HashSet<String>());
1960        when(mWifiConfigStore.switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class)))
1961                .thenReturn(newUserStoreData);
1962        // Now switch the user to user 2 and ensure that no private network has been removed.
1963        when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(true);
1964        Set<Integer> removedNetworks = mWifiConfigManager.handleUserSwitch(user2);
1965        assertTrue(removedNetworks.isEmpty());
1966    }
1967
1968    /**
1969     * Verifies the foreground user switch using {@link WifiConfigManager#handleUserSwitch(int)}
1970     * and ensures that any non current user private networks are moved to shared store file.
1971     * This test simulates the following test case:
1972     * 1. Loads the shared networks from shared store at bootup.
1973     * 2. Load the private networks from user store on user 1 unlock.
1974     * 3. Switch to user 2 and ensure that the user 2's private network has been moved to user 2's
1975     * private store file.
1976     */
1977    @Test
1978    public void testHandleUserSwitchPushesOtherPrivateNetworksToSharedStore() throws Exception {
1979        int user1 = TEST_DEFAULT_USER;
1980        int user2 = TEST_DEFAULT_USER + 1;
1981        setupUserProfiles(user2);
1982
1983        int appId = 674;
1984
1985        // Create 3 networks. 1 for user1, 1 for user2 and 1 shared.
1986        final WifiConfiguration user1Network = WifiConfigurationTestUtil.createPskNetwork();
1987        user1Network.shared = false;
1988        user1Network.creatorUid = UserHandle.getUid(user1, appId);
1989        final WifiConfiguration user2Network = WifiConfigurationTestUtil.createPskNetwork();
1990        user2Network.shared = false;
1991        user2Network.creatorUid = UserHandle.getUid(user2, appId);
1992        final WifiConfiguration sharedNetwork = WifiConfigurationTestUtil.createPskNetwork();
1993
1994        // Set up the shared store data that is loaded at bootup. User 2's private network
1995        // is still in shared store because they have not yet logged-in after upgrade.
1996        List<WifiConfiguration> sharedNetworks = new ArrayList<WifiConfiguration>() {
1997            {
1998                add(sharedNetwork);
1999                add(user2Network);
2000            }
2001        };
2002        WifiConfigStoreData loadStoreData =
2003                new WifiConfigStoreData(sharedNetworks, new ArrayList<WifiConfiguration>(),
2004                        new HashSet<String>());
2005        when(mWifiConfigStore.read()).thenReturn(loadStoreData);
2006        assertTrue(mWifiConfigManager.loadFromStore());
2007
2008        // Set up the user store data that is loaded at user unlock.
2009        List<WifiConfiguration> userNetworks = new ArrayList<WifiConfiguration>() {
2010            {
2011                add(user1Network);
2012            }
2013        };
2014        WifiConfigStoreData unlockLoadStoreData =
2015                new WifiConfigStoreData(new ArrayList<WifiConfiguration>(), userNetworks,
2016                        new HashSet<String>());
2017        when(mWifiConfigStore.switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class)))
2018                .thenReturn(unlockLoadStoreData);
2019        mWifiConfigManager.handleUserUnlock(user1);
2020        // Capture the written data for the user 1 and ensure that it corresponds to what was
2021        // setup.
2022        WifiConfigStoreData writtenStoreData = captureWriteStoreData();
2023        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
2024                sharedNetworks, writtenStoreData.getSharedConfigurations());
2025        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
2026                userNetworks, writtenStoreData.getUserConfigurations());
2027
2028        // Now switch the user to user2 and ensure that user 2's private network has been moved to
2029        // the user store.
2030        when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(true);
2031        mWifiConfigManager.handleUserSwitch(user2);
2032        // Set the expected network list before comparing. user1Network should be in shared data.
2033        // Note: In the real world, user1Network will no longer be visible now because it should
2034        // already be in user1's private store file. But, we're purposefully exposing it
2035        // via |loadStoreData| to test if other user's private networks are pushed to shared store.
2036        List<WifiConfiguration> expectedSharedNetworks = new ArrayList<WifiConfiguration>() {
2037            {
2038                add(sharedNetwork);
2039                add(user1Network);
2040            }
2041        };
2042        List<WifiConfiguration> expectedUserNetworks = new ArrayList<WifiConfiguration>() {
2043            {
2044                add(user2Network);
2045            }
2046        };
2047        // Capture the first written data triggered for saving the old user's network
2048        // configurations.
2049        writtenStoreData = captureWriteStoreData();
2050        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
2051                sharedNetworks, writtenStoreData.getSharedConfigurations());
2052        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
2053                userNetworks, writtenStoreData.getUserConfigurations());
2054
2055        // Now capture the next written data triggered after the switch and ensure that user 2's
2056        // network is now in user store data.
2057        writtenStoreData = captureWriteStoreData();
2058        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
2059                expectedSharedNetworks, writtenStoreData.getSharedConfigurations());
2060        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
2061                expectedUserNetworks, writtenStoreData.getUserConfigurations());
2062    }
2063
2064    /**
2065     * Verifies the foreground user switch using {@link WifiConfigManager#handleUserSwitch(int)}
2066     * and {@link WifiConfigManager#handleUserUnlock(int)} and ensures that the new store is
2067     * read immediately if the user is unlocked during the switch.
2068     */
2069    @Test
2070    public void testHandleUserSwitchWhenUnlocked() throws Exception {
2071        int user1 = TEST_DEFAULT_USER;
2072        int user2 = TEST_DEFAULT_USER + 1;
2073        setupUserProfiles(user2);
2074
2075        // Set up the internal data first.
2076        assertTrue(mWifiConfigManager.loadFromStore());
2077
2078        when(mWifiConfigStore.switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class)))
2079                .thenReturn(new WifiConfigStoreData(
2080                        new ArrayList<WifiConfiguration>(), new ArrayList<WifiConfiguration>(),
2081                        new HashSet<String>()));
2082
2083        // user2 is unlocked and switched to foreground.
2084        when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(true);
2085        mWifiConfigManager.handleUserSwitch(user2);
2086        // Ensure that the read was invoked.
2087        mContextConfigStoreMockOrder.verify(mWifiConfigStore)
2088                .switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class));
2089    }
2090
2091    /**
2092     * Verifies the foreground user switch using {@link WifiConfigManager#handleUserSwitch(int)}
2093     * and {@link WifiConfigManager#handleUserUnlock(int)} and ensures that the new store is not
2094     * read until the user is unlocked.
2095     */
2096    public void testHandleUserSwitchWhenLocked() throws Exception {
2097        int user1 = TEST_DEFAULT_USER;
2098        int user2 = TEST_DEFAULT_USER + 1;
2099        setupUserProfiles(user2);
2100
2101        // Set up the internal data first.
2102        assertTrue(mWifiConfigManager.loadFromStore());
2103
2104        // user2 is locked and switched to foreground.
2105        when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(false);
2106        mWifiConfigManager.handleUserSwitch(user2);
2107
2108        // Ensure that the read was not invoked.
2109        mContextConfigStoreMockOrder.verify(mWifiConfigStore, never())
2110                .switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class));
2111
2112        // Now try unlocking some other user (user1), this should be ignored.
2113        mWifiConfigManager.handleUserUnlock(user1);
2114        mContextConfigStoreMockOrder.verify(mWifiConfigStore, never())
2115                .switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class));
2116
2117        when(mWifiConfigStore.switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class)))
2118                .thenReturn(new WifiConfigStoreData(
2119                        new ArrayList<WifiConfiguration>(), new ArrayList<WifiConfiguration>(),
2120                        new HashSet<String>()));
2121
2122        // Unlock the user2 and ensure that we read the data now.
2123        mWifiConfigManager.handleUserUnlock(user2);
2124        mContextConfigStoreMockOrder.verify(mWifiConfigStore)
2125                .switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class));
2126    }
2127
2128    /**
2129     * Verifies that the foreground user stop using {@link WifiConfigManager#handleUserStop(int)}
2130     * and ensures that the store is written only when the foreground user is stopped.
2131     */
2132    @Test
2133    public void testHandleUserStop() throws Exception {
2134        int user1 = TEST_DEFAULT_USER;
2135        int user2 = TEST_DEFAULT_USER + 1;
2136        setupUserProfiles(user2);
2137
2138        // Try stopping background user2 first, this should not do anything.
2139        when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(false);
2140        mWifiConfigManager.handleUserStop(user2);
2141        mContextConfigStoreMockOrder.verify(mWifiConfigStore, never())
2142                .switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class));
2143
2144        // Now try stopping the foreground user1, this should trigger a write to store.
2145        mWifiConfigManager.handleUserStop(user1);
2146        mContextConfigStoreMockOrder.verify(mWifiConfigStore, never())
2147                .switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class));
2148        mContextConfigStoreMockOrder.verify(mWifiConfigStore).write(
2149                anyBoolean(), any(WifiConfigStoreData.class));
2150    }
2151
2152    /**
2153     * Verifies the foreground user unlock via {@link WifiConfigManager#handleUserUnlock(int)}
2154     * results in a store read after bootup.
2155     */
2156    @Test
2157    public void testHandleUserUnlockAfterBootup() throws Exception {
2158        int user1 = TEST_DEFAULT_USER;
2159
2160        // Set up the internal data first.
2161        assertTrue(mWifiConfigManager.loadFromStore());
2162        mContextConfigStoreMockOrder.verify(mWifiConfigStore).read();
2163        mContextConfigStoreMockOrder.verify(mWifiConfigStore, never())
2164                .write(anyBoolean(), any(WifiConfigStoreData.class));
2165        mContextConfigStoreMockOrder.verify(mWifiConfigStore, never())
2166                .switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class));
2167
2168        when(mWifiConfigStore.switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class)))
2169                .thenReturn(new WifiConfigStoreData(
2170                        new ArrayList<WifiConfiguration>(), new ArrayList<WifiConfiguration>(),
2171                        new HashSet<String>()));
2172
2173        // Unlock the user1 (default user) for the first time and ensure that we read the data.
2174        mWifiConfigManager.handleUserUnlock(user1);
2175        mContextConfigStoreMockOrder.verify(mWifiConfigStore, never()).read();
2176        mContextConfigStoreMockOrder.verify(mWifiConfigStore)
2177                .switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class));
2178        mContextConfigStoreMockOrder.verify(mWifiConfigStore)
2179                .write(anyBoolean(), any(WifiConfigStoreData.class));
2180    }
2181
2182    /**
2183     * Verifies that the store read after bootup received after
2184     * foreground user unlock via {@link WifiConfigManager#handleUserUnlock(int)}
2185     * results in a user store read.
2186     */
2187    @Test
2188    public void testHandleBootupAfterUserUnlock() throws Exception {
2189        int user1 = TEST_DEFAULT_USER;
2190
2191        // Unlock the user1 (default user) for the first time and ensure that we don't read the
2192        // data.
2193        mWifiConfigManager.handleUserUnlock(user1);
2194        mContextConfigStoreMockOrder.verify(mWifiConfigStore, never()).read();
2195        mContextConfigStoreMockOrder.verify(mWifiConfigStore, never())
2196                .write(anyBoolean(), any(WifiConfigStoreData.class));
2197        mContextConfigStoreMockOrder.verify(mWifiConfigStore, never())
2198                .switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class));
2199
2200        when(mWifiConfigStore.switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class)))
2201                .thenReturn(new WifiConfigStoreData(
2202                        new ArrayList<WifiConfiguration>(), new ArrayList<WifiConfiguration>(),
2203                        new HashSet<String>()));
2204
2205        // Read from store now.
2206        assertTrue(mWifiConfigManager.loadFromStore());
2207        mContextConfigStoreMockOrder.verify(mWifiConfigStore).read();
2208        mContextConfigStoreMockOrder.verify(mWifiConfigStore)
2209                .switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class));
2210        mContextConfigStoreMockOrder.verify(mWifiConfigStore)
2211                .write(anyBoolean(), any(WifiConfigStoreData.class));
2212    }
2213
2214    /**
2215     * Verifies the foreground user unlock via {@link WifiConfigManager#handleUserUnlock(int)} does
2216     * not always result in a store read unless the user had switched or just booted up.
2217     */
2218    @Test
2219    public void testHandleUserUnlockWithoutSwitchOrBootup() throws Exception {
2220        int user1 = TEST_DEFAULT_USER;
2221        int user2 = TEST_DEFAULT_USER + 1;
2222        setupUserProfiles(user2);
2223
2224        // Set up the internal data first.
2225        assertTrue(mWifiConfigManager.loadFromStore());
2226
2227        when(mWifiConfigStore.switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class)))
2228                .thenReturn(new WifiConfigStoreData(
2229                        new ArrayList<WifiConfiguration>(), new ArrayList<WifiConfiguration>(),
2230                        new HashSet<String>()));
2231
2232        // user2 is unlocked and switched to foreground.
2233        when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(true);
2234        mWifiConfigManager.handleUserSwitch(user2);
2235        // Ensure that the read was invoked.
2236        mContextConfigStoreMockOrder.verify(mWifiConfigStore)
2237                .switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class));
2238
2239        // Unlock the user2 again and ensure that we don't read the data now.
2240        mWifiConfigManager.handleUserUnlock(user2);
2241        mContextConfigStoreMockOrder.verify(mWifiConfigStore, never())
2242                .switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class));
2243    }
2244
2245    /**
2246     * Verifies the foreground user unlock via {@link WifiConfigManager#handleUserSwitch(int)}
2247     * is ignored if the legacy store migration is not complete.
2248     */
2249    @Test
2250    public void testHandleUserSwitchAfterBootupBeforeLegacyStoreMigration() throws Exception {
2251        int user2 = TEST_DEFAULT_USER + 1;
2252
2253        // Switch to user2 for the first time and ensure that we don't read or
2254        // write the store files.
2255        when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(false);
2256        mWifiConfigManager.handleUserSwitch(user2);
2257        mContextConfigStoreMockOrder.verify(mWifiConfigStore, never())
2258                .switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class));
2259        mContextConfigStoreMockOrder.verify(mWifiConfigStore, never())
2260                .write(anyBoolean(), any(WifiConfigStoreData.class));
2261    }
2262
2263    /**
2264     * Verifies the foreground user unlock via {@link WifiConfigManager#handleUserUnlock(int)}
2265     * is ignored if the legacy store migration is not complete.
2266     */
2267    @Test
2268    public void testHandleUserUnlockAfterBootupBeforeLegacyStoreMigration() throws Exception {
2269        int user1 = TEST_DEFAULT_USER;
2270
2271        // Unlock the user1 (default user) for the first time and ensure that we don't read or
2272        // write the store files.
2273        mWifiConfigManager.handleUserUnlock(user1);
2274        mContextConfigStoreMockOrder.verify(mWifiConfigStore, never())
2275                .switchUserStoreAndRead(any(WifiConfigStore.StoreFile.class));
2276        mContextConfigStoreMockOrder.verify(mWifiConfigStore, never())
2277                .write(anyBoolean(), any(WifiConfigStoreData.class));
2278    }
2279
2280    /**
2281     * Verifies the private network addition using
2282     * {@link WifiConfigManager#addOrUpdateNetwork(WifiConfiguration, int)}
2283     * by a non foreground user is rejected.
2284     */
2285    @Test
2286    public void testAddNetworkUsingBackgroundUserUId() throws Exception {
2287        int user2 = TEST_DEFAULT_USER + 1;
2288        setupUserProfiles(user2);
2289
2290        int creatorUid = UserHandle.getUid(user2, 674);
2291
2292        // Create a network for user2 try adding it. This should be rejected.
2293        final WifiConfiguration user2Network = WifiConfigurationTestUtil.createPskNetwork();
2294        NetworkUpdateResult result =
2295                mWifiConfigManager.addOrUpdateNetwork(user2Network, creatorUid);
2296        assertFalse(result.isSuccess());
2297    }
2298
2299    /**
2300     * Verifies the private network addition using
2301     * {@link WifiConfigManager#addOrUpdateNetwork(WifiConfiguration, int)}
2302     * by SysUI is always accepted.
2303     */
2304    @Test
2305    public void testAddNetworkUsingSysUiUid() throws Exception {
2306        // Set up the user profiles stuff. Needed for |WifiConfigurationUtil.isVisibleToAnyProfile|
2307        int user2 = TEST_DEFAULT_USER + 1;
2308        setupUserProfiles(user2);
2309
2310        when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(false);
2311        mWifiConfigManager.handleUserSwitch(user2);
2312
2313        // Create a network for user2 try adding it. This should be rejected.
2314        final WifiConfiguration user2Network = WifiConfigurationTestUtil.createPskNetwork();
2315        NetworkUpdateResult result =
2316                mWifiConfigManager.addOrUpdateNetwork(user2Network, TEST_SYSUI_UID);
2317        assertTrue(result.isSuccess());
2318    }
2319
2320    /**
2321     * Verifies the loading of networks using {@link WifiConfigManager#migrateFromLegacyStore()} ()}
2322     * attempts to migrate data from legacy stores when the legacy store files are present.
2323     */
2324    @Test
2325    public void testMigrationFromLegacyStore() throws Exception {
2326        // Create the store data to be returned from legacy stores.
2327        List<WifiConfiguration> networks = new ArrayList<>();
2328        networks.add(WifiConfigurationTestUtil.createPskNetwork());
2329        networks.add(WifiConfigurationTestUtil.createEapNetwork());
2330        networks.add(WifiConfigurationTestUtil.createWepNetwork());
2331        String deletedEphemeralSSID = "EphemeralSSID";
2332        Set<String> deletedEphermalSSIDs = new HashSet<>(Arrays.asList(deletedEphemeralSSID));
2333        WifiConfigStoreDataLegacy storeData =
2334                new WifiConfigStoreDataLegacy(networks, deletedEphermalSSIDs);
2335
2336        when(mWifiConfigStoreLegacy.areStoresPresent()).thenReturn(true);
2337        when(mWifiConfigStoreLegacy.read()).thenReturn(storeData);
2338
2339        // Now trigger the migration from legacy store. This should populate the in memory list with
2340        // all the networks above from the legacy store.
2341        assertTrue(mWifiConfigManager.migrateFromLegacyStore());
2342
2343        verify(mWifiConfigStoreLegacy).read();
2344        verify(mWifiConfigStoreLegacy).removeStores();
2345
2346        List<WifiConfiguration> retrievedNetworks =
2347                mWifiConfigManager.getConfiguredNetworksWithPasswords();
2348        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
2349                networks, retrievedNetworks);
2350        assertTrue(mWifiConfigManager.wasEphemeralNetworkDeleted(deletedEphemeralSSID));
2351    }
2352
2353    /**
2354     * Verifies the loading of networks using {@link WifiConfigManager#migrateFromLegacyStore()} ()}
2355     * does not attempt to migrate data from legacy stores when the legacy store files are absent
2356     * (i.e migration was already done once).
2357     */
2358    @Test
2359    public void testNoDuplicateMigrationFromLegacyStore() throws Exception {
2360        when(mWifiConfigStoreLegacy.areStoresPresent()).thenReturn(false);
2361
2362        // Now trigger a migration from legacy store.
2363        assertTrue(mWifiConfigManager.migrateFromLegacyStore());
2364
2365        verify(mWifiConfigStoreLegacy, never()).read();
2366        verify(mWifiConfigStoreLegacy, never()).removeStores();
2367    }
2368
2369    /**
2370     * Verifies the loading of networks using {@link WifiConfigManager#loadFromStore()} does
2371     * not attempt to read from any of the stores (new or legacy) when the store files are
2372     * not present.
2373     */
2374    @Test
2375    public void testFreshInstallDoesNotLoadFromStore() throws Exception {
2376        // New store files not present, so migrate from the old store.
2377        when(mWifiConfigStore.areStoresPresent()).thenReturn(false);
2378        when(mWifiConfigStoreLegacy.areStoresPresent()).thenReturn(false);
2379
2380        // Now trigger a load from store. This should populate the in memory list with all the
2381        // networks above.
2382        assertTrue(mWifiConfigManager.loadFromStore());
2383
2384        verify(mWifiConfigStore, never()).read();
2385        verify(mWifiConfigStoreLegacy, never()).read();
2386
2387        assertTrue(mWifiConfigManager.getConfiguredNetworksWithPasswords().isEmpty());
2388    }
2389
2390    /**
2391     * Verifies that the last user selected network parameter is set when
2392     * {@link WifiConfigManager#enableNetwork(int, boolean, int)} with disableOthers flag is set
2393     * to true and cleared when either {@link WifiConfigManager#disableNetwork(int, int)} or
2394     * {@link WifiConfigManager#removeNetwork(int, int)} is invoked using the same network ID.
2395     */
2396    @Test
2397    public void testLastSelectedNetwork() throws Exception {
2398        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
2399        NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(openNetwork);
2400
2401        when(mClock.getElapsedSinceBootMillis()).thenReturn(67L);
2402        assertTrue(mWifiConfigManager.enableNetwork(
2403                result.getNetworkId(), true, TEST_CREATOR_UID));
2404        assertEquals(result.getNetworkId(), mWifiConfigManager.getLastSelectedNetwork());
2405        assertEquals(67, mWifiConfigManager.getLastSelectedTimeStamp());
2406
2407        // Now disable the network and ensure that the last selected flag is cleared.
2408        assertTrue(mWifiConfigManager.disableNetwork(result.getNetworkId(), TEST_CREATOR_UID));
2409        assertEquals(
2410                WifiConfiguration.INVALID_NETWORK_ID, mWifiConfigManager.getLastSelectedNetwork());
2411
2412        // Enable it again and remove the network to ensure that the last selected flag was cleared.
2413        assertTrue(mWifiConfigManager.enableNetwork(
2414                result.getNetworkId(), true, TEST_CREATOR_UID));
2415        assertEquals(result.getNetworkId(), mWifiConfigManager.getLastSelectedNetwork());
2416        assertEquals(openNetwork.configKey(), mWifiConfigManager.getLastSelectedNetworkConfigKey());
2417
2418        assertTrue(mWifiConfigManager.removeNetwork(result.getNetworkId(), TEST_CREATOR_UID));
2419        assertEquals(
2420                WifiConfiguration.INVALID_NETWORK_ID, mWifiConfigManager.getLastSelectedNetwork());
2421    }
2422
2423    /**
2424     * Verifies that all the networks for the provided app is removed when
2425     * {@link WifiConfigManager#removeNetworksForApp(ApplicationInfo)} is invoked.
2426     */
2427    @Test
2428    public void testRemoveNetworksForApp() throws Exception {
2429        verifyAddNetworkToWifiConfigManager(WifiConfigurationTestUtil.createOpenNetwork());
2430        verifyAddNetworkToWifiConfigManager(WifiConfigurationTestUtil.createPskNetwork());
2431        verifyAddNetworkToWifiConfigManager(WifiConfigurationTestUtil.createWepNetwork());
2432
2433        assertFalse(mWifiConfigManager.getConfiguredNetworks().isEmpty());
2434
2435        ApplicationInfo app = new ApplicationInfo();
2436        app.uid = TEST_CREATOR_UID;
2437        app.packageName = TEST_CREATOR_NAME;
2438        assertEquals(3, mWifiConfigManager.removeNetworksForApp(app).size());
2439
2440        // Ensure all the networks are removed now.
2441        assertTrue(mWifiConfigManager.getConfiguredNetworks().isEmpty());
2442    }
2443
2444    /**
2445     * Verifies that all the networks for the provided user is removed when
2446     * {@link WifiConfigManager#removeNetworksForUser(int)} is invoked.
2447     */
2448    @Test
2449    public void testRemoveNetworksForUser() throws Exception {
2450        verifyAddNetworkToWifiConfigManager(WifiConfigurationTestUtil.createOpenNetwork());
2451        verifyAddNetworkToWifiConfigManager(WifiConfigurationTestUtil.createPskNetwork());
2452        verifyAddNetworkToWifiConfigManager(WifiConfigurationTestUtil.createWepNetwork());
2453
2454        assertFalse(mWifiConfigManager.getConfiguredNetworks().isEmpty());
2455
2456        assertEquals(3, mWifiConfigManager.removeNetworksForUser(TEST_DEFAULT_USER).size());
2457
2458        // Ensure all the networks are removed now.
2459        assertTrue(mWifiConfigManager.getConfiguredNetworks().isEmpty());
2460    }
2461
2462    /**
2463     * Verifies that the connect choice is removed from all networks when
2464     * {@link WifiConfigManager#removeNetwork(int, int)} is invoked.
2465     */
2466    @Test
2467    public void testRemoveNetworkRemovesConnectChoice() throws Exception {
2468        WifiConfiguration network1 = WifiConfigurationTestUtil.createOpenNetwork();
2469        WifiConfiguration network2 = WifiConfigurationTestUtil.createPskNetwork();
2470        WifiConfiguration network3 = WifiConfigurationTestUtil.createPskNetwork();
2471        verifyAddNetworkToWifiConfigManager(network1);
2472        verifyAddNetworkToWifiConfigManager(network2);
2473        verifyAddNetworkToWifiConfigManager(network3);
2474
2475        // Set connect choice of network 2 over network 1.
2476        assertTrue(
2477                mWifiConfigManager.setNetworkConnectChoice(
2478                        network1.networkId, network2.configKey(), 78L));
2479
2480        WifiConfiguration retrievedNetwork =
2481                mWifiConfigManager.getConfiguredNetwork(network1.networkId);
2482        assertEquals(
2483                network2.configKey(),
2484                retrievedNetwork.getNetworkSelectionStatus().getConnectChoice());
2485
2486        // Remove network 3 and ensure that the connect choice on network 1 is not removed.
2487        assertTrue(mWifiConfigManager.removeNetwork(network3.networkId, TEST_CREATOR_UID));
2488        retrievedNetwork = mWifiConfigManager.getConfiguredNetwork(network1.networkId);
2489        assertEquals(
2490                network2.configKey(),
2491                retrievedNetwork.getNetworkSelectionStatus().getConnectChoice());
2492
2493        // Now remove network 2 and ensure that the connect choice on network 1 is removed..
2494        assertTrue(mWifiConfigManager.removeNetwork(network2.networkId, TEST_CREATOR_UID));
2495        retrievedNetwork = mWifiConfigManager.getConfiguredNetwork(network1.networkId);
2496        assertNotEquals(
2497                network2.configKey(),
2498                retrievedNetwork.getNetworkSelectionStatus().getConnectChoice());
2499
2500        // This should have triggered 2 buffered writes. 1 for setting the connect choice, 1 for
2501        // clearing it after network removal.
2502        mContextConfigStoreMockOrder.verify(mWifiConfigStore, times(2))
2503                .write(eq(false), any(WifiConfigStoreData.class));
2504    }
2505
2506    /**
2507     * Verifies that the modification of a single network using
2508     * {@link WifiConfigManager#addOrUpdateNetwork(WifiConfiguration, int)} and ensures that any
2509     * updates to the network config in
2510     * {@link WifiKeyStore#updateNetworkKeys(WifiConfiguration, WifiConfiguration)} is reflected
2511     * in the internal database.
2512     */
2513    @Test
2514    public void testUpdateSingleNetworkWithKeysUpdate() {
2515        WifiConfiguration network = WifiConfigurationTestUtil.createEapNetwork();
2516        network.enterpriseConfig =
2517                WifiConfigurationTestUtil.createPEAPWifiEnterpriseConfigWithGTCPhase2();
2518        verifyAddNetworkToWifiConfigManager(network);
2519
2520        // Now verify that network configurations match before we make any change.
2521        WifiConfigurationTestUtil.assertConfigurationEqualForConfigManagerAddOrUpdate(
2522                network,
2523                mWifiConfigManager.getConfiguredNetworkWithPassword(network.networkId));
2524
2525        // Modify the network ca_cert field in updateNetworkKeys method during a network
2526        // config update.
2527        final String newCaCertAlias = "test";
2528        assertNotEquals(newCaCertAlias, network.enterpriseConfig.getCaCertificateAlias());
2529
2530        doAnswer(new AnswerWithArguments() {
2531            public boolean answer(WifiConfiguration newConfig, WifiConfiguration existingConfig) {
2532                newConfig.enterpriseConfig.setCaCertificateAlias(newCaCertAlias);
2533                return true;
2534            }
2535        }).when(mWifiKeyStore).updateNetworkKeys(
2536                any(WifiConfiguration.class), any(WifiConfiguration.class));
2537
2538        verifyUpdateNetworkToWifiConfigManagerWithoutIpChange(network);
2539
2540        // Now verify that the keys update is reflected in the configuration fetched from internal
2541        // db.
2542        network.enterpriseConfig.setCaCertificateAlias(newCaCertAlias);
2543        WifiConfigurationTestUtil.assertConfigurationEqualForConfigManagerAddOrUpdate(
2544                network,
2545                mWifiConfigManager.getConfiguredNetworkWithPassword(network.networkId));
2546    }
2547
2548    /**
2549     * Verifies that the dump method prints out all the saved network details with passwords masked.
2550     * {@link WifiConfigManager#dump(FileDescriptor, PrintWriter, String[])}.
2551     */
2552    @Test
2553    public void testDump() {
2554        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
2555        WifiConfiguration eapNetwork = WifiConfigurationTestUtil.createEapNetwork();
2556        eapNetwork.enterpriseConfig.setPassword("blah");
2557
2558        verifyAddNetworkToWifiConfigManager(pskNetwork);
2559        verifyAddNetworkToWifiConfigManager(eapNetwork);
2560
2561        StringWriter stringWriter = new StringWriter();
2562        mWifiConfigManager.dump(
2563                new FileDescriptor(), new PrintWriter(stringWriter), new String[0]);
2564        String dumpString = stringWriter.toString();
2565
2566        // Ensure that the network SSIDs were dumped out.
2567        assertTrue(dumpString.contains(pskNetwork.SSID));
2568        assertTrue(dumpString.contains(eapNetwork.SSID));
2569
2570        // Ensure that the network passwords were not dumped out.
2571        assertFalse(dumpString.contains(pskNetwork.preSharedKey));
2572        assertFalse(dumpString.contains(eapNetwork.enterpriseConfig.getPassword()));
2573    }
2574
2575    /**
2576     * Verifies the ordering of network list generated using
2577     * {@link WifiConfigManager#retrieveHiddenNetworkList()}.
2578     */
2579    @Test
2580    public void testRetrieveHiddenList() {
2581        // Create and add 3 networks.
2582        WifiConfiguration network1 = WifiConfigurationTestUtil.createWepHiddenNetwork();
2583        WifiConfiguration network2 = WifiConfigurationTestUtil.createPskHiddenNetwork();
2584        WifiConfiguration network3 = WifiConfigurationTestUtil.createOpenHiddenNetwork();
2585        verifyAddNetworkToWifiConfigManager(network1);
2586        verifyAddNetworkToWifiConfigManager(network2);
2587        verifyAddNetworkToWifiConfigManager(network3);
2588
2589        // Enable all of them.
2590        assertTrue(mWifiConfigManager.enableNetwork(network1.networkId, false, TEST_CREATOR_UID));
2591        assertTrue(mWifiConfigManager.enableNetwork(network2.networkId, false, TEST_CREATOR_UID));
2592        assertTrue(mWifiConfigManager.enableNetwork(network3.networkId, false, TEST_CREATOR_UID));
2593
2594        // Now set scan results in 2 of them to set the corresponding
2595        // {@link NetworkSelectionStatus#mSeenInLastQualifiedNetworkSelection} field.
2596        assertTrue(mWifiConfigManager.setNetworkCandidateScanResult(
2597                network1.networkId, createScanDetailForNetwork(network1).getScanResult(), 54));
2598        assertTrue(mWifiConfigManager.setNetworkCandidateScanResult(
2599                network3.networkId, createScanDetailForNetwork(network3).getScanResult(), 54));
2600
2601        // Now increment |network3|'s association count. This should ensure that this network
2602        // is preferred over |network1|.
2603        assertTrue(mWifiConfigManager.updateNetworkAfterConnect(network3.networkId));
2604
2605        // Retrieve the hidden network list & verify the order of the networks returned.
2606        List<WifiScanner.ScanSettings.HiddenNetwork> hiddenNetworks =
2607                mWifiConfigManager.retrieveHiddenNetworkList();
2608        assertEquals(3, hiddenNetworks.size());
2609        assertEquals(network3.SSID, hiddenNetworks.get(0).ssid);
2610        assertEquals(network1.SSID, hiddenNetworks.get(1).ssid);
2611        assertEquals(network2.SSID, hiddenNetworks.get(2).ssid);
2612
2613        // Now permanently disable |network3|. This should remove network 3 from the list.
2614        assertTrue(mWifiConfigManager.disableNetwork(network3.networkId, TEST_CREATOR_UID));
2615
2616        // Retrieve the hidden network list again & verify the order of the networks returned.
2617        hiddenNetworks = mWifiConfigManager.retrieveHiddenNetworkList();
2618        assertEquals(2, hiddenNetworks.size());
2619        assertEquals(network1.SSID, hiddenNetworks.get(0).ssid);
2620        assertEquals(network2.SSID, hiddenNetworks.get(1).ssid);
2621    }
2622
2623    /**
2624     * Verifies the addition of network configurations using
2625     * {@link WifiConfigManager#addOrUpdateNetwork(WifiConfiguration, int)} with same SSID and
2626     * default key mgmt does not add duplicate network configs.
2627     */
2628    @Test
2629    public void testAddMultipleNetworksWithSameSSIDAndDefaultKeyMgmt() {
2630        final String ssid = "test_blah";
2631        // Add a network with the above SSID and default key mgmt and ensure it was added
2632        // successfully.
2633        WifiConfiguration network1 = new WifiConfiguration();
2634        network1.SSID = ssid;
2635        NetworkUpdateResult result = addNetworkToWifiConfigManager(network1);
2636        assertTrue(result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID);
2637        assertTrue(result.isNewNetwork());
2638
2639        List<WifiConfiguration> retrievedNetworks =
2640                mWifiConfigManager.getConfiguredNetworksWithPasswords();
2641        assertEquals(1, retrievedNetworks.size());
2642        WifiConfigurationTestUtil.assertConfigurationEqualForConfigManagerAddOrUpdate(
2643                network1, retrievedNetworks.get(0));
2644
2645        // Now add a second network with the same SSID and default key mgmt and ensure that it
2646        // didn't add a new duplicate network.
2647        WifiConfiguration network2 = new WifiConfiguration();
2648        network2.SSID = ssid;
2649        result = addNetworkToWifiConfigManager(network2);
2650        assertTrue(result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID);
2651        assertFalse(result.isNewNetwork());
2652
2653        retrievedNetworks = mWifiConfigManager.getConfiguredNetworksWithPasswords();
2654        assertEquals(1, retrievedNetworks.size());
2655        WifiConfigurationTestUtil.assertConfigurationEqualForConfigManagerAddOrUpdate(
2656                network2, retrievedNetworks.get(0));
2657    }
2658
2659    /**
2660     * Verifies the addition of network configurations using
2661     * {@link WifiConfigManager#addOrUpdateNetwork(WifiConfiguration, int)} with same SSID and
2662     * different key mgmt should add different network configs.
2663     */
2664    @Test
2665    public void testAddMultipleNetworksWithSameSSIDAndDifferentKeyMgmt() {
2666        final String ssid = "test_blah";
2667        // Add a network with the above SSID and WPA_PSK key mgmt and ensure it was added
2668        // successfully.
2669        WifiConfiguration network1 = new WifiConfiguration();
2670        network1.SSID = ssid;
2671        network1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
2672        NetworkUpdateResult result = addNetworkToWifiConfigManager(network1);
2673        assertTrue(result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID);
2674        assertTrue(result.isNewNetwork());
2675
2676        List<WifiConfiguration> retrievedNetworks =
2677                mWifiConfigManager.getConfiguredNetworksWithPasswords();
2678        assertEquals(1, retrievedNetworks.size());
2679        WifiConfigurationTestUtil.assertConfigurationEqualForConfigManagerAddOrUpdate(
2680                network1, retrievedNetworks.get(0));
2681
2682        // Now add a second network with the same SSID and NONE key mgmt and ensure that it
2683        // does add a new network.
2684        WifiConfiguration network2 = new WifiConfiguration();
2685        network2.SSID = ssid;
2686        network2.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
2687        result = addNetworkToWifiConfigManager(network2);
2688        assertTrue(result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID);
2689        assertTrue(result.isNewNetwork());
2690
2691        retrievedNetworks = mWifiConfigManager.getConfiguredNetworksWithPasswords();
2692        assertEquals(2, retrievedNetworks.size());
2693        List<WifiConfiguration> networks = Arrays.asList(network1, network2);
2694        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
2695                networks, retrievedNetworks);
2696    }
2697
2698    /**
2699     * Verifies that adding a network with a proxy, without having permission OVERRIDE_WIFI_CONFIG,
2700     * holding device policy, or profile owner policy fails.
2701     */
2702    @Test
2703    public void testAddNetworkWithProxyFails() {
2704        verifyAddOrUpdateNetworkWithProxySettingsAndPermissions(
2705                false, // withConfOverride
2706                false, // withProfileOwnerPolicy
2707                false, // withDeviceOwnerPolicy
2708                WifiConfigurationTestUtil.createDHCPIpConfigurationWithPacProxy(),
2709                false, // assertSuccess
2710                WifiConfiguration.INVALID_NETWORK_ID); // Update networkID
2711        verifyAddOrUpdateNetworkWithProxySettingsAndPermissions(
2712                false, // withConfOverride
2713                false, // withProfileOwnerPolicy
2714                false, // withDeviceOwnerPolicy
2715                WifiConfigurationTestUtil.createDHCPIpConfigurationWithStaticProxy(),
2716                false, // assertSuccess
2717                WifiConfiguration.INVALID_NETWORK_ID); // Update networkID
2718    }
2719
2720    /**
2721     * Verifies that adding a network with a PAC or STATIC proxy with permission
2722     * OVERRIDE_WIFI_CONFIG is successful
2723     */
2724    @Test
2725    public void testAddNetworkWithProxyWithConfOverride() {
2726        verifyAddOrUpdateNetworkWithProxySettingsAndPermissions(
2727                true,  // withConfOverride
2728                false, // withProfileOwnerPolicy
2729                false, // withDeviceOwnerPolicy
2730                WifiConfigurationTestUtil.createDHCPIpConfigurationWithPacProxy(),
2731                true, // assertSuccess
2732                WifiConfiguration.INVALID_NETWORK_ID); // Update networkID
2733        verifyAddOrUpdateNetworkWithProxySettingsAndPermissions(
2734                true,  // withConfOverride
2735                false, // withProfileOwnerPolicy
2736                false, // withDeviceOwnerPolicy
2737                WifiConfigurationTestUtil.createDHCPIpConfigurationWithStaticProxy(),
2738                true, // assertSuccess
2739                WifiConfiguration.INVALID_NETWORK_ID); // Update networkID
2740    }
2741
2742    /**
2743     * Verifies that adding a network with a PAC or STATIC proxy, while holding policy
2744     * {@link DeviceAdminInfo.USES_POLICY_PROFILE_OWNER} is successful
2745     */
2746    @Test
2747    public void testAddNetworkWithProxyAsProfileOwner() {
2748        verifyAddOrUpdateNetworkWithProxySettingsAndPermissions(
2749                false,  // withConfOverride
2750                true, // withProfileOwnerPolicy
2751                false, // withDeviceOwnerPolicy
2752                WifiConfigurationTestUtil.createDHCPIpConfigurationWithPacProxy(),
2753                true, // assertSuccess
2754                WifiConfiguration.INVALID_NETWORK_ID); // Update networkID
2755        verifyAddOrUpdateNetworkWithProxySettingsAndPermissions(
2756                false,  // withConfOverride
2757                true, // withProfileOwnerPolicy
2758                false, // withDeviceOwnerPolicy
2759                WifiConfigurationTestUtil.createDHCPIpConfigurationWithStaticProxy(),
2760                true, // assertSuccess
2761                WifiConfiguration.INVALID_NETWORK_ID); // Update networkID
2762    }
2763    /**
2764     * Verifies that adding a network with a PAC or STATIC proxy, while holding policy
2765     * {@link DeviceAdminInfo.USES_POLICY_DEVICE_OWNER} is successful
2766     */
2767    @Test
2768    public void testAddNetworkWithProxyAsDeviceOwner() {
2769        verifyAddOrUpdateNetworkWithProxySettingsAndPermissions(
2770                false,  // withConfOverride
2771                false, // withProfileOwnerPolicy
2772                true, // withDeviceOwnerPolicy
2773                WifiConfigurationTestUtil.createDHCPIpConfigurationWithPacProxy(),
2774                true, // assertSuccess
2775                WifiConfiguration.INVALID_NETWORK_ID); // Update networkID
2776        verifyAddOrUpdateNetworkWithProxySettingsAndPermissions(
2777                false,  // withConfOverride
2778                false, // withProfileOwnerPolicy
2779                true, // withDeviceOwnerPolicy
2780                WifiConfigurationTestUtil.createDHCPIpConfigurationWithStaticProxy(),
2781                true, // assertSuccess
2782                WifiConfiguration.INVALID_NETWORK_ID); // Update networkID
2783    }
2784    /**
2785     * Verifies that updating a network (that has no proxy) and adding a PAC or STATIC proxy fails
2786     * without being able to override configs, or holding Device or Profile owner policies.
2787     */
2788    @Test
2789    public void testUpdateNetworkAddProxyFails() {
2790        WifiConfiguration network = WifiConfigurationTestUtil.createOpenHiddenNetwork();
2791        NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(network);
2792        verifyAddOrUpdateNetworkWithProxySettingsAndPermissions(
2793                false, // withConfOverride
2794                false, // withProfileOwnerPolicy
2795                false, // withDeviceOwnerPolicy
2796                WifiConfigurationTestUtil.createDHCPIpConfigurationWithPacProxy(),
2797                false, // assertSuccess
2798                result.getNetworkId()); // Update networkID
2799        verifyAddOrUpdateNetworkWithProxySettingsAndPermissions(
2800                false, // withConfOverride
2801                false, // withProfileOwnerPolicy
2802                false, // withDeviceOwnerPolicy
2803                WifiConfigurationTestUtil.createDHCPIpConfigurationWithStaticProxy(),
2804                false, // assertSuccess
2805                result.getNetworkId()); // Update networkID
2806    }
2807    /**
2808     * Verifies that updating a network and adding a proxy is successful in the cases where app can
2809     * override configs, holds policy {@link DeviceAdminInfo.USES_POLICY_PROFILE_OWNER},
2810     * and holds policy {@link DeviceAdminInfo.USES_POLICY_DEVICE_OWNER}, and that it fails
2811     * otherwise.
2812     */
2813    @Test
2814    public void testUpdateNetworkAddProxyWithPermissionAndSystem() {
2815        // Testing updating network with uid permission OVERRIDE_WIFI_CONFIG
2816        WifiConfiguration network = WifiConfigurationTestUtil.createOpenHiddenNetwork();
2817        NetworkUpdateResult result =
2818                mWifiConfigManager.addOrUpdateNetwork(network, TEST_CREATOR_UID);
2819        assertTrue(result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID);
2820        verifyAddOrUpdateNetworkWithProxySettingsAndPermissions(
2821                true, // withConfOverride
2822                false, // withProfileOwnerPolicy
2823                false, // withDeviceOwnerPolicy
2824                WifiConfigurationTestUtil.createDHCPIpConfigurationWithPacProxy(),
2825                true, // assertSuccess
2826                result.getNetworkId()); // Update networkID
2827
2828        // Testing updating network with proxy while holding Profile Owner policy
2829        network = WifiConfigurationTestUtil.createOpenHiddenNetwork();
2830        result = mWifiConfigManager.addOrUpdateNetwork(network, TEST_NO_PERM_UID);
2831        assertTrue(result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID);
2832        verifyAddOrUpdateNetworkWithProxySettingsAndPermissions(
2833                false, // withConfOverride
2834                true, // withProfileOwnerPolicy
2835                false, // withDeviceOwnerPolicy
2836                WifiConfigurationTestUtil.createDHCPIpConfigurationWithPacProxy(),
2837                true, // assertSuccess
2838                result.getNetworkId()); // Update networkID
2839
2840        // Testing updating network with proxy while holding Device Owner Policy
2841        network = WifiConfigurationTestUtil.createOpenHiddenNetwork();
2842        result = mWifiConfigManager.addOrUpdateNetwork(network, TEST_NO_PERM_UID);
2843        assertTrue(result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID);
2844        verifyAddOrUpdateNetworkWithProxySettingsAndPermissions(
2845                false, // withConfOverride
2846                false, // withProfileOwnerPolicy
2847                true, // withDeviceOwnerPolicy
2848                WifiConfigurationTestUtil.createDHCPIpConfigurationWithPacProxy(),
2849                true, // assertSuccess
2850                result.getNetworkId()); // Update networkID
2851    }
2852
2853    /**
2854     * Verifies that updating a network that has a proxy without changing the proxy, can succeed
2855     * without proxy specific permissions.
2856     */
2857    @Test
2858    public void testUpdateNetworkUnchangedProxy() {
2859        IpConfiguration ipConf = WifiConfigurationTestUtil.createDHCPIpConfigurationWithPacProxy();
2860        // First create a WifiConfiguration with proxy
2861        NetworkUpdateResult result = verifyAddOrUpdateNetworkWithProxySettingsAndPermissions(
2862                        false, // withConfOverride
2863                        true, // withProfileOwnerPolicy
2864                        false, // withDeviceOwnerPolicy
2865                        ipConf,
2866                        true, // assertSuccess
2867                        WifiConfiguration.INVALID_NETWORK_ID); // Update networkID
2868        // Update the network while using the same ipConf, and no proxy specific permissions
2869        verifyAddOrUpdateNetworkWithProxySettingsAndPermissions(
2870                        false, // withConfOverride
2871                        false, // withProfileOwnerPolicy
2872                        false, // withDeviceOwnerPolicy
2873                        ipConf,
2874                        true, // assertSuccess
2875                        result.getNetworkId()); // Update networkID
2876    }
2877
2878    /**
2879     * Verifies that updating a network with a different proxy succeeds in the cases where app can
2880     * override configs, holds policy {@link DeviceAdminInfo.USES_POLICY_PROFILE_OWNER},
2881     * and holds policy {@link DeviceAdminInfo.USES_POLICY_DEVICE_OWNER}, and that it fails
2882     * otherwise.
2883     */
2884    @Test
2885    public void testUpdateNetworkDifferentProxy() {
2886        // Create two proxy configurations of the same type, but different values
2887        IpConfiguration ipConf1 =
2888                WifiConfigurationTestUtil.createDHCPIpConfigurationWithSpecificProxy(
2889                        WifiConfigurationTestUtil.STATIC_PROXY_SETTING,
2890                        TEST_STATIC_PROXY_HOST_1,
2891                        TEST_STATIC_PROXY_PORT_1,
2892                        TEST_STATIC_PROXY_EXCLUSION_LIST_1,
2893                        TEST_PAC_PROXY_LOCATION_1);
2894        IpConfiguration ipConf2 =
2895                WifiConfigurationTestUtil.createDHCPIpConfigurationWithSpecificProxy(
2896                        WifiConfigurationTestUtil.STATIC_PROXY_SETTING,
2897                        TEST_STATIC_PROXY_HOST_2,
2898                        TEST_STATIC_PROXY_PORT_2,
2899                        TEST_STATIC_PROXY_EXCLUSION_LIST_2,
2900                        TEST_PAC_PROXY_LOCATION_2);
2901
2902        // Update with Conf Override
2903        NetworkUpdateResult result = verifyAddOrUpdateNetworkWithProxySettingsAndPermissions(
2904                true, // withConfOverride
2905                false, // withProfileOwnerPolicy
2906                false, // withDeviceOwnerPolicy
2907                ipConf1,
2908                true, // assertSuccess
2909                WifiConfiguration.INVALID_NETWORK_ID); // Update networkID
2910        verifyAddOrUpdateNetworkWithProxySettingsAndPermissions(
2911                true, // withConfOverride
2912                false, // withProfileOwnerPolicy
2913                false, // withDeviceOwnerPolicy
2914                ipConf2,
2915                true, // assertSuccess
2916                result.getNetworkId()); // Update networkID
2917
2918        // Update as Device Owner
2919        result = verifyAddOrUpdateNetworkWithProxySettingsAndPermissions(
2920                false, // withConfOverride
2921                false, // withProfileOwnerPolicy
2922                true, // withDeviceOwnerPolicy
2923                ipConf1,
2924                true, // assertSuccess
2925                WifiConfiguration.INVALID_NETWORK_ID); // Update networkID
2926        verifyAddOrUpdateNetworkWithProxySettingsAndPermissions(
2927                false, // withConfOverride
2928                false, // withProfileOwnerPolicy
2929                true, // withDeviceOwnerPolicy
2930                ipConf2,
2931                true, // assertSuccess
2932                result.getNetworkId()); // Update networkID
2933
2934        // Update as Profile Owner
2935        result = verifyAddOrUpdateNetworkWithProxySettingsAndPermissions(
2936                false, // withConfOverride
2937                true, // withProfileOwnerPolicy
2938                false, // withDeviceOwnerPolicy
2939                ipConf1,
2940                true, // assertSuccess
2941                WifiConfiguration.INVALID_NETWORK_ID); // Update networkID
2942        verifyAddOrUpdateNetworkWithProxySettingsAndPermissions(
2943                false, // withConfOverride
2944                true, // withProfileOwnerPolicy
2945                false, // withDeviceOwnerPolicy
2946                ipConf2,
2947                true, // assertSuccess
2948                result.getNetworkId()); // Update networkID
2949
2950        // Update with no permissions (should fail)
2951        result = verifyAddOrUpdateNetworkWithProxySettingsAndPermissions(
2952                false, // withConfOverride
2953                true, // withProfileOwnerPolicy
2954                false, // withDeviceOwnerPolicy
2955                ipConf1,
2956                true, // assertSuccess
2957                WifiConfiguration.INVALID_NETWORK_ID); // Update networkID
2958        verifyAddOrUpdateNetworkWithProxySettingsAndPermissions(
2959                false, // withConfOverride
2960                false, // withProfileOwnerPolicy
2961                false, // withDeviceOwnerPolicy
2962                ipConf2,
2963                false, // assertSuccess
2964                result.getNetworkId()); // Update networkID
2965    }
2966    /**
2967     * Verifies that updating a network removing its proxy succeeds in the cases where app can
2968     * override configs, holds policy {@link DeviceAdminInfo.USES_POLICY_PROFILE_OWNER},
2969     * and holds policy {@link DeviceAdminInfo.USES_POLICY_DEVICE_OWNER}, and that it fails
2970     * otherwise.
2971     */
2972    @Test
2973    public void testUpdateNetworkRemoveProxy() {
2974        // Create two different IP configurations, one with a proxy and another without.
2975        IpConfiguration ipConf1 =
2976                WifiConfigurationTestUtil.createDHCPIpConfigurationWithSpecificProxy(
2977                        WifiConfigurationTestUtil.STATIC_PROXY_SETTING,
2978                        TEST_STATIC_PROXY_HOST_1,
2979                        TEST_STATIC_PROXY_PORT_1,
2980                        TEST_STATIC_PROXY_EXCLUSION_LIST_1,
2981                        TEST_PAC_PROXY_LOCATION_1);
2982        IpConfiguration ipConf2 =
2983                WifiConfigurationTestUtil.createDHCPIpConfigurationWithSpecificProxy(
2984                        WifiConfigurationTestUtil.NONE_PROXY_SETTING,
2985                        TEST_STATIC_PROXY_HOST_2,
2986                        TEST_STATIC_PROXY_PORT_2,
2987                        TEST_STATIC_PROXY_EXCLUSION_LIST_2,
2988                        TEST_PAC_PROXY_LOCATION_2);
2989
2990        // Update with Conf Override
2991        NetworkUpdateResult result = verifyAddOrUpdateNetworkWithProxySettingsAndPermissions(
2992                true, // withConfOverride
2993                false, // withProfileOwnerPolicy
2994                false, // withDeviceOwnerPolicy
2995                ipConf1,
2996                true, // assertSuccess
2997                WifiConfiguration.INVALID_NETWORK_ID); // Update networkID
2998        verifyAddOrUpdateNetworkWithProxySettingsAndPermissions(
2999                true, // withConfOverride
3000                false, // withProfileOwnerPolicy
3001                false, // withDeviceOwnerPolicy
3002                ipConf2,
3003                true, // assertSuccess
3004                result.getNetworkId()); // Update networkID
3005
3006        // Update as Device Owner
3007        result = verifyAddOrUpdateNetworkWithProxySettingsAndPermissions(
3008                false, // withConfOverride
3009                false, // withProfileOwnerPolicy
3010                true, // withDeviceOwnerPolicy
3011                ipConf1,
3012                true, // assertSuccess
3013                WifiConfiguration.INVALID_NETWORK_ID); // Update networkID
3014        verifyAddOrUpdateNetworkWithProxySettingsAndPermissions(
3015                false, // withConfOverride
3016                false, // withProfileOwnerPolicy
3017                true, // withDeviceOwnerPolicy
3018                ipConf2,
3019                true, // assertSuccess
3020                result.getNetworkId()); // Update networkID
3021
3022        // Update as Profile Owner
3023        result = verifyAddOrUpdateNetworkWithProxySettingsAndPermissions(
3024                false, // withConfOverride
3025                true, // withProfileOwnerPolicy
3026                false, // withDeviceOwnerPolicy
3027                ipConf1,
3028                true, // assertSuccess
3029                WifiConfiguration.INVALID_NETWORK_ID); // Update networkID
3030        verifyAddOrUpdateNetworkWithProxySettingsAndPermissions(
3031                false, // withConfOverride
3032                true, // withProfileOwnerPolicy
3033                false, // withDeviceOwnerPolicy
3034                ipConf2,
3035                true, // assertSuccess
3036                result.getNetworkId()); // Update networkID
3037
3038        // Update with no permissions (should fail)
3039        result = verifyAddOrUpdateNetworkWithProxySettingsAndPermissions(
3040                false, // withConfOverride
3041                true, // withProfileOwnerPolicy
3042                false, // withDeviceOwnerPolicy
3043                ipConf1,
3044                true, // assertSuccess
3045                WifiConfiguration.INVALID_NETWORK_ID); // Update networkID
3046        verifyAddOrUpdateNetworkWithProxySettingsAndPermissions(
3047                false, // withConfOverride
3048                false, // withProfileOwnerPolicy
3049                false, // withDeviceOwnerPolicy
3050                ipConf2,
3051                false, // assertSuccess
3052                result.getNetworkId()); // Update networkID
3053    }
3054
3055    private NetworkUpdateResult verifyAddOrUpdateNetworkWithProxySettingsAndPermissions(
3056            boolean withConfOverride,
3057            boolean withProfileOwnerPolicy,
3058            boolean withDeviceOwnerPolicy,
3059            IpConfiguration ipConfiguration,
3060            boolean assertSuccess,
3061            int networkId) {
3062        WifiConfiguration network;
3063        if (networkId == WifiConfiguration.INVALID_NETWORK_ID) {
3064            network = WifiConfigurationTestUtil.createOpenHiddenNetwork();
3065        } else {
3066            network = mWifiConfigManager.getConfiguredNetwork(networkId);
3067        }
3068        network.setIpConfiguration(ipConfiguration);
3069        when(mDevicePolicyManagerInternal.isActiveAdminWithPolicy(anyInt(),
3070                eq(DeviceAdminInfo.USES_POLICY_PROFILE_OWNER)))
3071                .thenReturn(withProfileOwnerPolicy);
3072        when(mDevicePolicyManagerInternal.isActiveAdminWithPolicy(anyInt(),
3073                eq(DeviceAdminInfo.USES_POLICY_DEVICE_OWNER)))
3074                .thenReturn(withDeviceOwnerPolicy);
3075        int uid = withConfOverride ? TEST_CREATOR_UID : TEST_NO_PERM_UID;
3076        NetworkUpdateResult result = mWifiConfigManager.addOrUpdateNetwork(network, uid);
3077        assertEquals(assertSuccess, result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID);
3078        return result;
3079    }
3080
3081    private void createWifiConfigManager() {
3082        mWifiConfigManager =
3083                new WifiConfigManager(
3084                        mContext, mFrameworkFacade, mClock, mUserManager, mTelephonyManager,
3085                        mWifiKeyStore, mWifiConfigStore, mWifiConfigStoreLegacy,
3086                        mWifiPermissionsWrapper);
3087        mWifiConfigManager.enableVerboseLogging(1);
3088    }
3089
3090    /**
3091     * This method sets defaults in the provided WifiConfiguration object if not set
3092     * so that it can be used for comparison with the configuration retrieved from
3093     * WifiConfigManager.
3094     */
3095    private void setDefaults(WifiConfiguration configuration) {
3096        if (configuration.allowedAuthAlgorithms.isEmpty()) {
3097            configuration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
3098        }
3099        if (configuration.allowedProtocols.isEmpty()) {
3100            configuration.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
3101            configuration.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
3102        }
3103        if (configuration.allowedKeyManagement.isEmpty()) {
3104            configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
3105            configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
3106        }
3107        if (configuration.allowedPairwiseCiphers.isEmpty()) {
3108            configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
3109            configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
3110        }
3111        if (configuration.allowedGroupCiphers.isEmpty()) {
3112            configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
3113            configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
3114            configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
3115            configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
3116        }
3117        if (configuration.getIpAssignment() == IpConfiguration.IpAssignment.UNASSIGNED) {
3118            configuration.setIpAssignment(IpConfiguration.IpAssignment.DHCP);
3119        }
3120        if (configuration.getProxySettings() == IpConfiguration.ProxySettings.UNASSIGNED) {
3121            configuration.setProxySettings(IpConfiguration.ProxySettings.NONE);
3122        }
3123        configuration.status = WifiConfiguration.Status.DISABLED;
3124        configuration.getNetworkSelectionStatus().setNetworkSelectionStatus(
3125                NetworkSelectionStatus.NETWORK_SELECTION_PERMANENTLY_DISABLED);
3126    }
3127
3128    /**
3129     * Modifies the provided configuration with creator uid, package name
3130     * and time.
3131     */
3132    private void setCreationDebugParams(WifiConfiguration configuration) {
3133        configuration.creatorUid = configuration.lastUpdateUid = TEST_CREATOR_UID;
3134        configuration.creatorName = configuration.lastUpdateName = TEST_CREATOR_NAME;
3135        configuration.creationTime = configuration.updateTime =
3136                WifiConfigManager.createDebugTimeStampString(
3137                        TEST_WALLCLOCK_CREATION_TIME_MILLIS);
3138    }
3139
3140    /**
3141     * Modifies the provided configuration with update uid, package name
3142     * and time.
3143     */
3144    private void setUpdateDebugParams(WifiConfiguration configuration) {
3145        configuration.lastUpdateUid = TEST_UPDATE_UID;
3146        configuration.lastUpdateName = TEST_UPDATE_NAME;
3147        configuration.updateTime =
3148                WifiConfigManager.createDebugTimeStampString(TEST_WALLCLOCK_UPDATE_TIME_MILLIS);
3149    }
3150
3151    private void assertNotEquals(Object expected, Object actual) {
3152        if (actual != null) {
3153            assertFalse(actual.equals(expected));
3154        } else {
3155            assertNotNull(expected);
3156        }
3157    }
3158
3159    /**
3160     * Modifies the provided WifiConfiguration with the specified bssid value. Also, asserts that
3161     * the existing |BSSID| field is not the same value as the one being set
3162     */
3163    private void assertAndSetNetworkBSSID(WifiConfiguration configuration, String bssid) {
3164        assertNotEquals(bssid, configuration.BSSID);
3165        configuration.BSSID = bssid;
3166    }
3167
3168    /**
3169     * Modifies the provided WifiConfiguration with the specified |IpConfiguration| object. Also,
3170     * asserts that the existing |mIpConfiguration| field is not the same value as the one being set
3171     */
3172    private void assertAndSetNetworkIpConfiguration(
3173            WifiConfiguration configuration, IpConfiguration ipConfiguration) {
3174        assertNotEquals(ipConfiguration, configuration.getIpConfiguration());
3175        configuration.setIpConfiguration(ipConfiguration);
3176    }
3177
3178    /**
3179     * Modifies the provided WifiConfiguration with the specified |wepKeys| value and
3180     * |wepTxKeyIndex|.
3181     */
3182    private void assertAndSetNetworkWepKeysAndTxIndex(
3183            WifiConfiguration configuration, String[] wepKeys, int wepTxKeyIdx) {
3184        assertNotEquals(wepKeys, configuration.wepKeys);
3185        assertNotEquals(wepTxKeyIdx, configuration.wepTxKeyIndex);
3186        configuration.wepKeys = Arrays.copyOf(wepKeys, wepKeys.length);
3187        configuration.wepTxKeyIndex = wepTxKeyIdx;
3188    }
3189
3190    /**
3191     * Modifies the provided WifiConfiguration with the specified |preSharedKey| value.
3192     */
3193    private void assertAndSetNetworkPreSharedKey(
3194            WifiConfiguration configuration, String preSharedKey) {
3195        assertNotEquals(preSharedKey, configuration.preSharedKey);
3196        configuration.preSharedKey = preSharedKey;
3197    }
3198
3199    /**
3200     * Modifies the provided WifiConfiguration with the specified enteprise |password| value.
3201     */
3202    private void assertAndSetNetworkEnterprisePassword(
3203            WifiConfiguration configuration, String password) {
3204        assertNotEquals(password, configuration.enterpriseConfig.getPassword());
3205        configuration.enterpriseConfig.setPassword(password);
3206    }
3207
3208    /**
3209     * Helper method to capture the store data written in WifiConfigStore.write() method.
3210     */
3211    private WifiConfigStoreData captureWriteStoreData() {
3212        try {
3213            ArgumentCaptor<WifiConfigStoreData> storeDataCaptor =
3214                    ArgumentCaptor.forClass(WifiConfigStoreData.class);
3215            mContextConfigStoreMockOrder.verify(mWifiConfigStore)
3216                    .write(anyBoolean(), storeDataCaptor.capture());
3217            return storeDataCaptor.getValue();
3218        } catch (Exception e) {
3219            fail("Exception encountered during write " + e);
3220        }
3221        return null;
3222    }
3223
3224    /**
3225     * Returns whether the provided network was in the store data or not.
3226     */
3227    private boolean isNetworkInConfigStoreData(WifiConfiguration configuration) {
3228        WifiConfigStoreData storeData = captureWriteStoreData();
3229        if (storeData == null) {
3230            return false;
3231        }
3232        return isNetworkInConfigStoreData(configuration, storeData);
3233    }
3234
3235    /**
3236     * Returns whether the provided network was in the store data or not.
3237     */
3238    private boolean isNetworkInConfigStoreData(
3239            WifiConfiguration configuration, WifiConfigStoreData storeData) {
3240        boolean foundNetworkInStoreData = false;
3241        for (WifiConfiguration retrievedConfig : storeData.getConfigurations()) {
3242            if (retrievedConfig.configKey().equals(configuration.configKey())) {
3243                foundNetworkInStoreData = true;
3244                break;
3245            }
3246        }
3247        return foundNetworkInStoreData;
3248    }
3249
3250    /**
3251     * Verifies that the provided network was not present in the last config store write.
3252     */
3253    private void verifyNetworkNotInConfigStoreData(WifiConfiguration configuration) {
3254        assertFalse(isNetworkInConfigStoreData(configuration));
3255    }
3256
3257    /**
3258     * Verifies that the provided network was present in the last config store write.
3259     */
3260    private void verifyNetworkInConfigStoreData(WifiConfiguration configuration) {
3261        assertTrue(isNetworkInConfigStoreData(configuration));
3262    }
3263
3264    private void assertPasswordsMaskedInWifiConfiguration(WifiConfiguration configuration) {
3265        if (!TextUtils.isEmpty(configuration.preSharedKey)) {
3266            assertEquals(WifiConfigManager.PASSWORD_MASK, configuration.preSharedKey);
3267        }
3268        if (configuration.wepKeys != null) {
3269            for (int i = 0; i < configuration.wepKeys.length; i++) {
3270                if (!TextUtils.isEmpty(configuration.wepKeys[i])) {
3271                    assertEquals(WifiConfigManager.PASSWORD_MASK, configuration.wepKeys[i]);
3272                }
3273            }
3274        }
3275        if (!TextUtils.isEmpty(configuration.enterpriseConfig.getPassword())) {
3276            assertEquals(
3277                    WifiConfigManager.PASSWORD_MASK,
3278                    configuration.enterpriseConfig.getPassword());
3279        }
3280    }
3281
3282    /**
3283     * Verifies that the network was present in the network change broadcast and returns the
3284     * change reason.
3285     */
3286    private int verifyNetworkInBroadcastAndReturnReason(WifiConfiguration configuration) {
3287        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
3288        ArgumentCaptor<UserHandle> userHandleCaptor = ArgumentCaptor.forClass(UserHandle.class);
3289        mContextConfigStoreMockOrder.verify(mContext)
3290                .sendBroadcastAsUser(intentCaptor.capture(), userHandleCaptor.capture());
3291
3292        assertEquals(userHandleCaptor.getValue(), UserHandle.ALL);
3293        Intent intent = intentCaptor.getValue();
3294
3295        int changeReason = intent.getIntExtra(WifiManager.EXTRA_CHANGE_REASON, -1);
3296        WifiConfiguration retrievedConfig =
3297                (WifiConfiguration) intent.getExtra(WifiManager.EXTRA_WIFI_CONFIGURATION);
3298        assertEquals(retrievedConfig.configKey(), configuration.configKey());
3299
3300        // Verify that all the passwords are masked in the broadcast configuration.
3301        assertPasswordsMaskedInWifiConfiguration(retrievedConfig);
3302
3303        return changeReason;
3304    }
3305
3306    /**
3307     * Verifies that we sent out an add broadcast with the provided network.
3308     */
3309    private void verifyNetworkAddBroadcast(WifiConfiguration configuration) {
3310        assertEquals(
3311                verifyNetworkInBroadcastAndReturnReason(configuration),
3312                WifiManager.CHANGE_REASON_ADDED);
3313    }
3314
3315    /**
3316     * Verifies that we sent out an update broadcast with the provided network.
3317     */
3318    private void verifyNetworkUpdateBroadcast(WifiConfiguration configuration) {
3319        assertEquals(
3320                verifyNetworkInBroadcastAndReturnReason(configuration),
3321                WifiManager.CHANGE_REASON_CONFIG_CHANGE);
3322    }
3323
3324    /**
3325     * Verifies that we sent out a remove broadcast with the provided network.
3326     */
3327    private void verifyNetworkRemoveBroadcast(WifiConfiguration configuration) {
3328        assertEquals(
3329                verifyNetworkInBroadcastAndReturnReason(configuration),
3330                WifiManager.CHANGE_REASON_REMOVED);
3331    }
3332
3333    /**
3334     * Adds the provided configuration to WifiConfigManager and modifies the provided configuration
3335     * with creator/update uid, package name and time. This also sets defaults for fields not
3336     * populated.
3337     * These fields are populated internally by WifiConfigManager and hence we need
3338     * to modify the configuration before we compare the added network with the retrieved network.
3339     */
3340    private NetworkUpdateResult addNetworkToWifiConfigManager(WifiConfiguration configuration) {
3341        when(mClock.getWallClockMillis()).thenReturn(TEST_WALLCLOCK_CREATION_TIME_MILLIS);
3342        NetworkUpdateResult result =
3343                mWifiConfigManager.addOrUpdateNetwork(configuration, TEST_CREATOR_UID);
3344        setDefaults(configuration);
3345        setCreationDebugParams(configuration);
3346        configuration.networkId = result.getNetworkId();
3347        return result;
3348    }
3349
3350    /**
3351     * Add network to WifiConfigManager and ensure that it was successful.
3352     */
3353    private NetworkUpdateResult verifyAddNetworkToWifiConfigManager(
3354            WifiConfiguration configuration) {
3355        NetworkUpdateResult result = addNetworkToWifiConfigManager(configuration);
3356        assertTrue(result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID);
3357        assertTrue(result.isNewNetwork());
3358        assertTrue(result.hasIpChanged());
3359        assertTrue(result.hasProxyChanged());
3360
3361        verifyNetworkAddBroadcast(configuration);
3362        // Verify that the config store write was triggered with this new configuration.
3363        verifyNetworkInConfigStoreData(configuration);
3364        return result;
3365    }
3366
3367    /**
3368     * Add ephemeral network to WifiConfigManager and ensure that it was successful.
3369     */
3370    private NetworkUpdateResult verifyAddEphemeralNetworkToWifiConfigManager(
3371            WifiConfiguration configuration) throws Exception {
3372        NetworkUpdateResult result = addNetworkToWifiConfigManager(configuration);
3373        assertTrue(result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID);
3374        assertTrue(result.isNewNetwork());
3375        assertTrue(result.hasIpChanged());
3376        assertTrue(result.hasProxyChanged());
3377
3378        verifyNetworkAddBroadcast(configuration);
3379        // Ensure that the write was not invoked for ephemeral network addition.
3380        mContextConfigStoreMockOrder.verify(mWifiConfigStore, never())
3381                .write(anyBoolean(), any(WifiConfigStoreData.class));
3382        return result;
3383    }
3384
3385    /**
3386     * Updates the provided configuration to WifiConfigManager and modifies the provided
3387     * configuration with update uid, package name and time.
3388     * These fields are populated internally by WifiConfigManager and hence we need
3389     * to modify the configuration before we compare the added network with the retrieved network.
3390     */
3391    private NetworkUpdateResult updateNetworkToWifiConfigManager(WifiConfiguration configuration) {
3392        when(mClock.getWallClockMillis()).thenReturn(TEST_WALLCLOCK_UPDATE_TIME_MILLIS);
3393        NetworkUpdateResult result =
3394                mWifiConfigManager.addOrUpdateNetwork(configuration, TEST_UPDATE_UID);
3395        setUpdateDebugParams(configuration);
3396        return result;
3397    }
3398
3399    /**
3400     * Update network to WifiConfigManager config change and ensure that it was successful.
3401     */
3402    private NetworkUpdateResult verifyUpdateNetworkToWifiConfigManager(
3403            WifiConfiguration configuration) {
3404        NetworkUpdateResult result = updateNetworkToWifiConfigManager(configuration);
3405        assertTrue(result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID);
3406        assertFalse(result.isNewNetwork());
3407
3408        verifyNetworkUpdateBroadcast(configuration);
3409        // Verify that the config store write was triggered with this new configuration.
3410        verifyNetworkInConfigStoreData(configuration);
3411        return result;
3412    }
3413
3414    /**
3415     * Update network to WifiConfigManager without IP config change and ensure that it was
3416     * successful.
3417     */
3418    private NetworkUpdateResult verifyUpdateNetworkToWifiConfigManagerWithoutIpChange(
3419            WifiConfiguration configuration) {
3420        NetworkUpdateResult result = verifyUpdateNetworkToWifiConfigManager(configuration);
3421        assertFalse(result.hasIpChanged());
3422        assertFalse(result.hasProxyChanged());
3423        return result;
3424    }
3425
3426    /**
3427     * Update network to WifiConfigManager with IP config change and ensure that it was
3428     * successful.
3429     */
3430    private NetworkUpdateResult verifyUpdateNetworkToWifiConfigManagerWithIpChange(
3431            WifiConfiguration configuration) {
3432        NetworkUpdateResult result = verifyUpdateNetworkToWifiConfigManager(configuration);
3433        assertTrue(result.hasIpChanged());
3434        assertTrue(result.hasProxyChanged());
3435        return result;
3436    }
3437
3438    /**
3439     * Removes network from WifiConfigManager and ensure that it was successful.
3440     */
3441    private void verifyRemoveNetworkFromWifiConfigManager(
3442            WifiConfiguration configuration) {
3443        assertTrue(mWifiConfigManager.removeNetwork(configuration.networkId, TEST_CREATOR_UID));
3444
3445        verifyNetworkRemoveBroadcast(configuration);
3446        // Verify if the config store write was triggered without this new configuration.
3447        verifyNetworkNotInConfigStoreData(configuration);
3448    }
3449
3450    /**
3451     * Removes ephemeral network from WifiConfigManager and ensure that it was successful.
3452     */
3453    private void verifyRemoveEphemeralNetworkFromWifiConfigManager(
3454            WifiConfiguration configuration) throws Exception {
3455        assertTrue(mWifiConfigManager.removeNetwork(configuration.networkId, TEST_CREATOR_UID));
3456
3457        verifyNetworkRemoveBroadcast(configuration);
3458        // Ensure that the write was not invoked for ephemeral network remove.
3459        mContextConfigStoreMockOrder.verify(mWifiConfigStore, never())
3460                .write(anyBoolean(), any(WifiConfigStoreData.class));
3461    }
3462
3463    /**
3464     * Verifies the provided network's public status and ensures that the network change broadcast
3465     * has been sent out.
3466     */
3467    private void verifyUpdateNetworkStatus(WifiConfiguration configuration, int status) {
3468        assertEquals(status, configuration.status);
3469        verifyNetworkUpdateBroadcast(configuration);
3470    }
3471
3472    /**
3473     * Verifies the network's selection status update.
3474     *
3475     * For temporarily disabled reasons, the method ensures that the status has changed only if
3476     * disable reason counter has exceeded the threshold.
3477     *
3478     * For permanently disabled/enabled reasons, the method ensures that the public status has
3479     * changed and the network change broadcast has been sent out.
3480     */
3481    private void verifyUpdateNetworkSelectionStatus(
3482            int networkId, int reason, int temporaryDisableReasonCounter) {
3483        when(mClock.getElapsedSinceBootMillis())
3484                .thenReturn(TEST_ELAPSED_UPDATE_NETWORK_SELECTION_TIME_MILLIS);
3485
3486        // Fetch the current status of the network before we try to update the status.
3487        WifiConfiguration retrievedNetwork = mWifiConfigManager.getConfiguredNetwork(networkId);
3488        NetworkSelectionStatus currentStatus = retrievedNetwork.getNetworkSelectionStatus();
3489        int currentDisableReason = currentStatus.getNetworkSelectionDisableReason();
3490
3491        // First set the status to the provided reason.
3492        assertTrue(mWifiConfigManager.updateNetworkSelectionStatus(networkId, reason));
3493
3494        // Now fetch the network configuration and verify the new status of the network.
3495        retrievedNetwork = mWifiConfigManager.getConfiguredNetwork(networkId);
3496
3497        NetworkSelectionStatus retrievedStatus = retrievedNetwork.getNetworkSelectionStatus();
3498        int retrievedDisableReason = retrievedStatus.getNetworkSelectionDisableReason();
3499        long retrievedDisableTime = retrievedStatus.getDisableTime();
3500        int retrievedDisableReasonCounter = retrievedStatus.getDisableReasonCounter(reason);
3501        int disableReasonThreshold =
3502                WifiConfigManager.NETWORK_SELECTION_DISABLE_THRESHOLD[reason];
3503
3504        if (reason == NetworkSelectionStatus.NETWORK_SELECTION_ENABLE) {
3505            assertEquals(reason, retrievedDisableReason);
3506            assertTrue(retrievedStatus.isNetworkEnabled());
3507            assertEquals(
3508                    NetworkSelectionStatus.INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP,
3509                    retrievedDisableTime);
3510            verifyUpdateNetworkStatus(retrievedNetwork, WifiConfiguration.Status.ENABLED);
3511        } else if (reason < NetworkSelectionStatus.DISABLED_TLS_VERSION_MISMATCH) {
3512            // For temporarily disabled networks, we need to ensure that the current status remains
3513            // until the threshold is crossed.
3514            assertEquals(temporaryDisableReasonCounter, retrievedDisableReasonCounter);
3515            if (retrievedDisableReasonCounter < disableReasonThreshold) {
3516                assertEquals(currentDisableReason, retrievedDisableReason);
3517                assertEquals(
3518                        currentStatus.getNetworkSelectionStatus(),
3519                        retrievedStatus.getNetworkSelectionStatus());
3520            } else {
3521                assertEquals(reason, retrievedDisableReason);
3522                assertTrue(retrievedStatus.isNetworkTemporaryDisabled());
3523                assertEquals(
3524                        TEST_ELAPSED_UPDATE_NETWORK_SELECTION_TIME_MILLIS, retrievedDisableTime);
3525            }
3526        } else if (reason < NetworkSelectionStatus.NETWORK_SELECTION_DISABLED_MAX) {
3527            assertEquals(reason, retrievedDisableReason);
3528            assertTrue(retrievedStatus.isNetworkPermanentlyDisabled());
3529            assertEquals(
3530                    NetworkSelectionStatus.INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP,
3531                    retrievedDisableTime);
3532            verifyUpdateNetworkStatus(retrievedNetwork, WifiConfiguration.Status.DISABLED);
3533        }
3534    }
3535
3536    /**
3537     * Creates a scan detail corresponding to the provided network and given BSSID, level &frequency
3538     * values.
3539     */
3540    private ScanDetail createScanDetailForNetwork(
3541            WifiConfiguration configuration, String bssid, int level, int frequency) {
3542        String caps;
3543        if (configuration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_PSK)) {
3544            caps = "[WPA2-PSK-CCMP]";
3545        } else if (configuration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_EAP)
3546                || configuration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.IEEE8021X)) {
3547            caps = "[WPA2-EAP-CCMP]";
3548        } else if (configuration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.NONE)
3549                && WifiConfigurationUtil.hasAnyValidWepKey(configuration.wepKeys)) {
3550            caps = "[WEP]";
3551        } else {
3552            caps = "[]";
3553        }
3554        WifiSsid ssid = WifiSsid.createFromAsciiEncoded(configuration.getPrintableSsid());
3555        // Fill in 0's in the fields we don't care about.
3556        return new ScanDetail(
3557                ssid, bssid, caps, level, frequency, mClock.getUptimeSinceBootMillis(),
3558                mClock.getWallClockMillis());
3559    }
3560
3561    /**
3562     * Creates a scan detail corresponding to the provided network and BSSID value.
3563     */
3564    private ScanDetail createScanDetailForNetwork(WifiConfiguration configuration, String bssid) {
3565        return createScanDetailForNetwork(configuration, bssid, 0, 0);
3566    }
3567
3568    /**
3569     * Creates a scan detail corresponding to the provided network and fixed BSSID value.
3570     */
3571    private ScanDetail createScanDetailForNetwork(WifiConfiguration configuration) {
3572        return createScanDetailForNetwork(configuration, TEST_BSSID);
3573    }
3574
3575    /**
3576     * Adds the provided network and then creates a scan detail corresponding to the network. The
3577     * method then creates a ScanDetail corresponding to the network and ensures that the network
3578     * is properly matched using
3579     * {@link WifiConfigManager#getSavedNetworkForScanDetailAndCache(ScanDetail)} and also
3580     * verifies that the provided scan detail was cached,
3581     */
3582    private void verifyAddSingleNetworkAndMatchScanDetailToNetworkAndCache(
3583            WifiConfiguration network) {
3584        // First add the provided network.
3585        verifyAddNetworkToWifiConfigManager(network);
3586
3587        // Now create a dummy scan detail corresponding to the network.
3588        ScanDetail scanDetail = createScanDetailForNetwork(network);
3589        ScanResult scanResult = scanDetail.getScanResult();
3590
3591        WifiConfiguration retrievedNetwork =
3592                mWifiConfigManager.getSavedNetworkForScanDetailAndCache(scanDetail);
3593        // Retrieve the network with password data for comparison.
3594        retrievedNetwork =
3595                mWifiConfigManager.getConfiguredNetworkWithPassword(retrievedNetwork.networkId);
3596
3597        WifiConfigurationTestUtil.assertConfigurationEqualForConfigManagerAddOrUpdate(
3598                network, retrievedNetwork);
3599
3600        // Now retrieve the scan detail cache and ensure that the new scan detail is in cache.
3601        ScanDetailCache retrievedScanDetailCache =
3602                mWifiConfigManager.getScanDetailCacheForNetwork(network.networkId);
3603        assertEquals(1, retrievedScanDetailCache.size());
3604        ScanResult retrievedScanResult = retrievedScanDetailCache.get(scanResult.BSSID);
3605
3606        ScanTestUtil.assertScanResultEquals(scanResult, retrievedScanResult);
3607    }
3608
3609    /**
3610     * Adds a new network and verifies that the |HasEverConnected| flag is set to false.
3611     */
3612    private void verifyAddNetworkHasEverConnectedFalse(WifiConfiguration network) {
3613        NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(network);
3614        WifiConfiguration retrievedNetwork =
3615                mWifiConfigManager.getConfiguredNetwork(result.getNetworkId());
3616        assertFalse("Adding a new network should not have hasEverConnected set to true.",
3617                retrievedNetwork.getNetworkSelectionStatus().getHasEverConnected());
3618    }
3619
3620    /**
3621     * Updates an existing network with some credential change and verifies that the
3622     * |HasEverConnected| flag is set to false.
3623     */
3624    private void verifyUpdateNetworkWithCredentialChangeHasEverConnectedFalse(
3625            WifiConfiguration network) {
3626        NetworkUpdateResult result = verifyUpdateNetworkToWifiConfigManagerWithoutIpChange(network);
3627        WifiConfiguration retrievedNetwork =
3628                mWifiConfigManager.getConfiguredNetwork(result.getNetworkId());
3629        assertFalse("Updating network credentials config should clear hasEverConnected.",
3630                retrievedNetwork.getNetworkSelectionStatus().getHasEverConnected());
3631    }
3632
3633    /**
3634     * Updates an existing network after connection using
3635     * {@link WifiConfigManager#updateNetworkAfterConnect(int)} and asserts that the
3636     * |HasEverConnected| flag is set to true.
3637     */
3638    private void verifyUpdateNetworkAfterConnectHasEverConnectedTrue(int networkId) {
3639        assertTrue(mWifiConfigManager.updateNetworkAfterConnect(networkId));
3640        WifiConfiguration retrievedNetwork = mWifiConfigManager.getConfiguredNetwork(networkId);
3641        assertTrue("hasEverConnected expected to be true after connection.",
3642                retrievedNetwork.getNetworkSelectionStatus().getHasEverConnected());
3643    }
3644
3645    /**
3646     * Sets up a user profiles for WifiConfigManager testing.
3647     *
3648     * @param userId Id of the user.
3649     */
3650    private void setupUserProfiles(int userId) {
3651        final UserInfo userInfo =
3652                new UserInfo(userId, Integer.toString(userId), UserInfo.FLAG_PRIMARY);
3653        List<UserInfo> userProfiles = Arrays.asList(userInfo);
3654        when(mUserManager.getProfiles(userId)).thenReturn(userProfiles);
3655        when(mUserManager.isUserUnlockingOrUnlocked(userId)).thenReturn(true);
3656    }
3657
3658}
3659