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