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