WifiConfigManagerTest.java revision b2c8d28046e96c4506482e030c6320cda6db8f30
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        verify(mWifiConfigStoreLegacy).removeStores();
1915
1916        List<WifiConfiguration> retrievedNetworks =
1917                mWifiConfigManager.getConfiguredNetworksWithPasswords();
1918        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
1919                networks, retrievedNetworks);
1920        assertTrue(mWifiConfigManager.wasEphemeralNetworkDeleted(deletedEphemeralSSID));
1921    }
1922
1923    /**
1924     * Verifies the loading of networks using {@link WifiConfigManager#loadFromStore()} does
1925     * not attempt to read from any of the stores (new or legacy) when the store files are
1926     * not present.
1927     */
1928    @Test
1929    public void testFreshInstallDoesNotLoadFromStore() throws Exception {
1930        // New store files not present, so migrate from the old store.
1931        when(mWifiConfigStore.areStoresPresent()).thenReturn(false);
1932        when(mWifiConfigStoreLegacy.areStoresPresent()).thenReturn(false);
1933
1934        // Now trigger a load from store. This should populate the in memory list with all the
1935        // networks above.
1936        mWifiConfigManager.loadFromStore();
1937
1938        verify(mWifiConfigStore, never()).read();
1939        verify(mWifiConfigStoreLegacy, never()).read();
1940
1941        assertTrue(mWifiConfigManager.getConfiguredNetworksWithPasswords().isEmpty());
1942    }
1943
1944    /**
1945     * Verifies that the last user selected network parameter is set when
1946     * {@link WifiConfigManager#enableNetwork(int, boolean, int)} with disableOthers flag is set
1947     * to true and cleared when either {@link WifiConfigManager#disableNetwork(int, int)} or
1948     * {@link WifiConfigManager#removeNetwork(int, int)} is invoked using the same network ID.
1949     */
1950    @Test
1951    public void testLastSelectedNetwork() throws Exception {
1952        WifiConfiguration openNetwork = WifiConfigurationTestUtil.createOpenNetwork();
1953        NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(openNetwork);
1954
1955        when(mClock.getElapsedSinceBootMillis()).thenReturn(67L);
1956        assertTrue(mWifiConfigManager.enableNetwork(
1957                result.getNetworkId(), true, TEST_CREATOR_UID));
1958        assertEquals(result.getNetworkId(), mWifiConfigManager.getLastSelectedNetwork());
1959        assertEquals(67, mWifiConfigManager.getLastSelectedTimeStamp());
1960
1961        // Now disable the network and ensure that the last selected flag is cleared.
1962        assertTrue(mWifiConfigManager.disableNetwork(result.getNetworkId(), TEST_CREATOR_UID));
1963        assertEquals(
1964                WifiConfiguration.INVALID_NETWORK_ID, mWifiConfigManager.getLastSelectedNetwork());
1965
1966        // Enable it again and remove the network to ensure that the last selected flag was cleared.
1967        assertTrue(mWifiConfigManager.enableNetwork(
1968                result.getNetworkId(), true, TEST_CREATOR_UID));
1969        assertEquals(result.getNetworkId(), mWifiConfigManager.getLastSelectedNetwork());
1970        assertEquals(openNetwork.configKey(), mWifiConfigManager.getLastSelectedNetworkConfigKey());
1971
1972        assertTrue(mWifiConfigManager.removeNetwork(result.getNetworkId(), TEST_CREATOR_UID));
1973        assertEquals(
1974                WifiConfiguration.INVALID_NETWORK_ID, mWifiConfigManager.getLastSelectedNetwork());
1975    }
1976
1977    /**
1978     * Verifies that all the networks for the provided app is removed when
1979     * {@link WifiConfigManager#removeNetworksForApp(ApplicationInfo)} is invoked.
1980     */
1981    @Test
1982    public void testRemoveNetworksForApp() throws Exception {
1983        verifyAddNetworkToWifiConfigManager(WifiConfigurationTestUtil.createOpenNetwork());
1984        verifyAddNetworkToWifiConfigManager(WifiConfigurationTestUtil.createPskNetwork());
1985        verifyAddNetworkToWifiConfigManager(WifiConfigurationTestUtil.createWepNetwork());
1986
1987        assertFalse(mWifiConfigManager.getConfiguredNetworks().isEmpty());
1988
1989        ApplicationInfo app = new ApplicationInfo();
1990        app.uid = TEST_CREATOR_UID;
1991        app.packageName = TEST_CREATOR_NAME;
1992        assertTrue(mWifiConfigManager.removeNetworksForApp(app));
1993
1994        // Ensure all the networks are removed now.
1995        assertTrue(mWifiConfigManager.getConfiguredNetworks().isEmpty());
1996    }
1997
1998    /**
1999     * Verifies that all the networks for the provided user is removed when
2000     * {@link WifiConfigManager#removeNetworksForUser(int)} is invoked.
2001     */
2002    @Test
2003    public void testRemoveNetworksForUser() throws Exception {
2004        verifyAddNetworkToWifiConfigManager(WifiConfigurationTestUtil.createOpenNetwork());
2005        verifyAddNetworkToWifiConfigManager(WifiConfigurationTestUtil.createPskNetwork());
2006        verifyAddNetworkToWifiConfigManager(WifiConfigurationTestUtil.createWepNetwork());
2007
2008        assertFalse(mWifiConfigManager.getConfiguredNetworks().isEmpty());
2009
2010        assertTrue(mWifiConfigManager.removeNetworksForUser(TEST_DEFAULT_USER));
2011
2012        // Ensure all the networks are removed now.
2013        assertTrue(mWifiConfigManager.getConfiguredNetworks().isEmpty());
2014    }
2015
2016    /**
2017     * Verifies that the connect choice is removed from all networks when
2018     * {@link WifiConfigManager#removeNetwork(int, int)} is invoked.
2019     */
2020    @Test
2021    public void testRemoveNetworkRemovesConnectChoice() throws Exception {
2022        WifiConfiguration network1 = WifiConfigurationTestUtil.createOpenNetwork();
2023        WifiConfiguration network2 = WifiConfigurationTestUtil.createPskNetwork();
2024        WifiConfiguration network3 = WifiConfigurationTestUtil.createPskNetwork();
2025        verifyAddNetworkToWifiConfigManager(network1);
2026        verifyAddNetworkToWifiConfigManager(network2);
2027        verifyAddNetworkToWifiConfigManager(network3);
2028
2029        // Set connect choice of network 2 over network 1.
2030        assertTrue(
2031                mWifiConfigManager.setNetworkConnectChoice(
2032                        network1.networkId, network2.configKey(), 78L));
2033
2034        WifiConfiguration retrievedNetwork =
2035                mWifiConfigManager.getConfiguredNetwork(network1.networkId);
2036        assertEquals(
2037                network2.configKey(),
2038                retrievedNetwork.getNetworkSelectionStatus().getConnectChoice());
2039
2040        // Remove network 3 and ensure that the connect choice on network 1 is not removed.
2041        assertTrue(mWifiConfigManager.removeNetwork(network3.networkId, TEST_CREATOR_UID));
2042        retrievedNetwork = mWifiConfigManager.getConfiguredNetwork(network1.networkId);
2043        assertEquals(
2044                network2.configKey(),
2045                retrievedNetwork.getNetworkSelectionStatus().getConnectChoice());
2046
2047        // Now remove network 2 and ensure that the connect choice on network 1 is removed..
2048        assertTrue(mWifiConfigManager.removeNetwork(network2.networkId, TEST_CREATOR_UID));
2049        retrievedNetwork = mWifiConfigManager.getConfiguredNetwork(network1.networkId);
2050        assertNotEquals(
2051                network2.configKey(),
2052                retrievedNetwork.getNetworkSelectionStatus().getConnectChoice());
2053
2054        // This should have triggered 2 buffered writes. 1 for setting the connect choice, 1 for
2055        // clearing it after network removal.
2056        mContextConfigStoreMockOrder.verify(mWifiConfigStore, times(2))
2057                .write(eq(false), any(WifiConfigStoreData.class));
2058    }
2059
2060    /**
2061     * Verifies that the modification of a single network using
2062     * {@link WifiConfigManager#addOrUpdateNetwork(WifiConfiguration, int)} and ensures that any
2063     * updates to the network config in
2064     * {@link WifiKeyStore#updateNetworkKeys(WifiConfiguration, WifiConfiguration)} is reflected
2065     * in the internal database.
2066     */
2067    @Test
2068    public void testUpdateSingleNetworkWithKeysUpdate() {
2069        WifiConfiguration network = WifiConfigurationTestUtil.createEapNetwork();
2070        network.enterpriseConfig =
2071                WifiConfigurationTestUtil.createPEAPWifiEnterpriseConfigWithGTCPhase2();
2072        verifyAddNetworkToWifiConfigManager(network);
2073
2074        // Now verify that network configurations match before we make any change.
2075        WifiConfigurationTestUtil.assertConfigurationEqualForConfigManagerAddOrUpdate(
2076                network,
2077                mWifiConfigManager.getConfiguredNetworkWithPassword(network.networkId));
2078
2079        // Modify the network ca_cert field in updateNetworkKeys method during a network
2080        // config update.
2081        final String newCaCertAlias = "test";
2082        assertNotEquals(newCaCertAlias, network.enterpriseConfig.getCaCertificateAlias());
2083
2084        doAnswer(new AnswerWithArguments() {
2085            public boolean answer(WifiConfiguration newConfig, WifiConfiguration existingConfig) {
2086                newConfig.enterpriseConfig.setCaCertificateAlias(newCaCertAlias);
2087                return true;
2088            }
2089        }).when(mWifiKeyStore).updateNetworkKeys(
2090                any(WifiConfiguration.class), any(WifiConfiguration.class));
2091
2092        verifyUpdateNetworkToWifiConfigManagerWithoutIpChange(network);
2093
2094        // Now verify that the keys update is reflected in the configuration fetched from internal
2095        // db.
2096        network.enterpriseConfig.setCaCertificateAlias(newCaCertAlias);
2097        WifiConfigurationTestUtil.assertConfigurationEqualForConfigManagerAddOrUpdate(
2098                network,
2099                mWifiConfigManager.getConfiguredNetworkWithPassword(network.networkId));
2100    }
2101
2102    /**
2103     * Verifies that the dump method prints out all the saved network details with passwords masked.
2104     * {@link WifiConfigManager#dump(FileDescriptor, PrintWriter, String[])}.
2105     */
2106    @Test
2107    public void testDump() {
2108        WifiConfiguration pskNetwork = WifiConfigurationTestUtil.createPskNetwork();
2109        WifiConfiguration eapNetwork = WifiConfigurationTestUtil.createEapNetwork();
2110        eapNetwork.enterpriseConfig.setPassword("blah");
2111
2112        verifyAddNetworkToWifiConfigManager(pskNetwork);
2113        verifyAddNetworkToWifiConfigManager(eapNetwork);
2114
2115        StringWriter stringWriter = new StringWriter();
2116        mWifiConfigManager.dump(
2117                new FileDescriptor(), new PrintWriter(stringWriter), new String[0]);
2118        String dumpString = stringWriter.toString();
2119
2120        // Ensure that the network SSIDs were dumped out.
2121        assertTrue(dumpString.contains(pskNetwork.SSID));
2122        assertTrue(dumpString.contains(eapNetwork.SSID));
2123
2124        // Ensure that the network passwords were not dumped out.
2125        assertFalse(dumpString.contains(pskNetwork.preSharedKey));
2126        assertFalse(dumpString.contains(eapNetwork.enterpriseConfig.getPassword()));
2127    }
2128
2129    /**
2130     * Verifies the ordering of network list generated using
2131     * {@link WifiConfigManager#retrieveHiddenNetworkList()}.
2132     */
2133    @Test
2134    public void testRetrieveHiddenList() {
2135        // Create and add 3 networks.
2136        WifiConfiguration network1 = WifiConfigurationTestUtil.createWepHiddenNetwork();
2137        WifiConfiguration network2 = WifiConfigurationTestUtil.createPskHiddenNetwork();
2138        WifiConfiguration network3 = WifiConfigurationTestUtil.createOpenHiddenNetwork();
2139        verifyAddNetworkToWifiConfigManager(network1);
2140        verifyAddNetworkToWifiConfigManager(network2);
2141        verifyAddNetworkToWifiConfigManager(network3);
2142
2143        // Enable all of them.
2144        assertTrue(mWifiConfigManager.enableNetwork(network1.networkId, false, TEST_CREATOR_UID));
2145        assertTrue(mWifiConfigManager.enableNetwork(network2.networkId, false, TEST_CREATOR_UID));
2146        assertTrue(mWifiConfigManager.enableNetwork(network3.networkId, false, TEST_CREATOR_UID));
2147
2148        // Now set scan results in 2 of them to set the corresponding
2149        // {@link NetworkSelectionStatus#mSeenInLastQualifiedNetworkSelection} field.
2150        assertTrue(mWifiConfigManager.setNetworkCandidateScanResult(
2151                network1.networkId, createScanDetailForNetwork(network1).getScanResult(), 54));
2152        assertTrue(mWifiConfigManager.setNetworkCandidateScanResult(
2153                network3.networkId, createScanDetailForNetwork(network3).getScanResult(), 54));
2154
2155        // Now increment |network3|'s association count. This should ensure that this network
2156        // is preferred over |network1|.
2157        assertTrue(mWifiConfigManager.updateNetworkAfterConnect(network3.networkId));
2158
2159        // Retrieve the hidden network list & verify the order of the networks returned.
2160        List<WifiScanner.ScanSettings.HiddenNetwork> hiddenNetworks =
2161                mWifiConfigManager.retrieveHiddenNetworkList();
2162        assertEquals(3, hiddenNetworks.size());
2163        assertEquals(network3.SSID, hiddenNetworks.get(0).ssid);
2164        assertEquals(network1.SSID, hiddenNetworks.get(1).ssid);
2165        assertEquals(network2.SSID, hiddenNetworks.get(2).ssid);
2166
2167        // Now permanently disable |network3|. This should remove network 3 from the list.
2168        assertTrue(mWifiConfigManager.disableNetwork(network3.networkId, TEST_CREATOR_UID));
2169
2170        // Retrieve the hidden network list again & verify the order of the networks returned.
2171        hiddenNetworks = mWifiConfigManager.retrieveHiddenNetworkList();
2172        assertEquals(2, hiddenNetworks.size());
2173        assertEquals(network1.SSID, hiddenNetworks.get(0).ssid);
2174        assertEquals(network2.SSID, hiddenNetworks.get(1).ssid);
2175    }
2176
2177    /**
2178     * Verifies the addition of network configurations using
2179     * {@link WifiConfigManager#addOrUpdateNetwork(WifiConfiguration, int)} with same SSID and
2180     * default key mgmt does not add duplicate network configs.
2181     */
2182    @Test
2183    public void testAddMultipleNetworksWithSameSSIDAndDefaultKeyMgmt() {
2184        final String ssid = "test_blah";
2185        // Add a network with the above SSID and default key mgmt and ensure it was added
2186        // successfully.
2187        WifiConfiguration network1 = new WifiConfiguration();
2188        network1.SSID = ssid;
2189        NetworkUpdateResult result = addNetworkToWifiConfigManager(network1);
2190        assertTrue(result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID);
2191        assertTrue(result.isNewNetwork());
2192
2193        List<WifiConfiguration> retrievedNetworks =
2194                mWifiConfigManager.getConfiguredNetworksWithPasswords();
2195        assertEquals(1, retrievedNetworks.size());
2196        WifiConfigurationTestUtil.assertConfigurationEqualForConfigManagerAddOrUpdate(
2197                network1, retrievedNetworks.get(0));
2198
2199        // Now add a second network with the same SSID and default key mgmt and ensure that it
2200        // didn't add a new duplicate network.
2201        WifiConfiguration network2 = new WifiConfiguration();
2202        network2.SSID = ssid;
2203        result = addNetworkToWifiConfigManager(network2);
2204        assertTrue(result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID);
2205        assertFalse(result.isNewNetwork());
2206
2207        retrievedNetworks = mWifiConfigManager.getConfiguredNetworksWithPasswords();
2208        assertEquals(1, retrievedNetworks.size());
2209        WifiConfigurationTestUtil.assertConfigurationEqualForConfigManagerAddOrUpdate(
2210                network2, retrievedNetworks.get(0));
2211    }
2212
2213    /**
2214     * Verifies the addition of network configurations using
2215     * {@link WifiConfigManager#addOrUpdateNetwork(WifiConfiguration, int)} with same SSID and
2216     * different key mgmt should add different network configs.
2217     */
2218    @Test
2219    public void testAddMultipleNetworksWithSameSSIDAndDifferentKeyMgmt() {
2220        final String ssid = "test_blah";
2221        // Add a network with the above SSID and WPA_PSK key mgmt and ensure it was added
2222        // successfully.
2223        WifiConfiguration network1 = new WifiConfiguration();
2224        network1.SSID = ssid;
2225        network1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
2226        NetworkUpdateResult result = addNetworkToWifiConfigManager(network1);
2227        assertTrue(result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID);
2228        assertTrue(result.isNewNetwork());
2229
2230        List<WifiConfiguration> retrievedNetworks =
2231                mWifiConfigManager.getConfiguredNetworksWithPasswords();
2232        assertEquals(1, retrievedNetworks.size());
2233        WifiConfigurationTestUtil.assertConfigurationEqualForConfigManagerAddOrUpdate(
2234                network1, retrievedNetworks.get(0));
2235
2236        // Now add a second network with the same SSID and NONE key mgmt and ensure that it
2237        // does add a new network.
2238        WifiConfiguration network2 = new WifiConfiguration();
2239        network2.SSID = ssid;
2240        network2.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
2241        result = addNetworkToWifiConfigManager(network2);
2242        assertTrue(result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID);
2243        assertTrue(result.isNewNetwork());
2244
2245        retrievedNetworks = mWifiConfigManager.getConfiguredNetworksWithPasswords();
2246        assertEquals(2, retrievedNetworks.size());
2247        List<WifiConfiguration> networks = Arrays.asList(network1, network2);
2248        WifiConfigurationTestUtil.assertConfigurationsEqualForConfigManagerAddOrUpdate(
2249                networks, retrievedNetworks);
2250    }
2251
2252    private void createWifiConfigManager() {
2253        mWifiConfigManager =
2254                new WifiConfigManager(
2255                        mContext, mFrameworkFacade, mClock, mUserManager, mTelephonyManager,
2256                        mWifiKeyStore, mWifiConfigStore, mWifiConfigStoreLegacy);
2257        mWifiConfigManager.enableVerboseLogging(1);
2258    }
2259
2260    /**
2261     * This method sets defaults in the provided WifiConfiguration object if not set
2262     * so that it can be used for comparison with the configuration retrieved from
2263     * WifiConfigManager.
2264     */
2265    private void setDefaults(WifiConfiguration configuration) {
2266        if (configuration.allowedAuthAlgorithms.isEmpty()) {
2267            configuration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
2268        }
2269        if (configuration.allowedProtocols.isEmpty()) {
2270            configuration.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
2271            configuration.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
2272        }
2273        if (configuration.allowedKeyManagement.isEmpty()) {
2274            configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
2275            configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
2276        }
2277        if (configuration.allowedPairwiseCiphers.isEmpty()) {
2278            configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
2279            configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
2280        }
2281        if (configuration.allowedGroupCiphers.isEmpty()) {
2282            configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
2283            configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
2284            configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
2285            configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
2286        }
2287        if (configuration.getIpAssignment() == IpConfiguration.IpAssignment.UNASSIGNED) {
2288            configuration.setIpAssignment(IpConfiguration.IpAssignment.DHCP);
2289        }
2290        if (configuration.getProxySettings() == IpConfiguration.ProxySettings.UNASSIGNED) {
2291            configuration.setProxySettings(IpConfiguration.ProxySettings.NONE);
2292        }
2293        configuration.status = WifiConfiguration.Status.DISABLED;
2294        configuration.getNetworkSelectionStatus().setNetworkSelectionStatus(
2295                NetworkSelectionStatus.NETWORK_SELECTION_PERMANENTLY_DISABLED);
2296    }
2297
2298    /**
2299     * Modifies the provided configuration with creator uid, package name
2300     * and time.
2301     */
2302    private void setCreationDebugParams(WifiConfiguration configuration) {
2303        configuration.creatorUid = configuration.lastUpdateUid = TEST_CREATOR_UID;
2304        configuration.creatorName = configuration.lastUpdateName = TEST_CREATOR_NAME;
2305        configuration.creationTime = configuration.updateTime =
2306                WifiConfigManager.createDebugTimeStampString(
2307                        TEST_WALLCLOCK_CREATION_TIME_MILLIS);
2308    }
2309
2310    /**
2311     * Modifies the provided configuration with update uid, package name
2312     * and time.
2313     */
2314    private void setUpdateDebugParams(WifiConfiguration configuration) {
2315        configuration.lastUpdateUid = TEST_UPDATE_UID;
2316        configuration.lastUpdateName = TEST_UPDATE_NAME;
2317        configuration.updateTime =
2318                WifiConfigManager.createDebugTimeStampString(TEST_WALLCLOCK_UPDATE_TIME_MILLIS);
2319    }
2320
2321    private void assertNotEquals(Object expected, Object actual) {
2322        if (actual != null) {
2323            assertFalse(actual.equals(expected));
2324        } else {
2325            assertNotNull(expected);
2326        }
2327    }
2328
2329    /**
2330     * Modifies the provided WifiConfiguration with the specified bssid value. Also, asserts that
2331     * the existing |BSSID| field is not the same value as the one being set
2332     */
2333    private void assertAndSetNetworkBSSID(WifiConfiguration configuration, String bssid) {
2334        assertNotEquals(bssid, configuration.BSSID);
2335        configuration.BSSID = bssid;
2336    }
2337
2338    /**
2339     * Modifies the provided WifiConfiguration with the specified |IpConfiguration| object. Also,
2340     * asserts that the existing |mIpConfiguration| field is not the same value as the one being set
2341     */
2342    private void assertAndSetNetworkIpConfiguration(
2343            WifiConfiguration configuration, IpConfiguration ipConfiguration) {
2344        assertNotEquals(ipConfiguration, configuration.getIpConfiguration());
2345        configuration.setIpConfiguration(ipConfiguration);
2346    }
2347
2348    /**
2349     * Modifies the provided WifiConfiguration with the specified |wepKeys| value and
2350     * |wepTxKeyIndex|.
2351     */
2352    private void assertAndSetNetworkWepKeysAndTxIndex(
2353            WifiConfiguration configuration, String[] wepKeys, int wepTxKeyIdx) {
2354        assertNotEquals(wepKeys, configuration.wepKeys);
2355        assertNotEquals(wepTxKeyIdx, configuration.wepTxKeyIndex);
2356        configuration.wepKeys = Arrays.copyOf(wepKeys, wepKeys.length);
2357        configuration.wepTxKeyIndex = wepTxKeyIdx;
2358    }
2359
2360    /**
2361     * Modifies the provided WifiConfiguration with the specified |preSharedKey| value.
2362     */
2363    private void assertAndSetNetworkPreSharedKey(
2364            WifiConfiguration configuration, String preSharedKey) {
2365        assertNotEquals(preSharedKey, configuration.preSharedKey);
2366        configuration.preSharedKey = preSharedKey;
2367    }
2368
2369    /**
2370     * Modifies the provided WifiConfiguration with the specified enteprise |password| value.
2371     */
2372    private void assertAndSetNetworkEnterprisePassword(
2373            WifiConfiguration configuration, String password) {
2374        assertNotEquals(password, configuration.enterpriseConfig.getPassword());
2375        configuration.enterpriseConfig.setPassword(password);
2376    }
2377
2378    /**
2379     * Helper method to capture the store data written in WifiConfigStore.write() method.
2380     */
2381    private WifiConfigStoreData captureWriteStoreData() {
2382        try {
2383            ArgumentCaptor<WifiConfigStoreData> storeDataCaptor =
2384                    ArgumentCaptor.forClass(WifiConfigStoreData.class);
2385            mContextConfigStoreMockOrder.verify(mWifiConfigStore)
2386                    .write(anyBoolean(), storeDataCaptor.capture());
2387            return storeDataCaptor.getValue();
2388        } catch (Exception e) {
2389            fail("Exception encountered during write " + e);
2390        }
2391        return null;
2392    }
2393
2394    /**
2395     * Returns whether the provided network was in the store data or not.
2396     */
2397    private boolean isNetworkInConfigStoreData(WifiConfiguration configuration) {
2398        WifiConfigStoreData storeData = captureWriteStoreData();
2399        if (storeData == null) {
2400            return false;
2401        }
2402        return isNetworkInConfigStoreData(configuration, storeData);
2403    }
2404
2405    /**
2406     * Returns whether the provided network was in the store data or not.
2407     */
2408    private boolean isNetworkInConfigStoreData(
2409            WifiConfiguration configuration, WifiConfigStoreData storeData) {
2410        boolean foundNetworkInStoreData = false;
2411        for (WifiConfiguration retrievedConfig : storeData.getConfigurations()) {
2412            if (retrievedConfig.configKey().equals(configuration.configKey())) {
2413                foundNetworkInStoreData = true;
2414                break;
2415            }
2416        }
2417        return foundNetworkInStoreData;
2418    }
2419
2420    /**
2421     * Verifies that the provided network was not present in the last config store write.
2422     */
2423    private void verifyNetworkNotInConfigStoreData(WifiConfiguration configuration) {
2424        assertFalse(isNetworkInConfigStoreData(configuration));
2425    }
2426
2427    /**
2428     * Verifies that the provided network was present in the last config store write.
2429     */
2430    private void verifyNetworkInConfigStoreData(WifiConfiguration configuration) {
2431        assertTrue(isNetworkInConfigStoreData(configuration));
2432    }
2433
2434    private void assertPasswordsMaskedInWifiConfiguration(WifiConfiguration configuration) {
2435        if (!TextUtils.isEmpty(configuration.preSharedKey)) {
2436            assertEquals(WifiConfigManager.PASSWORD_MASK, configuration.preSharedKey);
2437        }
2438        if (configuration.wepKeys != null) {
2439            for (int i = 0; i < configuration.wepKeys.length; i++) {
2440                if (!TextUtils.isEmpty(configuration.wepKeys[i])) {
2441                    assertEquals(WifiConfigManager.PASSWORD_MASK, configuration.wepKeys[i]);
2442                }
2443            }
2444        }
2445        if (!TextUtils.isEmpty(configuration.enterpriseConfig.getPassword())) {
2446            assertEquals(
2447                    WifiConfigManager.PASSWORD_MASK,
2448                    configuration.enterpriseConfig.getPassword());
2449        }
2450    }
2451
2452    /**
2453     * Verifies that the network was present in the network change broadcast and returns the
2454     * change reason.
2455     */
2456    private int verifyNetworkInBroadcastAndReturnReason(WifiConfiguration configuration) {
2457        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
2458        ArgumentCaptor<UserHandle> userHandleCaptor = ArgumentCaptor.forClass(UserHandle.class);
2459        mContextConfigStoreMockOrder.verify(mContext)
2460                .sendBroadcastAsUser(intentCaptor.capture(), userHandleCaptor.capture());
2461
2462        assertEquals(userHandleCaptor.getValue(), UserHandle.ALL);
2463        Intent intent = intentCaptor.getValue();
2464
2465        int changeReason = intent.getIntExtra(WifiManager.EXTRA_CHANGE_REASON, -1);
2466        WifiConfiguration retrievedConfig =
2467                (WifiConfiguration) intent.getExtra(WifiManager.EXTRA_WIFI_CONFIGURATION);
2468        assertEquals(retrievedConfig.configKey(), configuration.configKey());
2469
2470        // Verify that all the passwords are masked in the broadcast configuration.
2471        assertPasswordsMaskedInWifiConfiguration(retrievedConfig);
2472
2473        return changeReason;
2474    }
2475
2476    /**
2477     * Verifies that we sent out an add broadcast with the provided network.
2478     */
2479    private void verifyNetworkAddBroadcast(WifiConfiguration configuration) {
2480        assertEquals(
2481                verifyNetworkInBroadcastAndReturnReason(configuration),
2482                WifiManager.CHANGE_REASON_ADDED);
2483    }
2484
2485    /**
2486     * Verifies that we sent out an update broadcast with the provided network.
2487     */
2488    private void verifyNetworkUpdateBroadcast(WifiConfiguration configuration) {
2489        assertEquals(
2490                verifyNetworkInBroadcastAndReturnReason(configuration),
2491                WifiManager.CHANGE_REASON_CONFIG_CHANGE);
2492    }
2493
2494    /**
2495     * Verifies that we sent out a remove broadcast with the provided network.
2496     */
2497    private void verifyNetworkRemoveBroadcast(WifiConfiguration configuration) {
2498        assertEquals(
2499                verifyNetworkInBroadcastAndReturnReason(configuration),
2500                WifiManager.CHANGE_REASON_REMOVED);
2501    }
2502
2503    /**
2504     * Adds the provided configuration to WifiConfigManager and modifies the provided configuration
2505     * with creator/update uid, package name and time. This also sets defaults for fields not
2506     * populated.
2507     * These fields are populated internally by WifiConfigManager and hence we need
2508     * to modify the configuration before we compare the added network with the retrieved network.
2509     */
2510    private NetworkUpdateResult addNetworkToWifiConfigManager(WifiConfiguration configuration) {
2511        when(mClock.getWallClockMillis()).thenReturn(TEST_WALLCLOCK_CREATION_TIME_MILLIS);
2512        NetworkUpdateResult result =
2513                mWifiConfigManager.addOrUpdateNetwork(configuration, TEST_CREATOR_UID);
2514        setDefaults(configuration);
2515        setCreationDebugParams(configuration);
2516        configuration.networkId = result.getNetworkId();
2517        return result;
2518    }
2519
2520    /**
2521     * Add network to WifiConfigManager and ensure that it was successful.
2522     */
2523    private NetworkUpdateResult verifyAddNetworkToWifiConfigManager(
2524            WifiConfiguration configuration) {
2525        NetworkUpdateResult result = addNetworkToWifiConfigManager(configuration);
2526        assertTrue(result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID);
2527        assertTrue(result.isNewNetwork());
2528        assertTrue(result.hasIpChanged());
2529        assertTrue(result.hasProxyChanged());
2530
2531        verifyNetworkAddBroadcast(configuration);
2532        // Verify that the config store write was triggered with this new configuration.
2533        verifyNetworkInConfigStoreData(configuration);
2534        return result;
2535    }
2536
2537    /**
2538     * Add ephemeral network to WifiConfigManager and ensure that it was successful.
2539     */
2540    private NetworkUpdateResult verifyAddEphemeralNetworkToWifiConfigManager(
2541            WifiConfiguration configuration) throws Exception {
2542        NetworkUpdateResult result = addNetworkToWifiConfigManager(configuration);
2543        assertTrue(result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID);
2544        assertTrue(result.isNewNetwork());
2545        assertTrue(result.hasIpChanged());
2546        assertTrue(result.hasProxyChanged());
2547
2548        verifyNetworkAddBroadcast(configuration);
2549        // Ensure that the write was not invoked for ephemeral network addition.
2550        mContextConfigStoreMockOrder.verify(mWifiConfigStore, never())
2551                .write(anyBoolean(), any(WifiConfigStoreData.class));
2552        return result;
2553    }
2554
2555    /**
2556     * Updates the provided configuration to WifiConfigManager and modifies the provided
2557     * configuration with update uid, package name and time.
2558     * These fields are populated internally by WifiConfigManager and hence we need
2559     * to modify the configuration before we compare the added network with the retrieved network.
2560     */
2561    private NetworkUpdateResult updateNetworkToWifiConfigManager(WifiConfiguration configuration) {
2562        when(mClock.getWallClockMillis()).thenReturn(TEST_WALLCLOCK_UPDATE_TIME_MILLIS);
2563        NetworkUpdateResult result =
2564                mWifiConfigManager.addOrUpdateNetwork(configuration, TEST_UPDATE_UID);
2565        setUpdateDebugParams(configuration);
2566        return result;
2567    }
2568
2569    /**
2570     * Update network to WifiConfigManager config change and ensure that it was successful.
2571     */
2572    private NetworkUpdateResult verifyUpdateNetworkToWifiConfigManager(
2573            WifiConfiguration configuration) {
2574        NetworkUpdateResult result = updateNetworkToWifiConfigManager(configuration);
2575        assertTrue(result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID);
2576        assertFalse(result.isNewNetwork());
2577
2578        verifyNetworkUpdateBroadcast(configuration);
2579        // Verify that the config store write was triggered with this new configuration.
2580        verifyNetworkInConfigStoreData(configuration);
2581        return result;
2582    }
2583
2584    /**
2585     * Update network to WifiConfigManager without IP config change and ensure that it was
2586     * successful.
2587     */
2588    private NetworkUpdateResult verifyUpdateNetworkToWifiConfigManagerWithoutIpChange(
2589            WifiConfiguration configuration) {
2590        NetworkUpdateResult result = verifyUpdateNetworkToWifiConfigManager(configuration);
2591        assertFalse(result.hasIpChanged());
2592        assertFalse(result.hasProxyChanged());
2593        return result;
2594    }
2595
2596    /**
2597     * Update network to WifiConfigManager with IP config change and ensure that it was
2598     * successful.
2599     */
2600    private NetworkUpdateResult verifyUpdateNetworkToWifiConfigManagerWithIpChange(
2601            WifiConfiguration configuration) {
2602        NetworkUpdateResult result = verifyUpdateNetworkToWifiConfigManager(configuration);
2603        assertTrue(result.hasIpChanged());
2604        assertTrue(result.hasProxyChanged());
2605        return result;
2606    }
2607
2608    /**
2609     * Removes network from WifiConfigManager and ensure that it was successful.
2610     */
2611    private void verifyRemoveNetworkFromWifiConfigManager(
2612            WifiConfiguration configuration) {
2613        assertTrue(mWifiConfigManager.removeNetwork(configuration.networkId, TEST_CREATOR_UID));
2614
2615        verifyNetworkRemoveBroadcast(configuration);
2616        // Verify if the config store write was triggered without this new configuration.
2617        verifyNetworkNotInConfigStoreData(configuration);
2618    }
2619
2620    /**
2621     * Removes ephemeral network from WifiConfigManager and ensure that it was successful.
2622     */
2623    private void verifyRemoveEphemeralNetworkFromWifiConfigManager(
2624            WifiConfiguration configuration) throws  Exception {
2625        assertTrue(mWifiConfigManager.removeNetwork(configuration.networkId, TEST_CREATOR_UID));
2626
2627        verifyNetworkRemoveBroadcast(configuration);
2628        // Ensure that the write was not invoked for ephemeral network remove.
2629        mContextConfigStoreMockOrder.verify(mWifiConfigStore, never())
2630                .write(anyBoolean(), any(WifiConfigStoreData.class));
2631    }
2632
2633    /**
2634     * Verifies the provided network's public status and ensures that the network change broadcast
2635     * has been sent out.
2636     */
2637    private void verifyUpdateNetworkStatus(WifiConfiguration configuration, int status) {
2638        assertEquals(status, configuration.status);
2639        verifyNetworkUpdateBroadcast(configuration);
2640    }
2641
2642    /**
2643     * Verifies the network's selection status update.
2644     *
2645     * For temporarily disabled reasons, the method ensures that the status has changed only if
2646     * disable reason counter has exceeded the threshold.
2647     *
2648     * For permanently disabled/enabled reasons, the method ensures that the public status has
2649     * changed and the network change broadcast has been sent out.
2650     */
2651    private void verifyUpdateNetworkSelectionStatus(
2652            int networkId, int reason, int temporaryDisableReasonCounter) {
2653        when(mClock.getElapsedSinceBootMillis())
2654                .thenReturn(TEST_ELAPSED_UPDATE_NETWORK_SELECTION_TIME_MILLIS);
2655
2656        // Fetch the current status of the network before we try to update the status.
2657        WifiConfiguration retrievedNetwork = mWifiConfigManager.getConfiguredNetwork(networkId);
2658        NetworkSelectionStatus currentStatus = retrievedNetwork.getNetworkSelectionStatus();
2659        int currentDisableReason = currentStatus.getNetworkSelectionDisableReason();
2660
2661        // First set the status to the provided reason.
2662        assertTrue(mWifiConfigManager.updateNetworkSelectionStatus(networkId, reason));
2663
2664        // Now fetch the network configuration and verify the new status of the network.
2665        retrievedNetwork = mWifiConfigManager.getConfiguredNetwork(networkId);
2666
2667        NetworkSelectionStatus retrievedStatus = retrievedNetwork.getNetworkSelectionStatus();
2668        int retrievedDisableReason = retrievedStatus.getNetworkSelectionDisableReason();
2669        long retrievedDisableTime = retrievedStatus.getDisableTime();
2670        int retrievedDisableReasonCounter = retrievedStatus.getDisableReasonCounter(reason);
2671        int disableReasonThreshold =
2672                WifiConfigManager.NETWORK_SELECTION_DISABLE_THRESHOLD[reason];
2673
2674        if (reason == NetworkSelectionStatus.NETWORK_SELECTION_ENABLE) {
2675            assertEquals(reason, retrievedDisableReason);
2676            assertTrue(retrievedStatus.isNetworkEnabled());
2677            assertEquals(
2678                    NetworkSelectionStatus.INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP,
2679                    retrievedDisableTime);
2680            verifyUpdateNetworkStatus(retrievedNetwork, WifiConfiguration.Status.ENABLED);
2681        } else if (reason < NetworkSelectionStatus.DISABLED_TLS_VERSION_MISMATCH) {
2682            // For temporarily disabled networks, we need to ensure that the current status remains
2683            // until the threshold is crossed.
2684            assertEquals(temporaryDisableReasonCounter, retrievedDisableReasonCounter);
2685            if (retrievedDisableReasonCounter < disableReasonThreshold) {
2686                assertEquals(currentDisableReason, retrievedDisableReason);
2687                assertEquals(
2688                        currentStatus.getNetworkSelectionStatus(),
2689                        retrievedStatus.getNetworkSelectionStatus());
2690            } else {
2691                assertEquals(reason, retrievedDisableReason);
2692                assertTrue(retrievedStatus.isNetworkTemporaryDisabled());
2693                assertEquals(
2694                        TEST_ELAPSED_UPDATE_NETWORK_SELECTION_TIME_MILLIS, retrievedDisableTime);
2695            }
2696        } else if (reason < NetworkSelectionStatus.NETWORK_SELECTION_DISABLED_MAX) {
2697            assertEquals(reason, retrievedDisableReason);
2698            assertTrue(retrievedStatus.isNetworkPermanentlyDisabled());
2699            assertEquals(
2700                    NetworkSelectionStatus.INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP,
2701                    retrievedDisableTime);
2702            verifyUpdateNetworkStatus(retrievedNetwork, WifiConfiguration.Status.DISABLED);
2703        }
2704    }
2705
2706    /**
2707     * Creates a scan detail corresponding to the provided network and given BSSID, level &frequency
2708     * values.
2709     */
2710    private ScanDetail createScanDetailForNetwork(
2711            WifiConfiguration configuration, String bssid, int level, int frequency) {
2712        String caps;
2713        if (configuration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_PSK)) {
2714            caps = "[WPA2-PSK-CCMP]";
2715        } else if (configuration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_EAP)
2716                || configuration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.IEEE8021X)) {
2717            caps = "[WPA2-EAP-CCMP]";
2718        } else if (configuration.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.NONE)
2719                && WifiConfigurationUtil.hasAnyValidWepKey(configuration.wepKeys)) {
2720            caps = "[WEP]";
2721        } else {
2722            caps = "[]";
2723        }
2724        WifiSsid ssid = WifiSsid.createFromAsciiEncoded(configuration.getPrintableSsid());
2725        // Fill in 0's in the fields we don't care about.
2726        return new ScanDetail(
2727                ssid, bssid, caps, level, frequency, mClock.getUptimeSinceBootMillis(),
2728                mClock.getWallClockMillis());
2729    }
2730
2731    /**
2732     * Creates a scan detail corresponding to the provided network and BSSID value.
2733     */
2734    private ScanDetail createScanDetailForNetwork(WifiConfiguration configuration, String bssid) {
2735        return createScanDetailForNetwork(configuration, bssid, 0, 0);
2736    }
2737
2738    /**
2739     * Creates a scan detail corresponding to the provided network and fixed BSSID value.
2740     */
2741    private ScanDetail createScanDetailForNetwork(WifiConfiguration configuration) {
2742        return createScanDetailForNetwork(configuration, TEST_BSSID);
2743    }
2744
2745    /**
2746     * Adds the provided network and then creates a scan detail corresponding to the network. The
2747     * method then creates a ScanDetail corresponding to the network and ensures that the network
2748     * is properly matched using
2749     * {@link WifiConfigManager#getSavedNetworkForScanDetailAndCache(ScanDetail)} and also
2750     * verifies that the provided scan detail was cached,
2751     */
2752    private void verifyAddSingleNetworkAndMatchScanDetailToNetworkAndCache(
2753            WifiConfiguration network) {
2754        // First add the provided network.
2755        verifyAddNetworkToWifiConfigManager(network);
2756
2757        // Now create a dummy scan detail corresponding to the network.
2758        ScanDetail scanDetail = createScanDetailForNetwork(network);
2759        ScanResult scanResult = scanDetail.getScanResult();
2760
2761        WifiConfiguration retrievedNetwork =
2762                mWifiConfigManager.getSavedNetworkForScanDetailAndCache(scanDetail);
2763        // Retrieve the network with password data for comparison.
2764        retrievedNetwork =
2765                mWifiConfigManager.getConfiguredNetworkWithPassword(retrievedNetwork.networkId);
2766
2767        WifiConfigurationTestUtil.assertConfigurationEqualForConfigManagerAddOrUpdate(
2768                network, retrievedNetwork);
2769
2770        // Now retrieve the scan detail cache and ensure that the new scan detail is in cache.
2771        ScanDetailCache retrievedScanDetailCache =
2772                mWifiConfigManager.getScanDetailCacheForNetwork(network.networkId);
2773        assertEquals(1, retrievedScanDetailCache.size());
2774        ScanResult retrievedScanResult = retrievedScanDetailCache.get(scanResult.BSSID);
2775
2776        ScanTestUtil.assertScanResultEquals(scanResult, retrievedScanResult);
2777    }
2778
2779    /**
2780     * Adds a new network and verifies that the |HasEverConnected| flag is set to false.
2781     */
2782    private void verifyAddNetworkHasEverConnectedFalse(WifiConfiguration network) {
2783        NetworkUpdateResult result = verifyAddNetworkToWifiConfigManager(network);
2784        WifiConfiguration retrievedNetwork =
2785                mWifiConfigManager.getConfiguredNetwork(result.getNetworkId());
2786        assertFalse("Adding a new network should not have hasEverConnected set to true.",
2787                retrievedNetwork.getNetworkSelectionStatus().getHasEverConnected());
2788    }
2789
2790    /**
2791     * Updates an existing network with some credential change and verifies that the
2792     * |HasEverConnected| flag is set to false.
2793     */
2794    private void verifyUpdateNetworkWithCredentialChangeHasEverConnectedFalse(
2795            WifiConfiguration network) {
2796        NetworkUpdateResult result = verifyUpdateNetworkToWifiConfigManagerWithoutIpChange(network);
2797        WifiConfiguration retrievedNetwork =
2798                mWifiConfigManager.getConfiguredNetwork(result.getNetworkId());
2799        assertFalse("Updating network credentials config should clear hasEverConnected.",
2800                retrievedNetwork.getNetworkSelectionStatus().getHasEverConnected());
2801    }
2802
2803    /**
2804     * Updates an existing network after connection using
2805     * {@link WifiConfigManager#updateNetworkAfterConnect(int)} and asserts that the
2806     * |HasEverConnected| flag is set to true.
2807     */
2808    private void verifyUpdateNetworkAfterConnectHasEverConnectedTrue(int networkId) {
2809        assertTrue(mWifiConfigManager.updateNetworkAfterConnect(networkId));
2810        WifiConfiguration retrievedNetwork = mWifiConfigManager.getConfiguredNetwork(networkId);
2811        assertTrue("hasEverConnected expected to be true after connection.",
2812                retrievedNetwork.getNetworkSelectionStatus().getHasEverConnected());
2813    }
2814
2815    /**
2816     * Sets up a user profiles for WifiConfigManager testing.
2817     *
2818     * @param userId Id of the user.
2819     */
2820    private void setupUserProfiles(int userId) {
2821        final UserInfo userInfo =
2822                new UserInfo(userId, Integer.toString(userId), UserInfo.FLAG_PRIMARY);
2823        List<UserInfo> userProfiles = Arrays.asList(userInfo);
2824        when(mUserManager.getProfiles(userId)).thenReturn(userProfiles);
2825        when(mUserManager.isUserUnlockingOrUnlocked(userId)).thenReturn(true);
2826    }
2827
2828}
2829