WifiConfigManagerTest.java revision bbf3b21e42e6f13bddd1c30e4266b5be0d1404be
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 = 5;
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) {
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)}.
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    }
1484
1485    /**
1486     * Verifies the creation of channel list using
1487     * {@link WifiConfigManager#fetchChannelSetForNetworkForPartialScan(int, long)} and ensures
1488     * that scan results which have a timestamp  beyond the provided age are not used in the
1489     * channel list.
1490     */
1491    @Test
1492    public void testFetchChannelSetForNetworkIgnoresStaleScanResults() {
1493        WifiConfiguration network = WifiConfigurationTestUtil.createPskNetwork();
1494        verifyAddNetworkToWifiConfigManager(network);
1495
1496        long wallClockBase = 0;
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            // Increment the seen value in the scan results for each of them.
1501            when(mClock.getWallClockMillis()).thenReturn(wallClockBase + i);
1502            ScanDetail networkScanDetail =
1503                    createScanDetailForNetwork(
1504                            network, test_bssid_base + Integer.toString(i), 0, TEST_FREQ_LIST[i]);
1505            assertNotNull(
1506                    mWifiConfigManager.getSavedNetworkForScanDetailAndCache(networkScanDetail));
1507
1508        }
1509        int ageInMillis = 4;
1510        // Now fetch only scan results which are 4 millis stale. This should ignore the first
1511        // scan result.
1512        assertEquals(
1513                new HashSet<>(Arrays.asList(
1514                        Arrays.copyOfRange(
1515                                TEST_FREQ_LIST,
1516                                TEST_FREQ_LIST.length - ageInMillis, TEST_FREQ_LIST.length))),
1517                mWifiConfigManager.fetchChannelSetForNetworkForPartialScan(
1518                        network.networkId, ageInMillis));
1519    }
1520
1521    /**
1522     * Verifies the creation of channel list using
1523     * {@link WifiConfigManager#fetchChannelSetForNetworkForPartialScan(int, long)} and ensures
1524     * that the list size does not exceed the max configured for the device.
1525     */
1526    @Test
1527    public void testFetchChannelSetForNetworkIsLimitedToConfiguredSize() {
1528        // Need to recreate the WifiConfigManager instance for this test to modify the config
1529        // value which is read only in the constructor.
1530        int maxListSize = 3;
1531        mResources.setInteger(
1532                R.integer.config_wifi_framework_associated_partial_scan_max_num_active_channels,
1533                maxListSize);
1534        createWifiConfigManager();
1535
1536        WifiConfiguration network = WifiConfigurationTestUtil.createPskNetwork();
1537        verifyAddNetworkToWifiConfigManager(network);
1538
1539        // Create 5 scan results with different bssid's & frequencies.
1540        String test_bssid_base = "af:89:56:34:56:6";
1541        for (int i = 0; i < TEST_FREQ_LIST.length; i++) {
1542            ScanDetail networkScanDetail =
1543                    createScanDetailForNetwork(
1544                            network, test_bssid_base + Integer.toString(i), 0, TEST_FREQ_LIST[i]);
1545            assertNotNull(
1546                    mWifiConfigManager.getSavedNetworkForScanDetailAndCache(networkScanDetail));
1547
1548        }
1549        // Ensure that the fetched list size is limited.
1550        assertEquals(maxListSize,
1551                mWifiConfigManager.fetchChannelSetForNetworkForPartialScan(
1552                        network.networkId, 1).size());
1553    }
1554
1555    /**
1556     * Verifies the creation of channel list using
1557     * {@link WifiConfigManager#fetchChannelSetForNetworkForPartialScan(int, long)} and ensures
1558     * that scan results from linked networks are used in the channel list.
1559     */
1560    @Test
1561    public void testFetchChannelSetForNetworkIncludesLinkedNetworks() {
1562        WifiConfiguration network1 = WifiConfigurationTestUtil.createPskNetwork();
1563        WifiConfiguration network2 = WifiConfigurationTestUtil.createPskNetwork();
1564        verifyAddNetworkToWifiConfigManager(network1);
1565        verifyAddNetworkToWifiConfigManager(network2);
1566
1567        String test_bssid_base = "af:89:56:34:56:6";
1568        int TEST_FREQ_LISTIdx = 0;
1569        // Create 3 scan results with different bssid's & frequencies for network 1.
1570        for (; TEST_FREQ_LISTIdx < TEST_FREQ_LIST.length / 2; TEST_FREQ_LISTIdx++) {
1571            ScanDetail networkScanDetail =
1572                    createScanDetailForNetwork(
1573                            network1, test_bssid_base + Integer.toString(TEST_FREQ_LISTIdx), 0,
1574                            TEST_FREQ_LIST[TEST_FREQ_LISTIdx]);
1575            assertNotNull(
1576                    mWifiConfigManager.getSavedNetworkForScanDetailAndCache(networkScanDetail));
1577
1578        }
1579        // Create 3 scan results with different bssid's & frequencies for network 2.
1580        for (; TEST_FREQ_LISTIdx < TEST_FREQ_LIST.length; TEST_FREQ_LISTIdx++) {
1581            ScanDetail networkScanDetail =
1582                    createScanDetailForNetwork(
1583                            network2, test_bssid_base + Integer.toString(TEST_FREQ_LISTIdx), 0,
1584                            TEST_FREQ_LIST[TEST_FREQ_LISTIdx]);
1585            assertNotNull(
1586                    mWifiConfigManager.getSavedNetworkForScanDetailAndCache(networkScanDetail));
1587        }
1588
1589        // Link the 2 configurations together using the GwMacAddress.
1590        assertTrue(mWifiConfigManager.setNetworkDefaultGwMacAddress(
1591                network1.networkId, TEST_DEFAULT_GW_MAC_ADDRESS));
1592        assertTrue(mWifiConfigManager.setNetworkDefaultGwMacAddress(
1593                network2.networkId, TEST_DEFAULT_GW_MAC_ADDRESS));
1594
1595        // The channel list fetched should include scan results from both the linked networks.
1596        assertEquals(new HashSet<Integer>(Arrays.asList(TEST_FREQ_LIST)),
1597                mWifiConfigManager.fetchChannelSetForNetworkForPartialScan(network1.networkId, 1));
1598        assertEquals(new HashSet<Integer>(Arrays.asList(TEST_FREQ_LIST)),
1599                mWifiConfigManager.fetchChannelSetForNetworkForPartialScan(network2.networkId, 1));
1600    }
1601
1602    /**
1603     * Verifies the creation of channel list using
1604     * {@link WifiConfigManager#fetchChannelSetForNetworkForPartialScan(int, long)} and ensures
1605     * that scan results from linked networks are used in the channel list and that the list size
1606     * does not exceed the max configured for the device.
1607     */
1608    @Test
1609    public void testFetchChannelSetForNetworkIncludesLinkedNetworksIsLimitedToConfiguredSize() {
1610        // Need to recreate the WifiConfigManager instance for this test to modify the config
1611        // value which is read only in the constructor.
1612        int maxListSize = 3;
1613        mResources.setInteger(
1614                R.integer.config_wifi_framework_associated_partial_scan_max_num_active_channels,
1615                maxListSize);
1616
1617        createWifiConfigManager();
1618        WifiConfiguration network1 = WifiConfigurationTestUtil.createPskNetwork();
1619        WifiConfiguration network2 = WifiConfigurationTestUtil.createPskNetwork();
1620        verifyAddNetworkToWifiConfigManager(network1);
1621        verifyAddNetworkToWifiConfigManager(network2);
1622
1623        String test_bssid_base = "af:89:56:34:56:6";
1624        int TEST_FREQ_LISTIdx = 0;
1625        // Create 3 scan results with different bssid's & frequencies for network 1.
1626        for (; TEST_FREQ_LISTIdx < TEST_FREQ_LIST.length / 2; TEST_FREQ_LISTIdx++) {
1627            ScanDetail networkScanDetail =
1628                    createScanDetailForNetwork(
1629                            network1, test_bssid_base + Integer.toString(TEST_FREQ_LISTIdx), 0,
1630                            TEST_FREQ_LIST[TEST_FREQ_LISTIdx]);
1631            assertNotNull(
1632                    mWifiConfigManager.getSavedNetworkForScanDetailAndCache(networkScanDetail));
1633
1634        }
1635        // Create 3 scan results with different bssid's & frequencies for network 2.
1636        for (; TEST_FREQ_LISTIdx < TEST_FREQ_LIST.length; TEST_FREQ_LISTIdx++) {
1637            ScanDetail networkScanDetail =
1638                    createScanDetailForNetwork(
1639                            network2, test_bssid_base + Integer.toString(TEST_FREQ_LISTIdx), 0,
1640                            TEST_FREQ_LIST[TEST_FREQ_LISTIdx]);
1641            assertNotNull(
1642                    mWifiConfigManager.getSavedNetworkForScanDetailAndCache(networkScanDetail));
1643        }
1644
1645        // Link the 2 configurations together using the GwMacAddress.
1646        assertTrue(mWifiConfigManager.setNetworkDefaultGwMacAddress(
1647                network1.networkId, TEST_DEFAULT_GW_MAC_ADDRESS));
1648        assertTrue(mWifiConfigManager.setNetworkDefaultGwMacAddress(
1649                network2.networkId, TEST_DEFAULT_GW_MAC_ADDRESS));
1650
1651        // Ensure that the fetched list size is limited.
1652        assertEquals(maxListSize,
1653                mWifiConfigManager.fetchChannelSetForNetworkForPartialScan(
1654                        network1.networkId, 1).size());
1655        assertEquals(maxListSize,
1656                mWifiConfigManager.fetchChannelSetForNetworkForPartialScan(
1657                        network2.networkId, 1).size());
1658    }
1659
1660    /**
1661     * Verifies the foreground user switch using {@link WifiConfigManager#handleUserSwitch(int)}
1662     * and ensures that any non current user private networks are moved to shared store file.
1663     */
1664    @Test
1665    public void testHandleUserSwitchPushesOtherPrivateNetworksToSharedStore() throws Exception {
1666        int user1 = TEST_DEFAULT_USER;
1667        int user2 = TEST_DEFAULT_USER + 1;
1668        setupUserProfiles(user2);
1669
1670        int appId = 674;
1671
1672        // Create 3 networks. 1 for user1, 1 for user2 and 1 shared.
1673        final WifiConfiguration user1Network = WifiConfigurationTestUtil.createPskNetwork();
1674        user1Network.shared = false;
1675        user1Network.creatorUid = UserHandle.getUid(user1, appId);
1676        final WifiConfiguration user2Network = WifiConfigurationTestUtil.createPskNetwork();
1677        user2Network.shared = false;
1678        user2Network.creatorUid = UserHandle.getUid(user2, appId);
1679        final WifiConfiguration sharedNetwork = WifiConfigurationTestUtil.createPskNetwork();
1680
1681        // Set up the store data first that is loaded.
1682        List<WifiConfiguration> sharedNetworks = new ArrayList<WifiConfiguration>() {
1683            {
1684                add(sharedNetwork);
1685                add(user2Network);
1686            }
1687        };
1688        List<WifiConfiguration> userNetworks = new ArrayList<WifiConfiguration>() {
1689            {
1690                add(user1Network);
1691            }
1692        };
1693        WifiConfigStoreData loadStoreData =
1694                new WifiConfigStoreData(sharedNetworks, userNetworks, new HashSet<String>());
1695        when(mWifiConfigStore.read()).thenReturn(loadStoreData);
1696
1697        // Now switch the user to user2
1698        mWifiConfigManager.handleUserSwitch(user2);
1699
1700        // Set the expected network list before comparing. user1Network should be in shared data.
1701        // Note: In the real world, user1Network will no longer be visible now because it should
1702        // already be in user1's private store file. But, we're purposefully exposing it
1703        // via |loadStoreData| to test if other user's private networks are pushed to shared store.
1704        List<WifiConfiguration> expectedSharedNetworks = new ArrayList<WifiConfiguration>() {
1705            {
1706                add(sharedNetwork);
1707                add(user1Network);
1708            }
1709        };
1710        List<WifiConfiguration> expectedUserNetworks = new ArrayList<WifiConfiguration>() {
1711            {
1712                add(user2Network);
1713            }
1714        };
1715        // Capture the written data for the old user and ensure that it was empty.
1716        WifiConfigStoreData writtenStoreData = captureWriteStoreData();
1717        assertTrue(writtenStoreData.getConfigurations().isEmpty());
1718
1719        // Now capture the next written data and ensure that user1Network is now in shared data.
1720        writtenStoreData = captureWriteStoreData();
1721        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
1722                expectedSharedNetworks, writtenStoreData.getSharedConfigurations());
1723        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
1724                expectedUserNetworks, writtenStoreData.getUserConfigurations());
1725    }
1726
1727    /**
1728     * Verifies the foreground user switch using {@link WifiConfigManager#handleUserSwitch(int)}
1729     * and {@link WifiConfigManager#handleUserUnlock(int)} and ensures that the new store is
1730     * read immediately if the user is unlocked during the switch.
1731     */
1732    @Test
1733    public void testHandleUserSwitchWhenUnlocked() throws Exception {
1734        int user1 = TEST_DEFAULT_USER;
1735        int user2 = TEST_DEFAULT_USER + 1;
1736        setupUserProfiles(user2);
1737
1738        when(mWifiConfigStore.read()).thenReturn(
1739                new WifiConfigStoreData(
1740                        new ArrayList<WifiConfiguration>(), new ArrayList<WifiConfiguration>(),
1741                        new HashSet<String>()));
1742
1743        // user2 is unlocked and switched to foreground.
1744        when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(true);
1745        mWifiConfigManager.handleUserSwitch(user2);
1746        // Ensure that the read was invoked.
1747        mContextConfigStoreMockOrder.verify(mWifiConfigStore).read();
1748    }
1749
1750    /**
1751     * Verifies the foreground user switch using {@link WifiConfigManager#handleUserSwitch(int)}
1752     * and {@link WifiConfigManager#handleUserUnlock(int)} and ensures that the new store is not
1753     * read until the user is unlocked.
1754     */
1755    public void testHandleUserSwitchWhenLocked() throws Exception {
1756        int user1 = TEST_DEFAULT_USER;
1757        int user2 = TEST_DEFAULT_USER + 1;
1758        setupUserProfiles(user2);
1759
1760        // user2 is locked and switched to foreground.
1761        when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(false);
1762        mWifiConfigManager.handleUserSwitch(user2);
1763
1764        // Ensure that the read was not invoked.
1765        mContextConfigStoreMockOrder.verify(mWifiConfigStore, never()).read();
1766
1767        // Now try unlocking some other user (user1), this should be ignored.
1768        mWifiConfigManager.handleUserUnlock(user1);
1769        mContextConfigStoreMockOrder.verify(mWifiConfigStore, never()).read();
1770
1771        when(mWifiConfigStore.read()).thenReturn(
1772                new WifiConfigStoreData(
1773                        new ArrayList<WifiConfiguration>(), new ArrayList<WifiConfiguration>(),
1774                        new HashSet<String>()));
1775
1776        // Unlock the user2 and ensure that we read the data now.
1777        mWifiConfigManager.handleUserUnlock(user2);
1778        mContextConfigStoreMockOrder.verify(mWifiConfigStore).read();
1779    }
1780
1781    /**
1782     * Verifies that the foreground user stop using {@link WifiConfigManager#handleUserStop(int)}
1783     * and ensures that the store is written only when the foreground user is stopped.
1784     */
1785    @Test
1786    public void testHandleUserStop() throws Exception {
1787        int user1 = TEST_DEFAULT_USER;
1788        int user2 = TEST_DEFAULT_USER + 1;
1789        setupUserProfiles(user2);
1790
1791        // Try stopping background user2 first, this should not do anything.
1792        when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(false);
1793        mWifiConfigManager.handleUserStop(user2);
1794        mContextConfigStoreMockOrder.verify(mWifiConfigStore, never()).read();
1795
1796        // Now try stopping the foreground user1, this should trigger a write to store.
1797        mWifiConfigManager.handleUserStop(user1);
1798        mContextConfigStoreMockOrder.verify(mWifiConfigStore, never()).read();
1799        mContextConfigStoreMockOrder.verify(mWifiConfigStore).write(
1800                anyBoolean(), any(WifiConfigStoreData.class));
1801    }
1802
1803    /**
1804     * Verifies the foreground user unlock via {@link WifiConfigManager#handleUserUnlock(int)}
1805     * results in a store read after bootup.
1806     */
1807    @Test
1808    public void testHandleUserUnlockAfterBootup() throws Exception {
1809        int user1 = TEST_DEFAULT_USER;
1810
1811        when(mWifiConfigStore.read()).thenReturn(
1812                new WifiConfigStoreData(
1813                        new ArrayList<WifiConfiguration>(), new ArrayList<WifiConfiguration>(),
1814                        new HashSet<String>()));
1815
1816        // Unlock the user1 (default user) for the first time and ensure that we read the data.
1817        mWifiConfigManager.handleUserUnlock(user1);
1818        mContextConfigStoreMockOrder.verify(mWifiConfigStore).read();
1819    }
1820
1821    /**
1822     * Verifies the foreground user unlock via {@link WifiConfigManager#handleUserUnlock(int)} does
1823     * not always result in a store read unless the user had switched or just booted up.
1824     */
1825    @Test
1826    public void testHandleUserUnlockWithoutSwitchOrBootup() throws Exception {
1827        int user1 = TEST_DEFAULT_USER;
1828        int user2 = TEST_DEFAULT_USER + 1;
1829        setupUserProfiles(user2);
1830
1831        when(mWifiConfigStore.read()).thenReturn(
1832                new WifiConfigStoreData(
1833                        new ArrayList<WifiConfiguration>(), new ArrayList<WifiConfiguration>(),
1834                        new HashSet<String>()));
1835
1836        // user2 is unlocked and switched to foreground.
1837        when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(true);
1838        mWifiConfigManager.handleUserSwitch(user2);
1839        // Ensure that the read was invoked.
1840        mContextConfigStoreMockOrder.verify(mWifiConfigStore).read();
1841
1842        // Unlock the user2 again and ensure that we don't read the data now.
1843        mWifiConfigManager.handleUserUnlock(user2);
1844        mContextConfigStoreMockOrder.verify(mWifiConfigStore, never()).read();
1845    }
1846
1847    /**
1848     * Verifies the private network addition using
1849     * {@link WifiConfigManager#addOrUpdateNetwork(WifiConfiguration, int)}
1850     * by a non foreground user is rejected.
1851     */
1852    @Test
1853    public void testAddNetworkUsingBackgroundUserUId() throws Exception {
1854        int user2 = TEST_DEFAULT_USER + 1;
1855        setupUserProfiles(user2);
1856
1857        int creatorUid = UserHandle.getUid(user2, 674);
1858
1859        // Create a network for user2 try adding it. This should be rejected.
1860        final WifiConfiguration user2Network = WifiConfigurationTestUtil.createPskNetwork();
1861        NetworkUpdateResult result =
1862                mWifiConfigManager.addOrUpdateNetwork(user2Network, creatorUid);
1863        assertFalse(result.isSuccess());
1864    }
1865
1866    /**
1867     * Verifies the private network addition using
1868     * {@link WifiConfigManager#addOrUpdateNetwork(WifiConfiguration, int)}
1869     * by SysUI is always accepted.
1870     */
1871    @Test
1872    public void testAddNetworkUsingSysUiUid() throws Exception {
1873        // Set up the user profiles stuff. Needed for |WifiConfigurationUtil.isVisibleToAnyProfile|
1874        int user2 = TEST_DEFAULT_USER + 1;
1875        setupUserProfiles(user2);
1876
1877        when(mUserManager.isUserUnlockingOrUnlocked(user2)).thenReturn(false);
1878        mWifiConfigManager.handleUserSwitch(user2);
1879
1880        // Create a network for user2 try adding it. This should be rejected.
1881        final WifiConfiguration user2Network = WifiConfigurationTestUtil.createPskNetwork();
1882        NetworkUpdateResult result =
1883                mWifiConfigManager.addOrUpdateNetwork(user2Network, TEST_SYSUI_UID);
1884        assertTrue(result.isSuccess());
1885    }
1886
1887    /**
1888     * Verifies the loading of networks using {@link WifiConfigManager#loadFromStore()} attempts
1889     * to migrate data from legacy stores when the new store files are absent.
1890     */
1891    @Test
1892    public void testMigrationFromLegacyStore() throws Exception {
1893        // Create the store data to be returned from legacy stores.
1894        List<WifiConfiguration> networks = new ArrayList<>();
1895        networks.add(WifiConfigurationTestUtil.createPskNetwork());
1896        networks.add(WifiConfigurationTestUtil.createEapNetwork());
1897        networks.add(WifiConfigurationTestUtil.createWepNetwork());
1898        String deletedEphemeralSSID = "EphemeralSSID";
1899        Set<String> deletedEphermalSSIDs = new HashSet<>(Arrays.asList(deletedEphemeralSSID));
1900        WifiConfigStoreDataLegacy storeData =
1901                new WifiConfigStoreDataLegacy(networks, deletedEphermalSSIDs);
1902
1903        // New store files not present, so migrate from the old store.
1904        when(mWifiConfigStore.areStoresPresent()).thenReturn(false);
1905        when(mWifiConfigStoreLegacy.areStoresPresent()).thenReturn(true);
1906        when(mWifiConfigStoreLegacy.read()).thenReturn(storeData);
1907
1908        // Now trigger a load from store. This should populate the in memory list with all the
1909        // networks above from the legacy store.
1910        mWifiConfigManager.loadFromStore();
1911
1912        verify(mWifiConfigStore, never()).read();
1913        verify(mWifiConfigStoreLegacy).read();
1914
1915        List<WifiConfiguration> retrievedNetworks =
1916                mWifiConfigManager.getConfiguredNetworksWithPasswords();
1917        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
1918                networks, retrievedNetworks);
1919        assertTrue(mWifiConfigManager.wasEphemeralNetworkDeleted(deletedEphemeralSSID));
1920    }
1921
1922    /**
1923     * Verifies the loading of networks using {@link WifiConfigManager#loadFromStore()} does
1924     * not attempt to read from any of the stores (new or legacy) when the store files are
1925     * not present.
1926     */
1927    @Test
1928    public void testFreshInstallDoesNotLoadFromStore() throws Exception {
1929        // New store files not present, so migrate from the old store.
1930        when(mWifiConfigStore.areStoresPresent()).thenReturn(false);
1931        when(mWifiConfigStoreLegacy.areStoresPresent()).thenReturn(false);
1932
1933        // Now trigger a load from store. This should populate the in memory list with all the
1934        // networks above.
1935        mWifiConfigManager.loadFromStore();
1936
1937        verify(mWifiConfigStore, never()).read();
1938        verify(mWifiConfigStoreLegacy, never()).read();
1939
1940        assertTrue(mWifiConfigManager.getConfiguredNetworksWithPasswords().isEmpty());
1941    }
1942
1943    /**
1944     * Verifies that the last user selected network parameter is set when
1945     * {@link WifiConfigManager#enableNetwork(int, boolean, int)} with disableOthers flag is set
1946     * to true and cleared when either {@link WifiConfigManager#disableNetwork(int, int)} or
1947     * {@link WifiConfigManager#removeNetwork(int, int)} is invoked using the same network ID.
1948     */
1949    @Test
1950    public void testLastSelectedNetwork() throws Exception {
1951        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
1952        NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(openNetwork);
1953
1954        when(mClock.getElapsedSinceBootMillis()).thenReturn(67L);
1955        assertTrue(mWifiConfigManager.enableNetwork(
1956                result.getNetworkId(), true, TEST_CREATOR_UID));
1957        assertEquals(result.getNetworkId(), mWifiConfigManager.getLastSelectedNetwork());
1958        assertEquals(67, mWifiConfigManager.getLastSelectedTimeStamp());
1959
1960        // Now disable the network and ensure that the last selected flag is cleared.
1961        assertTrue(mWifiConfigManager.disableNetwork(result.getNetworkId(), TEST_CREATOR_UID));
1962        assertEquals(
1963                WifiConfiguration.INVALID_NETWORK_ID, mWifiConfigManager.getLastSelectedNetwork());
1964
1965        // Enable it again and remove the network to ensure that the last selected flag was cleared.
1966        assertTrue(mWifiConfigManager.enableNetwork(
1967                result.getNetworkId(), true, TEST_CREATOR_UID));
1968        assertEquals(result.getNetworkId(), mWifiConfigManager.getLastSelectedNetwork());
1969        assertEquals(openNetwork.configKey(), mWifiConfigManager.getLastSelectedNetworkConfigKey());
1970
1971        assertTrue(mWifiConfigManager.removeNetwork(result.getNetworkId(), TEST_CREATOR_UID));
1972        assertEquals(
1973                WifiConfiguration.INVALID_NETWORK_ID, mWifiConfigManager.getLastSelectedNetwork());
1974    }
1975
1976    /**
1977     * Verifies that all the networks for the provided app is removed when
1978     * {@link WifiConfigManager#removeNetworksForApp(ApplicationInfo)} is invoked.
1979     */
1980    @Test
1981    public void testRemoveNetworksForApp() throws Exception {
1982        verifyAddNetworkToWifiConfigManager(WifiConfigurationTestUtil.createOpenNetwork());
1983        verifyAddNetworkToWifiConfigManager(WifiConfigurationTestUtil.createPskNetwork());
1984        verifyAddNetworkToWifiConfigManager(WifiConfigurationTestUtil.createWepNetwork());
1985
1986        assertFalse(mWifiConfigManager.getConfiguredNetworks().isEmpty());
1987
1988        ApplicationInfo app = new ApplicationInfo();
1989        app.uid = TEST_CREATOR_UID;
1990        app.packageName = TEST_CREATOR_NAME;
1991        assertTrue(mWifiConfigManager.removeNetworksForApp(app));
1992
1993        // Ensure all the networks are removed now.
1994        assertTrue(mWifiConfigManager.getConfiguredNetworks().isEmpty());
1995    }
1996
1997    /**
1998     * Verifies that all the networks for the provided user is removed when
1999     * {@link WifiConfigManager#removeNetworksForUser(int)} is invoked.
2000     */
2001    @Test
2002    public void testRemoveNetworksForUser() throws Exception {
2003        verifyAddNetworkToWifiConfigManager(WifiConfigurationTestUtil.createOpenNetwork());
2004        verifyAddNetworkToWifiConfigManager(WifiConfigurationTestUtil.createPskNetwork());
2005        verifyAddNetworkToWifiConfigManager(WifiConfigurationTestUtil.createWepNetwork());
2006
2007        assertFalse(mWifiConfigManager.getConfiguredNetworks().isEmpty());
2008
2009        assertTrue(mWifiConfigManager.removeNetworksForUser(TEST_DEFAULT_USER));
2010
2011        // Ensure all the networks are removed now.
2012        assertTrue(mWifiConfigManager.getConfiguredNetworks().isEmpty());
2013    }
2014
2015    /**
2016     * Verifies that the connect choice is removed from all networks when
2017     * {@link WifiConfigManager#removeNetwork(int, int)} is invoked.
2018     */
2019    @Test
2020    public void testRemoveNetworkRemovesConnectChoice() throws Exception {
2021        WifiConfiguration network1 = WifiConfigurationTestUtil.createOpenNetwork();
2022        WifiConfiguration network2 = WifiConfigurationTestUtil.createPskNetwork();
2023        WifiConfiguration network3 = WifiConfigurationTestUtil.createPskNetwork();
2024        verifyAddNetworkToWifiConfigManager(network1);
2025        verifyAddNetworkToWifiConfigManager(network2);
2026        verifyAddNetworkToWifiConfigManager(network3);
2027
2028        // Set connect choice of network 2 over network 1.
2029        assertTrue(
2030                mWifiConfigManager.setNetworkConnectChoice(
2031                        network1.networkId, network2.configKey(), 78L));
2032
2033        WifiConfiguration retrievedNetwork =
2034                mWifiConfigManager.getConfiguredNetwork(network1.networkId);
2035        assertEquals(
2036                network2.configKey(),
2037                retrievedNetwork.getNetworkSelectionStatus().getConnectChoice());
2038
2039        // Remove network 3 and ensure that the connect choice on network 1 is not removed.
2040        assertTrue(mWifiConfigManager.removeNetwork(network3.networkId, TEST_CREATOR_UID));
2041        retrievedNetwork = mWifiConfigManager.getConfiguredNetwork(network1.networkId);
2042        assertEquals(
2043                network2.configKey(),
2044                retrievedNetwork.getNetworkSelectionStatus().getConnectChoice());
2045
2046        // Now remove network 2 and ensure that the connect choice on network 1 is removed..
2047        assertTrue(mWifiConfigManager.removeNetwork(network2.networkId, TEST_CREATOR_UID));
2048        retrievedNetwork = mWifiConfigManager.getConfiguredNetwork(network1.networkId);
2049        assertNotEquals(
2050                network2.configKey(),
2051                retrievedNetwork.getNetworkSelectionStatus().getConnectChoice());
2052
2053        // This should have triggered 2 buffered writes. 1 for setting the connect choice, 1 for
2054        // clearing it after network removal.
2055        mContextConfigStoreMockOrder.verify(mWifiConfigStore, times(2))
2056                .write(eq(false), any(WifiConfigStoreData.class));
2057    }
2058
2059    /**
2060     * Verifies that the modification of a single network using
2061     * {@link WifiConfigManager#addOrUpdateNetwork(WifiConfiguration, int)} and ensures that any
2062     * updates to the network config in
2063     * {@link WifiKeyStore#updateNetworkKeys(WifiConfiguration, WifiConfiguration)} is reflected
2064     * in the internal database.
2065     */
2066    @Test
2067    public void testUpdateSingleNetworkWithKeysUpdate() {
2068        WifiConfiguration network = WifiConfigurationTestUtil.createEapNetwork();
2069        network.enterpriseConfig =
2070                WifiConfigurationTestUtil.createPEAPWifiEnterpriseConfigWithGTCPhase2();
2071        verifyAddNetworkToWifiConfigManager(network);
2072
2073        // Now verify that network configurations match before we make any change.
2074        WifiConfigurationTestUtil.assertConfigurationEqualForConfigManagerAddOrUpdate(
2075                network,
2076                mWifiConfigManager.getConfiguredNetworkWithPassword(network.networkId));
2077
2078        // Modify the network ca_cert field in updateNetworkKeys method during a network
2079        // config update.
2080        final String newCaCertAlias = "test";
2081        assertNotEquals(newCaCertAlias, network.enterpriseConfig.getCaCertificateAlias());
2082
2083        doAnswer(new AnswerWithArguments() {
2084            public boolean answer(WifiConfiguration newConfig, WifiConfiguration existingConfig) {
2085                newConfig.enterpriseConfig.setCaCertificateAlias(newCaCertAlias);
2086                return true;
2087            }
2088        }).when(mWifiKeyStore).updateNetworkKeys(
2089                any(WifiConfiguration.class), any(WifiConfiguration.class));
2090
2091        verifyUpdateNetworkToWifiConfigManagerWithoutIpChange(network);
2092
2093        // Now verify that the keys update is reflected in the configuration fetched from internal
2094        // db.
2095        network.enterpriseConfig.setCaCertificateAlias(newCaCertAlias);
2096        WifiConfigurationTestUtil.assertConfigurationEqualForConfigManagerAddOrUpdate(
2097                network,
2098                mWifiConfigManager.getConfiguredNetworkWithPassword(network.networkId));
2099    }
2100
2101    /**
2102     * Verifies that the dump method prints out all the saved network details with passwords masked.
2103     * {@link WifiConfigManager#dump(FileDescriptor, PrintWriter, String[])}.
2104     */
2105    @Test
2106    public void testDump() {
2107        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
2108        WifiConfiguration eapNetwork = WifiConfigurationTestUtil.createEapNetwork();
2109        eapNetwork.enterpriseConfig.setPassword("blah");
2110
2111        verifyAddNetworkToWifiConfigManager(pskNetwork);
2112        verifyAddNetworkToWifiConfigManager(eapNetwork);
2113
2114        StringWriter stringWriter = new StringWriter();
2115        mWifiConfigManager.dump(
2116                new FileDescriptor(), new PrintWriter(stringWriter), new String[0]);
2117        String dumpString = stringWriter.toString();
2118
2119        // Ensure that the network SSIDs were dumped out.
2120        assertTrue(dumpString.contains(pskNetwork.SSID));
2121        assertTrue(dumpString.contains(eapNetwork.SSID));
2122
2123        // Ensure that the network passwords were not dumped out.
2124        assertFalse(dumpString.contains(pskNetwork.preSharedKey));
2125        assertFalse(dumpString.contains(eapNetwork.enterpriseConfig.getPassword()));
2126    }
2127
2128    /**
2129     * Verifies the ordering of network list generated using
2130     * {@link WifiConfigManager#retrieveHiddenNetworkList()}.
2131     */
2132    @Test
2133    public void testRetrieveHiddenList() {
2134        // Create and add 3 networks.
2135        WifiConfiguration network1 = WifiConfigurationTestUtil.createWepHiddenNetwork();
2136        WifiConfiguration network2 = WifiConfigurationTestUtil.createPskHiddenNetwork();
2137        WifiConfiguration network3 = WifiConfigurationTestUtil.createOpenHiddenNetwork();
2138        verifyAddNetworkToWifiConfigManager(network1);
2139        verifyAddNetworkToWifiConfigManager(network2);
2140        verifyAddNetworkToWifiConfigManager(network3);
2141
2142        // Enable all of them.
2143        assertTrue(mWifiConfigManager.enableNetwork(network1.networkId, false, TEST_CREATOR_UID));
2144        assertTrue(mWifiConfigManager.enableNetwork(network2.networkId, false, TEST_CREATOR_UID));
2145        assertTrue(mWifiConfigManager.enableNetwork(network3.networkId, false, TEST_CREATOR_UID));
2146
2147        // Now set scan results in 2 of them to set the corresponding
2148        // {@link NetworkSelectionStatus#mSeenInLastQualifiedNetworkSelection} field.
2149        assertTrue(mWifiConfigManager.setNetworkCandidateScanResult(
2150                network1.networkId, createScanDetailForNetwork(network1).getScanResult(), 54));
2151        assertTrue(mWifiConfigManager.setNetworkCandidateScanResult(
2152                network3.networkId, createScanDetailForNetwork(network3).getScanResult(), 54));
2153
2154        // Now increment |network3|'s association count. This should ensure that this network
2155        // is preferred over |network1|.
2156        assertTrue(mWifiConfigManager.updateNetworkAfterConnect(network3.networkId));
2157
2158        // Retrieve the hidden network list & verify the order of the networks returned.
2159        List<WifiScanner.ScanSettings.HiddenNetwork> hiddenNetworks =
2160                mWifiConfigManager.retrieveHiddenNetworkList();
2161        assertEquals(3, hiddenNetworks.size());
2162        assertEquals(network3.SSID, hiddenNetworks.get(0).ssid);
2163        assertEquals(network1.SSID, hiddenNetworks.get(1).ssid);
2164        assertEquals(network2.SSID, hiddenNetworks.get(2).ssid);
2165
2166        // Now permanently disable |network3|. This should remove network 3 from the list.
2167        assertTrue(mWifiConfigManager.disableNetwork(network3.networkId, TEST_CREATOR_UID));
2168
2169        // Retrieve the hidden network list again & verify the order of the networks returned.
2170        hiddenNetworks = mWifiConfigManager.retrieveHiddenNetworkList();
2171        assertEquals(2, hiddenNetworks.size());
2172        assertEquals(network1.SSID, hiddenNetworks.get(0).ssid);
2173        assertEquals(network2.SSID, hiddenNetworks.get(1).ssid);
2174    }
2175
2176    /**
2177     * Verifies the addition of network configurations using
2178     * {@link WifiConfigManager#addOrUpdateNetwork(WifiConfiguration, int)} with same SSID and
2179     * default key mgmt does not add duplicate network configs.
2180     */
2181    @Test
2182    public void testAddMultipleNetworksWithSameSSIDAndDefaultKeyMgmt() {
2183        final String ssid = "test_blah";
2184        // Add a network with the above SSID and default key mgmt and ensure it was added
2185        // successfully.
2186        WifiConfiguration network1 = new WifiConfiguration();
2187        network1.SSID = ssid;
2188        NetworkUpdateResult result = addNetworkToWifiConfigManager(network1);
2189        assertTrue(result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID);
2190        assertTrue(result.isNewNetwork());
2191
2192        List<WifiConfiguration> retrievedNetworks =
2193                mWifiConfigManager.getConfiguredNetworksWithPasswords();
2194        assertEquals(1, retrievedNetworks.size());
2195        WifiConfigurationTestUtil.assertConfigurationEqualForConfigManagerAddOrUpdate(
2196                network1, retrievedNetworks.get(0));
2197
2198        // Now add a second network with the same SSID and default key mgmt and ensure that it
2199        // didn't add a new duplicate network.
2200        WifiConfiguration network2 = new WifiConfiguration();
2201        network2.SSID = ssid;
2202        result = addNetworkToWifiConfigManager(network2);
2203        assertTrue(result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID);
2204        assertFalse(result.isNewNetwork());
2205
2206        retrievedNetworks = mWifiConfigManager.getConfiguredNetworksWithPasswords();
2207        assertEquals(1, retrievedNetworks.size());
2208        WifiConfigurationTestUtil.assertConfigurationEqualForConfigManagerAddOrUpdate(
2209                network2, retrievedNetworks.get(0));
2210    }
2211
2212    /**
2213     * Verifies the addition of network configurations using
2214     * {@link WifiConfigManager#addOrUpdateNetwork(WifiConfiguration, int)} with same SSID and
2215     * different key mgmt should add different network configs.
2216     */
2217    @Test
2218    public void testAddMultipleNetworksWithSameSSIDAndDifferentKeyMgmt() {
2219        final String ssid = "test_blah";
2220        // Add a network with the above SSID and WPA_PSK key mgmt and ensure it was added
2221        // successfully.
2222        WifiConfiguration network1 = new WifiConfiguration();
2223        network1.SSID = ssid;
2224        network1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
2225        NetworkUpdateResult result = addNetworkToWifiConfigManager(network1);
2226        assertTrue(result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID);
2227        assertTrue(result.isNewNetwork());
2228
2229        List<WifiConfiguration> retrievedNetworks =
2230                mWifiConfigManager.getConfiguredNetworksWithPasswords();
2231        assertEquals(1, retrievedNetworks.size());
2232        WifiConfigurationTestUtil.assertConfigurationEqualForConfigManagerAddOrUpdate(
2233                network1, retrievedNetworks.get(0));
2234
2235        // Now add a second network with the same SSID and NONE key mgmt and ensure that it
2236        // does add a new network.
2237        WifiConfiguration network2 = new WifiConfiguration();
2238        network2.SSID = ssid;
2239        network2.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
2240        result = addNetworkToWifiConfigManager(network2);
2241        assertTrue(result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID);
2242        assertTrue(result.isNewNetwork());
2243
2244        retrievedNetworks = mWifiConfigManager.getConfiguredNetworksWithPasswords();
2245        assertEquals(2, retrievedNetworks.size());
2246        List<WifiConfiguration> networks = Arrays.asList(network1, network2);
2247        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
2248                networks, retrievedNetworks);
2249    }
2250
2251    private void createWifiConfigManager() {
2252        mWifiConfigManager =
2253                new WifiConfigManager(
2254                        mContext, mFrameworkFacade, mClock, mUserManager, mTelephonyManager,
2255                        mWifiKeyStore, mWifiConfigStore, mWifiConfigStoreLegacy);
2256        mWifiConfigManager.enableVerboseLogging(1);
2257    }
2258
2259    /**
2260     * This method sets defaults in the provided WifiConfiguration object if not set
2261     * so that it can be used for comparison with the configuration retrieved from
2262     * WifiConfigManager.
2263     */
2264    private void setDefaults(WifiConfiguration configuration) {
2265        if (configuration.allowedAuthAlgorithms.isEmpty()) {
2266            configuration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
2267        }
2268        if (configuration.allowedProtocols.isEmpty()) {
2269            configuration.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
2270            configuration.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
2271        }
2272        if (configuration.allowedKeyManagement.isEmpty()) {
2273            configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
2274            configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
2275        }
2276        if (configuration.allowedPairwiseCiphers.isEmpty()) {
2277            configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
2278            configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
2279        }
2280        if (configuration.allowedGroupCiphers.isEmpty()) {
2281            configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
2282            configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
2283            configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
2284            configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
2285        }
2286        if (configuration.getIpAssignment() == IpConfiguration.IpAssignment.UNASSIGNED) {
2287            configuration.setIpAssignment(IpConfiguration.IpAssignment.DHCP);
2288        }
2289        if (configuration.getProxySettings() == IpConfiguration.ProxySettings.UNASSIGNED) {
2290            configuration.setProxySettings(IpConfiguration.ProxySettings.NONE);
2291        }
2292        configuration.status = WifiConfiguration.Status.DISABLED;
2293        configuration.getNetworkSelectionStatus().setNetworkSelectionStatus(
2294                NetworkSelectionStatus.NETWORK_SELECTION_PERMANENTLY_DISABLED);
2295    }
2296
2297    /**
2298     * Modifies the provided configuration with creator uid, package name
2299     * and time.
2300     */
2301    private void setCreationDebugParams(WifiConfiguration configuration) {
2302        configuration.creatorUid = configuration.lastUpdateUid = TEST_CREATOR_UID;
2303        configuration.creatorName = configuration.lastUpdateName = TEST_CREATOR_NAME;
2304        configuration.creationTime = configuration.updateTime =
2305                WifiConfigManager.createDebugTimeStampString(
2306                        TEST_WALLCLOCK_CREATION_TIME_MILLIS);
2307    }
2308
2309    /**
2310     * Modifies the provided configuration with update uid, package name
2311     * and time.
2312     */
2313    private void setUpdateDebugParams(WifiConfiguration configuration) {
2314        configuration.lastUpdateUid = TEST_UPDATE_UID;
2315        configuration.lastUpdateName = TEST_UPDATE_NAME;
2316        configuration.updateTime =
2317                WifiConfigManager.createDebugTimeStampString(TEST_WALLCLOCK_UPDATE_TIME_MILLIS);
2318    }
2319
2320    private void assertNotEquals(Object expected, Object actual) {
2321        if (actual != null) {
2322            assertFalse(actual.equals(expected));
2323        } else {
2324            assertNotNull(expected);
2325        }
2326    }
2327
2328    /**
2329     * Modifies the provided WifiConfiguration with the specified bssid value. Also, asserts that
2330     * the existing |BSSID| field is not the same value as the one being set
2331     */
2332    private void assertAndSetNetworkBSSID(WifiConfiguration configuration, String bssid) {
2333        assertNotEquals(bssid, configuration.BSSID);
2334        configuration.BSSID = bssid;
2335    }
2336
2337    /**
2338     * Modifies the provided WifiConfiguration with the specified |IpConfiguration| object. Also,
2339     * asserts that the existing |mIpConfiguration| field is not the same value as the one being set
2340     */
2341    private void assertAndSetNetworkIpConfiguration(
2342            WifiConfiguration configuration, IpConfiguration ipConfiguration) {
2343        assertNotEquals(ipConfiguration, configuration.getIpConfiguration());
2344        configuration.setIpConfiguration(ipConfiguration);
2345    }
2346
2347    /**
2348     * Modifies the provided WifiConfiguration with the specified |wepKeys| value and
2349     * |wepTxKeyIndex|.
2350     */
2351    private void assertAndSetNetworkWepKeysAndTxIndex(
2352            WifiConfiguration configuration, String[] wepKeys, int wepTxKeyIdx) {
2353        assertNotEquals(wepKeys, configuration.wepKeys);
2354        assertNotEquals(wepTxKeyIdx, configuration.wepTxKeyIndex);
2355        configuration.wepKeys = Arrays.copyOf(wepKeys, wepKeys.length);
2356        configuration.wepTxKeyIndex = wepTxKeyIdx;
2357    }
2358
2359    /**
2360     * Modifies the provided WifiConfiguration with the specified |preSharedKey| value.
2361     */
2362    private void assertAndSetNetworkPreSharedKey(
2363            WifiConfiguration configuration, String preSharedKey) {
2364        assertNotEquals(preSharedKey, configuration.preSharedKey);
2365        configuration.preSharedKey = preSharedKey;
2366    }
2367
2368    /**
2369     * Modifies the provided WifiConfiguration with the specified enteprise |password| value.
2370     */
2371    private void assertAndSetNetworkEnterprisePassword(
2372            WifiConfiguration configuration, String password) {
2373        assertNotEquals(password, configuration.enterpriseConfig.getPassword());
2374        configuration.enterpriseConfig.setPassword(password);
2375    }
2376
2377    /**
2378     * Helper method to capture the store data written in WifiConfigStore.write() method.
2379     */
2380    private WifiConfigStoreData captureWriteStoreData() {
2381        try {
2382            ArgumentCaptor<WifiConfigStoreData> storeDataCaptor =
2383                    ArgumentCaptor.forClass(WifiConfigStoreData.class);
2384            mContextConfigStoreMockOrder.verify(mWifiConfigStore)
2385                    .write(anyBoolean(), storeDataCaptor.capture());
2386            return storeDataCaptor.getValue();
2387        } catch (Exception e) {
2388            fail("Exception encountered during write " + e);
2389        }
2390        return null;
2391    }
2392
2393    /**
2394     * Returns whether the provided network was in the store data or not.
2395     */
2396    private boolean isNetworkInConfigStoreData(WifiConfiguration configuration) {
2397        WifiConfigStoreData storeData = captureWriteStoreData();
2398        if (storeData == null) {
2399            return false;
2400        }
2401        return isNetworkInConfigStoreData(configuration, storeData);
2402    }
2403
2404    /**
2405     * Returns whether the provided network was in the store data or not.
2406     */
2407    private boolean isNetworkInConfigStoreData(
2408            WifiConfiguration configuration, WifiConfigStoreData storeData) {
2409        boolean foundNetworkInStoreData = false;
2410        for (WifiConfiguration retrievedConfig : storeData.getConfigurations()) {
2411            if (retrievedConfig.configKey().equals(configuration.configKey())) {
2412                foundNetworkInStoreData = true;
2413                break;
2414            }
2415        }
2416        return foundNetworkInStoreData;
2417    }
2418
2419    /**
2420     * Verifies that the provided network was not present in the last config store write.
2421     */
2422    private void verifyNetworkNotInConfigStoreData(WifiConfiguration configuration) {
2423        assertFalse(isNetworkInConfigStoreData(configuration));
2424    }
2425
2426    /**
2427     * Verifies that the provided network was present in the last config store write.
2428     */
2429    private void verifyNetworkInConfigStoreData(WifiConfiguration configuration) {
2430        assertTrue(isNetworkInConfigStoreData(configuration));
2431    }
2432
2433    private void assertPasswordsMaskedInWifiConfiguration(WifiConfiguration configuration) {
2434        if (!TextUtils.isEmpty(configuration.preSharedKey)) {
2435            assertEquals(WifiConfigManager.PASSWORD_MASK, configuration.preSharedKey);
2436        }
2437        if (configuration.wepKeys != null) {
2438            for (int i = 0; i < configuration.wepKeys.length; i++) {
2439                if (!TextUtils.isEmpty(configuration.wepKeys[i])) {
2440                    assertEquals(WifiConfigManager.PASSWORD_MASK, configuration.wepKeys[i]);
2441                }
2442            }
2443        }
2444        if (!TextUtils.isEmpty(configuration.enterpriseConfig.getPassword())) {
2445            assertEquals(
2446                    WifiConfigManager.PASSWORD_MASK,
2447                    configuration.enterpriseConfig.getPassword());
2448        }
2449    }
2450
2451    /**
2452     * Verifies that the network was present in the network change broadcast and returns the
2453     * change reason.
2454     */
2455    private int verifyNetworkInBroadcastAndReturnReason(WifiConfiguration configuration) {
2456        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
2457        ArgumentCaptor<UserHandle> userHandleCaptor = ArgumentCaptor.forClass(UserHandle.class);
2458        mContextConfigStoreMockOrder.verify(mContext)
2459                .sendBroadcastAsUser(intentCaptor.capture(), userHandleCaptor.capture());
2460
2461        assertEquals(userHandleCaptor.getValue(), UserHandle.ALL);
2462        Intent intent = intentCaptor.getValue();
2463
2464        int changeReason = intent.getIntExtra(WifiManager.EXTRA_CHANGE_REASON, -1);
2465        WifiConfiguration retrievedConfig =
2466                (WifiConfiguration) intent.getExtra(WifiManager.EXTRA_WIFI_CONFIGURATION);
2467        assertEquals(retrievedConfig.configKey(), configuration.configKey());
2468
2469        // Verify that all the passwords are masked in the broadcast configuration.
2470        assertPasswordsMaskedInWifiConfiguration(retrievedConfig);
2471
2472        return changeReason;
2473    }
2474
2475    /**
2476     * Verifies that we sent out an add broadcast with the provided network.
2477     */
2478    private void verifyNetworkAddBroadcast(WifiConfiguration configuration) {
2479        assertEquals(
2480                verifyNetworkInBroadcastAndReturnReason(configuration),
2481                WifiManager.CHANGE_REASON_ADDED);
2482    }
2483
2484    /**
2485     * Verifies that we sent out an update broadcast with the provided network.
2486     */
2487    private void verifyNetworkUpdateBroadcast(WifiConfiguration configuration) {
2488        assertEquals(
2489                verifyNetworkInBroadcastAndReturnReason(configuration),
2490                WifiManager.CHANGE_REASON_CONFIG_CHANGE);
2491    }
2492
2493    /**
2494     * Verifies that we sent out a remove broadcast with the provided network.
2495     */
2496    private void verifyNetworkRemoveBroadcast(WifiConfiguration configuration) {
2497        assertEquals(
2498                verifyNetworkInBroadcastAndReturnReason(configuration),
2499                WifiManager.CHANGE_REASON_REMOVED);
2500    }
2501
2502    /**
2503     * Adds the provided configuration to WifiConfigManager and modifies the provided configuration
2504     * with creator/update uid, package name and time. This also sets defaults for fields not
2505     * populated.
2506     * These fields are populated internally by WifiConfigManager and hence we need
2507     * to modify the configuration before we compare the added network with the retrieved network.
2508     */
2509    private NetworkUpdateResult addNetworkToWifiConfigManager(WifiConfiguration configuration) {
2510        when(mClock.getWallClockMillis()).thenReturn(TEST_WALLCLOCK_CREATION_TIME_MILLIS);
2511        NetworkUpdateResult result =
2512                mWifiConfigManager.addOrUpdateNetwork(configuration, TEST_CREATOR_UID);
2513        setDefaults(configuration);
2514        setCreationDebugParams(configuration);
2515        configuration.networkId = result.getNetworkId();
2516        return result;
2517    }
2518
2519    /**
2520     * Add network to WifiConfigManager and ensure that it was successful.
2521     */
2522    private NetworkUpdateResult verifyAddNetworkToWifiConfigManager(
2523            WifiConfiguration configuration) {
2524        NetworkUpdateResult result = addNetworkToWifiConfigManager(configuration);
2525        assertTrue(result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID);
2526        assertTrue(result.isNewNetwork());
2527        assertTrue(result.hasIpChanged());
2528        assertTrue(result.hasProxyChanged());
2529
2530        verifyNetworkAddBroadcast(configuration);
2531        // Verify that the config store write was triggered with this new configuration.
2532        verifyNetworkInConfigStoreData(configuration);
2533        return result;
2534    }
2535
2536    /**
2537     * Add ephemeral network to WifiConfigManager and ensure that it was successful.
2538     */
2539    private NetworkUpdateResult verifyAddEphemeralNetworkToWifiConfigManager(
2540            WifiConfiguration configuration) throws Exception {
2541        NetworkUpdateResult result = addNetworkToWifiConfigManager(configuration);
2542        assertTrue(result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID);
2543        assertTrue(result.isNewNetwork());
2544        assertTrue(result.hasIpChanged());
2545        assertTrue(result.hasProxyChanged());
2546
2547        verifyNetworkAddBroadcast(configuration);
2548        // Ensure that the write was not invoked for ephemeral network addition.
2549        mContextConfigStoreMockOrder.verify(mWifiConfigStore, never())
2550                .write(anyBoolean(), any(WifiConfigStoreData.class));
2551        return result;
2552    }
2553
2554    /**
2555     * Updates the provided configuration to WifiConfigManager and modifies the provided
2556     * configuration with update uid, package name and time.
2557     * These fields are populated internally by WifiConfigManager and hence we need
2558     * to modify the configuration before we compare the added network with the retrieved network.
2559     */
2560    private NetworkUpdateResult updateNetworkToWifiConfigManager(WifiConfiguration configuration) {
2561        when(mClock.getWallClockMillis()).thenReturn(TEST_WALLCLOCK_UPDATE_TIME_MILLIS);
2562        NetworkUpdateResult result =
2563                mWifiConfigManager.addOrUpdateNetwork(configuration, TEST_UPDATE_UID);
2564        setUpdateDebugParams(configuration);
2565        return result;
2566    }
2567
2568    /**
2569     * Update network to WifiConfigManager config change and ensure that it was successful.
2570     */
2571    private NetworkUpdateResult verifyUpdateNetworkToWifiConfigManager(
2572            WifiConfiguration configuration) {
2573        NetworkUpdateResult result = updateNetworkToWifiConfigManager(configuration);
2574        assertTrue(result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID);
2575        assertFalse(result.isNewNetwork());
2576
2577        verifyNetworkUpdateBroadcast(configuration);
2578        // Verify that the config store write was triggered with this new configuration.
2579        verifyNetworkInConfigStoreData(configuration);
2580        return result;
2581    }
2582
2583    /**
2584     * Update network to WifiConfigManager without IP config change and ensure that it was
2585     * successful.
2586     */
2587    private NetworkUpdateResult verifyUpdateNetworkToWifiConfigManagerWithoutIpChange(
2588            WifiConfiguration configuration) {
2589        NetworkUpdateResult result = verifyUpdateNetworkToWifiConfigManager(configuration);
2590        assertFalse(result.hasIpChanged());
2591        assertFalse(result.hasProxyChanged());
2592        return result;
2593    }
2594
2595    /**
2596     * Update network to WifiConfigManager with IP config change and ensure that it was
2597     * successful.
2598     */
2599    private NetworkUpdateResult verifyUpdateNetworkToWifiConfigManagerWithIpChange(
2600            WifiConfiguration configuration) {
2601        NetworkUpdateResult result = verifyUpdateNetworkToWifiConfigManager(configuration);
2602        assertTrue(result.hasIpChanged());
2603        assertTrue(result.hasProxyChanged());
2604        return result;
2605    }
2606
2607    /**
2608     * Removes network from WifiConfigManager and ensure that it was successful.
2609     */
2610    private void verifyRemoveNetworkFromWifiConfigManager(
2611            WifiConfiguration configuration) {
2612        assertTrue(mWifiConfigManager.removeNetwork(configuration.networkId, TEST_CREATOR_UID));
2613
2614        verifyNetworkRemoveBroadcast(configuration);
2615        // Verify if the config store write was triggered without this new configuration.
2616        verifyNetworkNotInConfigStoreData(configuration);
2617    }
2618
2619    /**
2620     * Removes ephemeral network from WifiConfigManager and ensure that it was successful.
2621     */
2622    private void verifyRemoveEphemeralNetworkFromWifiConfigManager(
2623            WifiConfiguration configuration) throws  Exception {
2624        assertTrue(mWifiConfigManager.removeNetwork(configuration.networkId, TEST_CREATOR_UID));
2625
2626        verifyNetworkRemoveBroadcast(configuration);
2627        // Ensure that the write was not invoked for ephemeral network remove.
2628        mContextConfigStoreMockOrder.verify(mWifiConfigStore, never())
2629                .write(anyBoolean(), any(WifiConfigStoreData.class));
2630    }
2631
2632    /**
2633     * Verifies the provided network's public status and ensures that the network change broadcast
2634     * has been sent out.
2635     */
2636    private void verifyUpdateNetworkStatus(WifiConfiguration configuration, int status) {
2637        assertEquals(status, configuration.status);
2638        verifyNetworkUpdateBroadcast(configuration);
2639    }
2640
2641    /**
2642     * Verifies the network's selection status update.
2643     *
2644     * For temporarily disabled reasons, the method ensures that the status has changed only if
2645     * disable reason counter has exceeded the threshold.
2646     *
2647     * For permanently disabled/enabled reasons, the method ensures that the public status has
2648     * changed and the network change broadcast has been sent out.
2649     */
2650    private void verifyUpdateNetworkSelectionStatus(
2651            int networkId, int reason, int temporaryDisableReasonCounter) {
2652        when(mClock.getElapsedSinceBootMillis())
2653                .thenReturn(TEST_ELAPSED_UPDATE_NETWORK_SELECTION_TIME_MILLIS);
2654
2655        // Fetch the current status of the network before we try to update the status.
2656        WifiConfiguration retrievedNetwork = mWifiConfigManager.getConfiguredNetwork(networkId);
2657        NetworkSelectionStatus currentStatus = retrievedNetwork.getNetworkSelectionStatus();
2658        int currentDisableReason = currentStatus.getNetworkSelectionDisableReason();
2659
2660        // First set the status to the provided reason.
2661        assertTrue(mWifiConfigManager.updateNetworkSelectionStatus(networkId, reason));
2662
2663        // Now fetch the network configuration and verify the new status of the network.
2664        retrievedNetwork = mWifiConfigManager.getConfiguredNetwork(networkId);
2665
2666        NetworkSelectionStatus retrievedStatus = retrievedNetwork.getNetworkSelectionStatus();
2667        int retrievedDisableReason = retrievedStatus.getNetworkSelectionDisableReason();
2668        long retrievedDisableTime = retrievedStatus.getDisableTime();
2669        int retrievedDisableReasonCounter = retrievedStatus.getDisableReasonCounter(reason);
2670        int disableReasonThreshold =
2671                WifiConfigManager.NETWORK_SELECTION_DISABLE_THRESHOLD[reason];
2672
2673        if (reason == NetworkSelectionStatus.NETWORK_SELECTION_ENABLE) {
2674            assertEquals(reason, retrievedDisableReason);
2675            assertTrue(retrievedStatus.isNetworkEnabled());
2676            assertEquals(
2677                    NetworkSelectionStatus.INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP,
2678                    retrievedDisableTime);
2679            verifyUpdateNetworkStatus(retrievedNetwork, WifiConfiguration.Status.ENABLED);
2680        } else if (reason < NetworkSelectionStatus.DISABLED_TLS_VERSION_MISMATCH) {
2681            // For temporarily disabled networks, we need to ensure that the current status remains
2682            // until the threshold is crossed.
2683            assertEquals(temporaryDisableReasonCounter, retrievedDisableReasonCounter);
2684            if (retrievedDisableReasonCounter < disableReasonThreshold) {
2685                assertEquals(currentDisableReason, retrievedDisableReason);
2686                assertEquals(
2687                        currentStatus.getNetworkSelectionStatus(),
2688                        retrievedStatus.getNetworkSelectionStatus());
2689            } else {
2690                assertEquals(reason, retrievedDisableReason);
2691                assertTrue(retrievedStatus.isNetworkTemporaryDisabled());
2692                assertEquals(
2693                        TEST_ELAPSED_UPDATE_NETWORK_SELECTION_TIME_MILLIS, retrievedDisableTime);
2694            }
2695        } else if (reason < NetworkSelectionStatus.NETWORK_SELECTION_DISABLED_MAX) {
2696            assertEquals(reason, retrievedDisableReason);
2697            assertTrue(retrievedStatus.isNetworkPermanentlyDisabled());
2698            assertEquals(
2699                    NetworkSelectionStatus.INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP,
2700                    retrievedDisableTime);
2701            verifyUpdateNetworkStatus(retrievedNetwork, WifiConfiguration.Status.DISABLED);
2702        }
2703    }
2704
2705    /**
2706     * Creates a scan detail corresponding to the provided network and given BSSID, level &frequency
2707     * values.
2708     */
2709    private ScanDetail createScanDetailForNetwork(
2710            WifiConfiguration configuration, String bssid, int level, int frequency) {
2711        String caps;
2712        if (configuration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_PSK)) {
2713            caps = "[WPA2-PSK-CCMP]";
2714        } else if (configuration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_EAP)
2715                || configuration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.IEEE8021X)) {
2716            caps = "[WPA2-EAP-CCMP]";
2717        } else if (configuration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.NONE)
2718                && WifiConfigurationUtil.hasAnyValidWepKey(configuration.wepKeys)) {
2719            caps = "[WEP]";
2720        } else {
2721            caps = "[]";
2722        }
2723        WifiSsid ssid = WifiSsid.createFromAsciiEncoded(configuration.getPrintableSsid());
2724        // Fill in 0's in the fields we don't care about.
2725        return new ScanDetail(
2726                ssid, bssid, caps, level, frequency, mClock.getUptimeSinceBootMillis(),
2727                mClock.getWallClockMillis());
2728    }
2729
2730    /**
2731     * Creates a scan detail corresponding to the provided network and BSSID value.
2732     */
2733    private ScanDetail createScanDetailForNetwork(WifiConfiguration configuration, String bssid) {
2734        return createScanDetailForNetwork(configuration, bssid, 0, 0);
2735    }
2736
2737    /**
2738     * Creates a scan detail corresponding to the provided network and fixed BSSID value.
2739     */
2740    private ScanDetail createScanDetailForNetwork(WifiConfiguration configuration) {
2741        return createScanDetailForNetwork(configuration, TEST_BSSID);
2742    }
2743
2744    /**
2745     * Adds the provided network and then creates a scan detail corresponding to the network. The
2746     * method then creates a ScanDetail corresponding to the network and ensures that the network
2747     * is properly matched using
2748     * {@link WifiConfigManager#getSavedNetworkForScanDetailAndCache(ScanDetail)} and also
2749     * verifies that the provided scan detail was cached,
2750     */
2751    private void verifyAddSingleNetworkAndMatchScanDetailToNetworkAndCache(
2752            WifiConfiguration network) {
2753        // First add the provided network.
2754        verifyAddNetworkToWifiConfigManager(network);
2755
2756        // Now create a dummy scan detail corresponding to the network.
2757        ScanDetail scanDetail = createScanDetailForNetwork(network);
2758        ScanResult scanResult = scanDetail.getScanResult();
2759
2760        WifiConfiguration retrievedNetwork =
2761                mWifiConfigManager.getSavedNetworkForScanDetailAndCache(scanDetail);
2762        // Retrieve the network with password data for comparison.
2763        retrievedNetwork =
2764                mWifiConfigManager.getConfiguredNetworkWithPassword(retrievedNetwork.networkId);
2765
2766        WifiConfigurationTestUtil.assertConfigurationEqualForConfigManagerAddOrUpdate(
2767                network, retrievedNetwork);
2768
2769        // Now retrieve the scan detail cache and ensure that the new scan detail is in cache.
2770        ScanDetailCache retrievedScanDetailCache =
2771                mWifiConfigManager.getScanDetailCacheForNetwork(network.networkId);
2772        assertEquals(1, retrievedScanDetailCache.size());
2773        ScanResult retrievedScanResult = retrievedScanDetailCache.get(scanResult.BSSID);
2774
2775        ScanTestUtil.assertScanResultEquals(scanResult, retrievedScanResult);
2776    }
2777
2778    /**
2779     * Adds a new network and verifies that the |HasEverConnected| flag is set to false.
2780     */
2781    private void verifyAddNetworkHasEverConnectedFalse(WifiConfiguration network) {
2782        NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(network);
2783        WifiConfiguration retrievedNetwork =
2784                mWifiConfigManager.getConfiguredNetwork(result.getNetworkId());
2785        assertFalse("Adding a new network should not have hasEverConnected set to true.",
2786                retrievedNetwork.getNetworkSelectionStatus().getHasEverConnected());
2787    }
2788
2789    /**
2790     * Updates an existing network with some credential change and verifies that the
2791     * |HasEverConnected| flag is set to false.
2792     */
2793    private void verifyUpdateNetworkWithCredentialChangeHasEverConnectedFalse(
2794            WifiConfiguration network) {
2795        NetworkUpdateResult result = verifyUpdateNetworkToWifiConfigManagerWithoutIpChange(network);
2796        WifiConfiguration retrievedNetwork =
2797                mWifiConfigManager.getConfiguredNetwork(result.getNetworkId());
2798        assertFalse("Updating network credentials config should clear hasEverConnected.",
2799                retrievedNetwork.getNetworkSelectionStatus().getHasEverConnected());
2800    }
2801
2802    /**
2803     * Updates an existing network after connection using
2804     * {@link WifiConfigManager#updateNetworkAfterConnect(int)} and asserts that the
2805     * |HasEverConnected| flag is set to true.
2806     */
2807    private void verifyUpdateNetworkAfterConnectHasEverConnectedTrue(int networkId) {
2808        assertTrue(mWifiConfigManager.updateNetworkAfterConnect(networkId));
2809        WifiConfiguration retrievedNetwork = mWifiConfigManager.getConfiguredNetwork(networkId);
2810        assertTrue("hasEverConnected expected to be true after connection.",
2811                retrievedNetwork.getNetworkSelectionStatus().getHasEverConnected());
2812    }
2813
2814    /**
2815     * Sets up a user profiles for WifiConfigManager testing.
2816     *
2817     * @param userId Id of the user.
2818     */
2819    private void setupUserProfiles(int userId) {
2820        final UserInfo userInfo =
2821                new UserInfo(userId, Integer.toString(userId), UserInfo.FLAG_PRIMARY);
2822        List<UserInfo> userProfiles = Arrays.asList(userInfo);
2823        when(mUserManager.getProfiles(userId)).thenReturn(userProfiles);
2824        when(mUserManager.isUserUnlockingOrUnlocked(userId)).thenReturn(true);
2825    }
2826
2827}
2828