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