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