184d962ec8f487f824214744498bba505a6db0c59Randy Pan/* 284d962ec8f487f824214744498bba505a6db0c59Randy Pan * Copyright (C) 2016 The Android Open Source Project 384d962ec8f487f824214744498bba505a6db0c59Randy Pan * 484d962ec8f487f824214744498bba505a6db0c59Randy Pan * Licensed under the Apache License, Version 2.0 (the "License"); 584d962ec8f487f824214744498bba505a6db0c59Randy Pan * you may not use this file except in compliance with the License. 684d962ec8f487f824214744498bba505a6db0c59Randy Pan * You may obtain a copy of the License at 784d962ec8f487f824214744498bba505a6db0c59Randy Pan * 884d962ec8f487f824214744498bba505a6db0c59Randy Pan * http://www.apache.org/licenses/LICENSE-2.0 984d962ec8f487f824214744498bba505a6db0c59Randy Pan * 1084d962ec8f487f824214744498bba505a6db0c59Randy Pan * Unless required by applicable law or agreed to in writing, software 1184d962ec8f487f824214744498bba505a6db0c59Randy Pan * distributed under the License is distributed on an "AS IS" BASIS, 1284d962ec8f487f824214744498bba505a6db0c59Randy Pan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1384d962ec8f487f824214744498bba505a6db0c59Randy Pan * See the License for the specific language governing permissions and 1484d962ec8f487f824214744498bba505a6db0c59Randy Pan * limitations under the License. 1584d962ec8f487f824214744498bba505a6db0c59Randy Pan */ 1684d962ec8f487f824214744498bba505a6db0c59Randy Pan 1784d962ec8f487f824214744498bba505a6db0c59Randy Panpackage com.android.server.wifi; 1884d962ec8f487f824214744498bba505a6db0c59Randy Pan 19095121ada1c9ea6034e86606395de20cddcad9baRoshan Piusimport static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.DISABLED_AUTHENTICATION_FAILURE; 20095121ada1c9ea6034e86606395de20cddcad9baRoshan Piusimport static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.DISABLED_NO_INTERNET_TEMPORARY; 21095121ada1c9ea6034e86606395de20cddcad9baRoshan Pius 2284d962ec8f487f824214744498bba505a6db0c59Randy Panimport static com.android.server.wifi.WifiConfigurationTestUtil.generateWifiConfig; 23cb26f07ae9c558f8c6136c951a7f633d0ccfe79fRandy Panimport static com.android.server.wifi.WifiStateMachine.WIFI_WORK_SOURCE; 2484d962ec8f487f824214744498bba505a6db0c59Randy Pan 25fb196453c07daad5e525520cecad84cec5d89fb7Roshan Piusimport static org.junit.Assert.*; 2684d962ec8f487f824214744498bba505a6db0c59Randy Panimport static org.mockito.Mockito.*; 2784d962ec8f487f824214744498bba505a6db0c59Randy Pan 28f4267b6840dbc7f430638c35c5448187b6e83846Christopher Wileyimport android.app.test.MockAnswerUtil.AnswerWithArguments; 29026cb51837e4cf3aea30b903320b992a3f5d0d7bChristopher Wileyimport android.app.test.TestAlarmManager; 3084d962ec8f487f824214744498bba505a6db0c59Randy Panimport android.content.Context; 31adf5ee14bfcdef705684b1c4f12d80fae8433170Peter Qiuimport android.content.pm.PackageManager; 3284d962ec8f487f824214744498bba505a6db0c59Randy Panimport android.content.res.Resources; 33d0258ee4816148ff4ab9ac6b854fc5c51ea53be3Amin Shaikhimport android.net.NetworkScoreManager; 3484d962ec8f487f824214744498bba505a6db0c59Randy Panimport android.net.wifi.ScanResult; 35fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Piusimport android.net.wifi.ScanResult.InformationElement; 3650abba06efa7834b5309df561375e4a2e2df630dRandy Panimport android.net.wifi.SupplicantState; 3784d962ec8f487f824214744498bba505a6db0c59Randy Panimport android.net.wifi.WifiConfiguration; 3884d962ec8f487f824214744498bba505a6db0c59Randy Panimport android.net.wifi.WifiInfo; 39c8701c8ad058ec7fa69a2e3c60495f27708bced5Sundeep Ghumanimport android.net.wifi.WifiNetworkScoreCache; 4084d962ec8f487f824214744498bba505a6db0c59Randy Panimport android.net.wifi.WifiScanner; 41fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Piusimport android.net.wifi.WifiScanner.PnoScanListener; 42fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Piusimport android.net.wifi.WifiScanner.PnoSettings; 43cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Panimport android.net.wifi.WifiScanner.ScanData; 4484d962ec8f487f824214744498bba505a6db0c59Randy Panimport android.net.wifi.WifiScanner.ScanListener; 4584d962ec8f487f824214744498bba505a6db0c59Randy Panimport android.net.wifi.WifiScanner.ScanSettings; 461d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Piusimport android.net.wifi.WifiSsid; 479686c96d8d0c0bc21ca069e244e2570c169724e1Lorenzo Colittiimport android.os.Process; 48ee0ab818341d44614ffe56ae73ecc08b974c2cbbRoshan Piusimport android.os.SystemClock; 49e78a18cf874b4d9bb5db2ef7804b8ac576e56489Mitchell Willsimport android.os.WorkSource; 50f4267b6840dbc7f430638c35c5448187b6e83846Christopher Wileyimport android.os.test.TestLooper; 517f2a1e30dd5d14320ffc7b185ac25fdb79fe52b0Etan Cohenimport android.support.test.filters.SmallTest; 5217c2a7b30e5680b11fc0073ce322ee7bc14ef2c5Randy Panimport android.util.LocalLog; 5384d962ec8f487f824214744498bba505a6db0c59Randy Pan 5484d962ec8f487f824214744498bba505a6db0c59Randy Panimport com.android.internal.R; 5584d962ec8f487f824214744498bba505a6db0c59Randy Pan 5684d962ec8f487f824214744498bba505a6db0c59Randy Panimport org.junit.After; 5784d962ec8f487f824214744498bba505a6db0c59Randy Panimport org.junit.Before; 5884d962ec8f487f824214744498bba505a6db0c59Randy Panimport org.junit.Test; 59cb26f07ae9c558f8c6136c951a7f633d0ccfe79fRandy Panimport org.mockito.ArgumentCaptor; 60a54399f6da655dfbe440333ca3682b9199060a27Randy Panimport org.mockito.Captor; 61b4de842310ca698d59ed5b9117d38362e2945947Rebecca Silbersteinimport org.mockito.Mock; 62b4de842310ca698d59ed5b9117d38362e2945947Rebecca Silbersteinimport org.mockito.MockitoAnnotations; 6384d962ec8f487f824214744498bba505a6db0c59Randy Pan 6417c2a7b30e5680b11fc0073ce322ee7bc14ef2c5Randy Panimport java.io.FileDescriptor; 6517c2a7b30e5680b11fc0073ce322ee7bc14ef2c5Randy Panimport java.io.PrintWriter; 6617c2a7b30e5680b11fc0073ce322ee7bc14ef2c5Randy Panimport java.io.StringWriter; 67fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Piusimport java.nio.charset.StandardCharsets; 68fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Piusimport java.util.ArrayList; 69fb196453c07daad5e525520cecad84cec5d89fb7Roshan Piusimport java.util.HashSet; 703f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chenimport java.util.List; 71652381b37461a4aa793327365e144bb4335cbd27Roshan Piusimport java.util.stream.Collectors; 7284d962ec8f487f824214744498bba505a6db0c59Randy Pan 7384d962ec8f487f824214744498bba505a6db0c59Randy Pan/** 7484d962ec8f487f824214744498bba505a6db0c59Randy Pan * Unit tests for {@link com.android.server.wifi.WifiConnectivityManager}. 7584d962ec8f487f824214744498bba505a6db0c59Randy Pan */ 7684d962ec8f487f824214744498bba505a6db0c59Randy Pan@SmallTest 7784d962ec8f487f824214744498bba505a6db0c59Randy Panpublic class WifiConnectivityManagerTest { 7884d962ec8f487f824214744498bba505a6db0c59Randy Pan /** 7984d962ec8f487f824214744498bba505a6db0c59Randy Pan * Called before each test 8084d962ec8f487f824214744498bba505a6db0c59Randy Pan */ 8184d962ec8f487f824214744498bba505a6db0c59Randy Pan @Before 8284d962ec8f487f824214744498bba505a6db0c59Randy Pan public void setUp() throws Exception { 83b4de842310ca698d59ed5b9117d38362e2945947Rebecca Silberstein MockitoAnnotations.initMocks(this); 8409abbe29be6e552a2531b0367bd6d29647d33767Glen Kuhne mResource = mockResource(); 85f4267b6840dbc7f430638c35c5448187b6e83846Christopher Wiley mAlarmManager = new TestAlarmManager(); 8609abbe29be6e552a2531b0367bd6d29647d33767Glen Kuhne mContext = mockContext(); 8717c2a7b30e5680b11fc0073ce322ee7bc14ef2c5Randy Pan mLocalLog = new LocalLog(512); 8809abbe29be6e552a2531b0367bd6d29647d33767Glen Kuhne mWifiStateMachine = mockWifiStateMachine(); 8909abbe29be6e552a2531b0367bd6d29647d33767Glen Kuhne mWifiConfigManager = mockWifiConfigManager(); 90fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius mWifiInfo = getWifiInfo(); 91cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan mScanData = mockScanData(); 9209abbe29be6e552a2531b0367bd6d29647d33767Glen Kuhne mWifiScanner = mockWifiScanner(); 93a54399f6da655dfbe440333ca3682b9199060a27Randy Pan mWifiConnectivityHelper = mockWifiConnectivityHelper(); 94220d198691d07506137b6af0bae810ed47ac4ed6Randy Pan mWifiNS = mockWifiNetworkSelector(); 9594eec4ff65e7e4c1c06c3e817655842b46c02b0aRoshan Pius mWifiConnectivityManager = createConnectivityManager(); 965d0addadb370bcbb8900414fb9597bd415e6fea0Randy Pan verify(mWifiConfigManager).setOnSavedNetworkUpdateListener(anyObject()); 9784d962ec8f487f824214744498bba505a6db0c59Randy Pan mWifiConnectivityManager.setWifiEnabled(true); 985de29ec72c54cb73fdc1b59072f66a2627b8764cNingyuan Wang when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime()); 99e4606e0f9532d250a1e06e8aba5fb48556225773Randy Pan mFullScanMaxTxPacketRate = mResource.getInteger( 100e4606e0f9532d250a1e06e8aba5fb48556225773Randy Pan R.integer.config_wifi_framework_max_tx_rate_for_full_scan); 101e4606e0f9532d250a1e06e8aba5fb48556225773Randy Pan mFullScanMaxRxPacketRate = mResource.getInteger( 102e4606e0f9532d250a1e06e8aba5fb48556225773Randy Pan R.integer.config_wifi_framework_max_rx_rate_for_full_scan); 10384f6d8d25d5982b703a74113083e814c9fe5b28fMehdi Alizadeh when(mCarrierNetworkConfig.isCarrierEncryptionInfoAvailable()).thenReturn(true); 10484d962ec8f487f824214744498bba505a6db0c59Randy Pan } 10584d962ec8f487f824214744498bba505a6db0c59Randy Pan 10684d962ec8f487f824214744498bba505a6db0c59Randy Pan /** 10784d962ec8f487f824214744498bba505a6db0c59Randy Pan * Called after each test 10884d962ec8f487f824214744498bba505a6db0c59Randy Pan */ 10984d962ec8f487f824214744498bba505a6db0c59Randy Pan @After 11084d962ec8f487f824214744498bba505a6db0c59Randy Pan public void cleanup() { 11184d962ec8f487f824214744498bba505a6db0c59Randy Pan validateMockitoUsage(); 11284d962ec8f487f824214744498bba505a6db0c59Randy Pan } 11384d962ec8f487f824214744498bba505a6db0c59Randy Pan 11484d962ec8f487f824214744498bba505a6db0c59Randy Pan private Resources mResource; 115d0258ee4816148ff4ab9ac6b854fc5c51ea53be3Amin Shaikh 11684d962ec8f487f824214744498bba505a6db0c59Randy Pan private Context mContext; 117f4267b6840dbc7f430638c35c5448187b6e83846Christopher Wiley private TestAlarmManager mAlarmManager; 118f4267b6840dbc7f430638c35c5448187b6e83846Christopher Wiley private TestLooper mLooper = new TestLooper(); 11984d962ec8f487f824214744498bba505a6db0c59Randy Pan private WifiConnectivityManager mWifiConnectivityManager; 120220d198691d07506137b6af0bae810ed47ac4ed6Randy Pan private WifiNetworkSelector mWifiNS; 12184d962ec8f487f824214744498bba505a6db0c59Randy Pan private WifiStateMachine mWifiStateMachine; 12284d962ec8f487f824214744498bba505a6db0c59Randy Pan private WifiScanner mWifiScanner; 123a54399f6da655dfbe440333ca3682b9199060a27Randy Pan private WifiConnectivityHelper mWifiConnectivityHelper; 124cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan private ScanData mScanData; 12584d962ec8f487f824214744498bba505a6db0c59Randy Pan private WifiConfigManager mWifiConfigManager; 12684d962ec8f487f824214744498bba505a6db0c59Randy Pan private WifiInfo mWifiInfo; 12717c2a7b30e5680b11fc0073ce322ee7bc14ef2c5Randy Pan private LocalLog mLocalLog; 128d0258ee4816148ff4ab9ac6b854fc5c51ea53be3Amin Shaikh @Mock private FrameworkFacade mFrameworkFacade; 129d0258ee4816148ff4ab9ac6b854fc5c51ea53be3Amin Shaikh @Mock private NetworkScoreManager mNetworkScoreManager; 130b4de842310ca698d59ed5b9117d38362e2945947Rebecca Silberstein @Mock private Clock mClock; 131b4de842310ca698d59ed5b9117d38362e2945947Rebecca Silberstein @Mock private WifiLastResortWatchdog mWifiLastResortWatchdog; 132ce76a17ac5010e0b7ff5dcf6d8c9db8b48280f9cStephen Chen @Mock private OpenNetworkNotifier mOpenNetworkNotifier; 133664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh @Mock private CarrierNetworkNotifier mCarrierNetworkNotifier; 134664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh @Mock private CarrierNetworkConfig mCarrierNetworkConfig; 135b4de842310ca698d59ed5b9117d38362e2945947Rebecca Silberstein @Mock private WifiMetrics mWifiMetrics; 1360b9616e0e126221238edf5843a01b0cd3ec4daeeStephen Chen @Mock private WifiNetworkScoreCache mScoreCache; 137a54399f6da655dfbe440333ca3682b9199060a27Randy Pan @Captor ArgumentCaptor<ScanResult> mCandidateScanResultCaptor; 138ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan @Captor ArgumentCaptor<ArrayList<String>> mBssidBlacklistCaptor; 139ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan @Captor ArgumentCaptor<ArrayList<String>> mSsidWhitelistCaptor; 140095121ada1c9ea6034e86606395de20cddcad9baRoshan Pius @Captor ArgumentCaptor<WifiConfigManager.OnSavedNetworkUpdateListener> 141095121ada1c9ea6034e86606395de20cddcad9baRoshan Pius mSavedNetworkUpdateListenerCaptor; 14294eec4ff65e7e4c1c06c3e817655842b46c02b0aRoshan Pius private MockResources mResources; 143e4606e0f9532d250a1e06e8aba5fb48556225773Randy Pan private int mFullScanMaxTxPacketRate; 144e4606e0f9532d250a1e06e8aba5fb48556225773Randy Pan private int mFullScanMaxRxPacketRate; 14584d962ec8f487f824214744498bba505a6db0c59Randy Pan 14684d962ec8f487f824214744498bba505a6db0c59Randy Pan private static final int CANDIDATE_NETWORK_ID = 0; 14784d962ec8f487f824214744498bba505a6db0c59Randy Pan private static final String CANDIDATE_SSID = "\"AnSsid\""; 14884d962ec8f487f824214744498bba505a6db0c59Randy Pan private static final String CANDIDATE_BSSID = "6c:f3:7f:ae:8c:f3"; 149b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan private static final String INVALID_SCAN_RESULT_BSSID = "6c:f3:7f:ae:8c:f4"; 150b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan private static final long CURRENT_SYSTEM_TIME_MS = 1000; 151ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan private static final int MAX_BSSID_BLACKLIST_SIZE = 16; 152ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan 15384d962ec8f487f824214744498bba505a6db0c59Randy Pan 15409abbe29be6e552a2531b0367bd6d29647d33767Glen Kuhne Resources mockResource() { 15584d962ec8f487f824214744498bba505a6db0c59Randy Pan Resources resource = mock(Resources.class); 15684d962ec8f487f824214744498bba505a6db0c59Randy Pan 15784d962ec8f487f824214744498bba505a6db0c59Randy Pan when(resource.getInteger(R.integer.config_wifi_framework_SECURITY_AWARD)).thenReturn(80); 15884d962ec8f487f824214744498bba505a6db0c59Randy Pan when(resource.getInteger(R.integer.config_wifi_framework_SAME_BSSID_AWARD)).thenReturn(24); 15994eec4ff65e7e4c1c06c3e817655842b46c02b0aRoshan Pius when(resource.getBoolean( 16094eec4ff65e7e4c1c06c3e817655842b46c02b0aRoshan Pius R.bool.config_wifi_framework_enable_associated_network_selection)).thenReturn(true); 16194eec4ff65e7e4c1c06c3e817655842b46c02b0aRoshan Pius when(resource.getInteger( 16294eec4ff65e7e4c1c06c3e817655842b46c02b0aRoshan Pius R.integer.config_wifi_framework_wifi_score_good_rssi_threshold_24GHz)) 163220d198691d07506137b6af0bae810ed47ac4ed6Randy Pan .thenReturn(-60); 16494eec4ff65e7e4c1c06c3e817655842b46c02b0aRoshan Pius when(resource.getInteger( 165b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan R.integer.config_wifi_framework_current_network_boost)).thenReturn(16); 166e4606e0f9532d250a1e06e8aba5fb48556225773Randy Pan when(resource.getInteger( 167e4606e0f9532d250a1e06e8aba5fb48556225773Randy Pan R.integer.config_wifi_framework_max_tx_rate_for_full_scan)).thenReturn(8); 168e4606e0f9532d250a1e06e8aba5fb48556225773Randy Pan when(resource.getInteger( 169e4606e0f9532d250a1e06e8aba5fb48556225773Randy Pan R.integer.config_wifi_framework_max_rx_rate_for_full_scan)).thenReturn(16); 17084d962ec8f487f824214744498bba505a6db0c59Randy Pan return resource; 17184d962ec8f487f824214744498bba505a6db0c59Randy Pan } 17284d962ec8f487f824214744498bba505a6db0c59Randy Pan 17309abbe29be6e552a2531b0367bd6d29647d33767Glen Kuhne Context mockContext() { 17484d962ec8f487f824214744498bba505a6db0c59Randy Pan Context context = mock(Context.class); 17584d962ec8f487f824214744498bba505a6db0c59Randy Pan 17684d962ec8f487f824214744498bba505a6db0c59Randy Pan when(context.getResources()).thenReturn(mResource); 17784d962ec8f487f824214744498bba505a6db0c59Randy Pan when(context.getSystemService(Context.ALARM_SERVICE)).thenReturn( 1781d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius mAlarmManager.getAlarmManager()); 179adf5ee14bfcdef705684b1c4f12d80fae8433170Peter Qiu when(context.getPackageManager()).thenReturn(mock(PackageManager.class)); 18084d962ec8f487f824214744498bba505a6db0c59Randy Pan 18184d962ec8f487f824214744498bba505a6db0c59Randy Pan return context; 18284d962ec8f487f824214744498bba505a6db0c59Randy Pan } 18384d962ec8f487f824214744498bba505a6db0c59Randy Pan 184cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan ScanData mockScanData() { 185cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan ScanData scanData = mock(ScanData.class); 186cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan 187cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan when(scanData.isAllChannelsScanned()).thenReturn(true); 188cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan 189cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan return scanData; 190cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan } 191cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan 19209abbe29be6e552a2531b0367bd6d29647d33767Glen Kuhne WifiScanner mockWifiScanner() { 19384d962ec8f487f824214744498bba505a6db0c59Randy Pan WifiScanner scanner = mock(WifiScanner.class); 194cb26f07ae9c558f8c6136c951a7f633d0ccfe79fRandy Pan ArgumentCaptor<ScanListener> allSingleScanListenerCaptor = 195cb26f07ae9c558f8c6136c951a7f633d0ccfe79fRandy Pan ArgumentCaptor.forClass(ScanListener.class); 196cb26f07ae9c558f8c6136c951a7f633d0ccfe79fRandy Pan 197cb26f07ae9c558f8c6136c951a7f633d0ccfe79fRandy Pan doNothing().when(scanner).registerScanListener(allSingleScanListenerCaptor.capture()); 19884d962ec8f487f824214744498bba505a6db0c59Randy Pan 199cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan ScanData[] scanDatas = new ScanData[1]; 200cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan scanDatas[0] = mScanData; 20184d962ec8f487f824214744498bba505a6db0c59Randy Pan 20284d962ec8f487f824214744498bba505a6db0c59Randy Pan // do a synchronous answer for the ScanListener callbacks 20384d962ec8f487f824214744498bba505a6db0c59Randy Pan doAnswer(new AnswerWithArguments() { 204b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan public void answer(ScanSettings settings, ScanListener listener, 205b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan WorkSource workSource) throws Exception { 206b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan listener.onResults(scanDatas); 207b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan }}).when(scanner).startBackgroundScan(anyObject(), anyObject(), anyObject()); 20884d962ec8f487f824214744498bba505a6db0c59Randy Pan 20984d962ec8f487f824214744498bba505a6db0c59Randy Pan doAnswer(new AnswerWithArguments() { 210b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan public void answer(ScanSettings settings, ScanListener listener, 211b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan WorkSource workSource) throws Exception { 212b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan listener.onResults(scanDatas); 213652381b37461a4aa793327365e144bb4335cbd27Roshan Pius // WCM processes scan results received via onFullResult (even though they're the 214652381b37461a4aa793327365e144bb4335cbd27Roshan Pius // same as onResult for single scans). 215652381b37461a4aa793327365e144bb4335cbd27Roshan Pius if (mScanData != null && mScanData.getResults() != null) { 216652381b37461a4aa793327365e144bb4335cbd27Roshan Pius for (int i = 0; i < mScanData.getResults().length; i++) { 217652381b37461a4aa793327365e144bb4335cbd27Roshan Pius allSingleScanListenerCaptor.getValue().onFullResult( 218652381b37461a4aa793327365e144bb4335cbd27Roshan Pius mScanData.getResults()[i]); 219652381b37461a4aa793327365e144bb4335cbd27Roshan Pius } 220652381b37461a4aa793327365e144bb4335cbd27Roshan Pius } 221b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan allSingleScanListenerCaptor.getValue().onResults(scanDatas); 222b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan }}).when(scanner).startScan(anyObject(), anyObject(), anyObject()); 22384d962ec8f487f824214744498bba505a6db0c59Randy Pan 224fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius // This unfortunately needs to be a somewhat valid scan result, otherwise 225fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius // |ScanDetailUtil.toScanDetail| raises exceptions. 226fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius final ScanResult[] scanResults = new ScanResult[1]; 227fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius scanResults[0] = new ScanResult(WifiSsid.createFromAsciiEncoded(CANDIDATE_SSID), 228fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius CANDIDATE_SSID, CANDIDATE_BSSID, 1245, 0, "some caps", 229fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius -78, 2450, 1025, 22, 33, 20, 0, 0, true); 230fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius scanResults[0].informationElements = new InformationElement[1]; 231fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius scanResults[0].informationElements[0] = new InformationElement(); 232fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius scanResults[0].informationElements[0].id = InformationElement.EID_SSID; 233fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius scanResults[0].informationElements[0].bytes = 234b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan CANDIDATE_SSID.getBytes(StandardCharsets.UTF_8); 235fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius 236fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius doAnswer(new AnswerWithArguments() { 237fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius public void answer(ScanSettings settings, PnoSettings pnoSettings, 238fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius PnoScanListener listener) throws Exception { 239fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius listener.onPnoNetworkFound(scanResults); 240fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius }}).when(scanner).startDisconnectedPnoScan(anyObject(), anyObject(), anyObject()); 241fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius 242fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius doAnswer(new AnswerWithArguments() { 243fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius public void answer(ScanSettings settings, PnoSettings pnoSettings, 244fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius PnoScanListener listener) throws Exception { 245fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius listener.onPnoNetworkFound(scanResults); 246fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius }}).when(scanner).startConnectedPnoScan(anyObject(), anyObject(), anyObject()); 247fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius 24884d962ec8f487f824214744498bba505a6db0c59Randy Pan return scanner; 24984d962ec8f487f824214744498bba505a6db0c59Randy Pan } 25084d962ec8f487f824214744498bba505a6db0c59Randy Pan 251a54399f6da655dfbe440333ca3682b9199060a27Randy Pan WifiConnectivityHelper mockWifiConnectivityHelper() { 252a54399f6da655dfbe440333ca3682b9199060a27Randy Pan WifiConnectivityHelper connectivityHelper = mock(WifiConnectivityHelper.class); 253a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 254a54399f6da655dfbe440333ca3682b9199060a27Randy Pan when(connectivityHelper.isFirmwareRoamingSupported()).thenReturn(false); 255ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan when(connectivityHelper.getMaxNumBlacklistBssid()).thenReturn(MAX_BSSID_BLACKLIST_SIZE); 256a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 257a54399f6da655dfbe440333ca3682b9199060a27Randy Pan return connectivityHelper; 258a54399f6da655dfbe440333ca3682b9199060a27Randy Pan } 259a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 26009abbe29be6e552a2531b0367bd6d29647d33767Glen Kuhne WifiStateMachine mockWifiStateMachine() { 26184d962ec8f487f824214744498bba505a6db0c59Randy Pan WifiStateMachine stateMachine = mock(WifiStateMachine.class); 26284d962ec8f487f824214744498bba505a6db0c59Randy Pan 26384d962ec8f487f824214744498bba505a6db0c59Randy Pan when(stateMachine.isConnected()).thenReturn(false); 26484d962ec8f487f824214744498bba505a6db0c59Randy Pan when(stateMachine.isDisconnected()).thenReturn(true); 26584d962ec8f487f824214744498bba505a6db0c59Randy Pan when(stateMachine.isSupplicantTransientState()).thenReturn(false); 26684d962ec8f487f824214744498bba505a6db0c59Randy Pan 26784d962ec8f487f824214744498bba505a6db0c59Randy Pan return stateMachine; 26884d962ec8f487f824214744498bba505a6db0c59Randy Pan } 26984d962ec8f487f824214744498bba505a6db0c59Randy Pan 270220d198691d07506137b6af0bae810ed47ac4ed6Randy Pan WifiNetworkSelector mockWifiNetworkSelector() { 271220d198691d07506137b6af0bae810ed47ac4ed6Randy Pan WifiNetworkSelector ns = mock(WifiNetworkSelector.class); 27284d962ec8f487f824214744498bba505a6db0c59Randy Pan 27384d962ec8f487f824214744498bba505a6db0c59Randy Pan WifiConfiguration candidate = generateWifiConfig( 27484d962ec8f487f824214744498bba505a6db0c59Randy Pan 0, CANDIDATE_NETWORK_ID, CANDIDATE_SSID, false, true, null, null); 275b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan candidate.BSSID = WifiStateMachine.SUPPLICANT_BSSID_ANY; 27684d962ec8f487f824214744498bba505a6db0c59Randy Pan ScanResult candidateScanResult = new ScanResult(); 27784d962ec8f487f824214744498bba505a6db0c59Randy Pan candidateScanResult.SSID = CANDIDATE_SSID; 27884d962ec8f487f824214744498bba505a6db0c59Randy Pan candidateScanResult.BSSID = CANDIDATE_BSSID; 27984d962ec8f487f824214744498bba505a6db0c59Randy Pan candidate.getNetworkSelectionStatus().setCandidate(candidateScanResult); 28084d962ec8f487f824214744498bba505a6db0c59Randy Pan 281167b90b5e002698378728a54a417a08c317d29dcRandy Pan when(ns.selectNetwork(anyObject(), anyObject(), anyObject(), anyBoolean(), 282b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan anyBoolean(), anyBoolean())).thenReturn(candidate); 283220d198691d07506137b6af0bae810ed47ac4ed6Randy Pan return ns; 28484d962ec8f487f824214744498bba505a6db0c59Randy Pan } 28584d962ec8f487f824214744498bba505a6db0c59Randy Pan 286fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius WifiInfo getWifiInfo() { 287fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius WifiInfo wifiInfo = new WifiInfo(); 28884d962ec8f487f824214744498bba505a6db0c59Randy Pan 289fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius wifiInfo.setNetworkId(WifiConfiguration.INVALID_NETWORK_ID); 290fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius wifiInfo.setBSSID(null); 291fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius wifiInfo.setSupplicantState(SupplicantState.DISCONNECTED); 29284d962ec8f487f824214744498bba505a6db0c59Randy Pan 29384d962ec8f487f824214744498bba505a6db0c59Randy Pan return wifiInfo; 29484d962ec8f487f824214744498bba505a6db0c59Randy Pan } 29584d962ec8f487f824214744498bba505a6db0c59Randy Pan 29609abbe29be6e552a2531b0367bd6d29647d33767Glen Kuhne WifiConfigManager mockWifiConfigManager() { 29784d962ec8f487f824214744498bba505a6db0c59Randy Pan WifiConfigManager wifiConfigManager = mock(WifiConfigManager.class); 29884d962ec8f487f824214744498bba505a6db0c59Randy Pan 29994eec4ff65e7e4c1c06c3e817655842b46c02b0aRoshan Pius when(wifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(null); 30084d962ec8f487f824214744498bba505a6db0c59Randy Pan 301fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius // Pass dummy pno network list, otherwise Pno scan requests will not be triggered. 302fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius PnoSettings.PnoNetwork pnoNetwork = new PnoSettings.PnoNetwork(CANDIDATE_SSID); 303fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius ArrayList<PnoSettings.PnoNetwork> pnoNetworkList = new ArrayList<>(); 304fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius pnoNetworkList.add(pnoNetwork); 30594eec4ff65e7e4c1c06c3e817655842b46c02b0aRoshan Pius when(wifiConfigManager.retrievePnoNetworkList()).thenReturn(pnoNetworkList); 30694eec4ff65e7e4c1c06c3e817655842b46c02b0aRoshan Pius when(wifiConfigManager.retrievePnoNetworkList()).thenReturn(pnoNetworkList); 307095121ada1c9ea6034e86606395de20cddcad9baRoshan Pius doNothing().when(wifiConfigManager).setOnSavedNetworkUpdateListener( 308095121ada1c9ea6034e86606395de20cddcad9baRoshan Pius mSavedNetworkUpdateListenerCaptor.capture()); 309fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius 31084d962ec8f487f824214744498bba505a6db0c59Randy Pan return wifiConfigManager; 31184d962ec8f487f824214744498bba505a6db0c59Randy Pan } 31284d962ec8f487f824214744498bba505a6db0c59Randy Pan 31394eec4ff65e7e4c1c06c3e817655842b46c02b0aRoshan Pius WifiConnectivityManager createConnectivityManager() { 31479545bef4e8d6c1d891f7396665b5c457bc31617Michael Plass return new WifiConnectivityManager(mContext, 31579545bef4e8d6c1d891f7396665b5c457bc31617Michael Plass new ScoringParams(mContext), 31679545bef4e8d6c1d891f7396665b5c457bc31617Michael Plass mWifiStateMachine, mWifiScanner, 317a54399f6da655dfbe440333ca3682b9199060a27Randy Pan mWifiConfigManager, mWifiInfo, mWifiNS, mWifiConnectivityHelper, 318664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh mWifiLastResortWatchdog, mOpenNetworkNotifier, mCarrierNetworkNotifier, 319664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh mCarrierNetworkConfig, mWifiMetrics, mLooper.getLooper(), mClock, mLocalLog, true, 320664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh mFrameworkFacade, null, null, null); 32194eec4ff65e7e4c1c06c3e817655842b46c02b0aRoshan Pius } 32294eec4ff65e7e4c1c06c3e817655842b46c02b0aRoshan Pius 32384d962ec8f487f824214744498bba505a6db0c59Randy Pan /** 32484d962ec8f487f824214744498bba505a6db0c59Randy Pan * Wifi enters disconnected state while screen is on. 32584d962ec8f487f824214744498bba505a6db0c59Randy Pan * 32684d962ec8f487f824214744498bba505a6db0c59Randy Pan * Expected behavior: WifiConnectivityManager calls 327fe993ca46449a8aab3f7f55e2132456064bcee94Roshan Pius * WifiStateMachine.startConnectToNetwork() with the 32884d962ec8f487f824214744498bba505a6db0c59Randy Pan * expected candidate network ID and BSSID. 32984d962ec8f487f824214744498bba505a6db0c59Randy Pan */ 33084d962ec8f487f824214744498bba505a6db0c59Randy Pan @Test 33184d962ec8f487f824214744498bba505a6db0c59Randy Pan public void enterWifiDisconnectedStateWhenScreenOn() { 33284d962ec8f487f824214744498bba505a6db0c59Randy Pan // Set screen to on 33384d962ec8f487f824214744498bba505a6db0c59Randy Pan mWifiConnectivityManager.handleScreenStateChanged(true); 33484d962ec8f487f824214744498bba505a6db0c59Randy Pan 33584d962ec8f487f824214744498bba505a6db0c59Randy Pan // Set WiFi to disconnected state 33684d962ec8f487f824214744498bba505a6db0c59Randy Pan mWifiConnectivityManager.handleConnectionStateChanged( 33784d962ec8f487f824214744498bba505a6db0c59Randy Pan WifiConnectivityManager.WIFI_STATE_DISCONNECTED); 33884d962ec8f487f824214744498bba505a6db0c59Randy Pan 3399686c96d8d0c0bc21ca069e244e2570c169724e1Lorenzo Colitti verify(mWifiStateMachine).startConnectToNetwork( 3409686c96d8d0c0bc21ca069e244e2570c169724e1Lorenzo Colitti CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); 34184d962ec8f487f824214744498bba505a6db0c59Randy Pan } 34284d962ec8f487f824214744498bba505a6db0c59Randy Pan 34384d962ec8f487f824214744498bba505a6db0c59Randy Pan /** 34484d962ec8f487f824214744498bba505a6db0c59Randy Pan * Wifi enters connected state while screen is on. 34584d962ec8f487f824214744498bba505a6db0c59Randy Pan * 34684d962ec8f487f824214744498bba505a6db0c59Randy Pan * Expected behavior: WifiConnectivityManager calls 347fe993ca46449a8aab3f7f55e2132456064bcee94Roshan Pius * WifiStateMachine.startConnectToNetwork() with the 34884d962ec8f487f824214744498bba505a6db0c59Randy Pan * expected candidate network ID and BSSID. 34984d962ec8f487f824214744498bba505a6db0c59Randy Pan */ 35084d962ec8f487f824214744498bba505a6db0c59Randy Pan @Test 35184d962ec8f487f824214744498bba505a6db0c59Randy Pan public void enterWifiConnectedStateWhenScreenOn() { 35284d962ec8f487f824214744498bba505a6db0c59Randy Pan // Set screen to on 35384d962ec8f487f824214744498bba505a6db0c59Randy Pan mWifiConnectivityManager.handleScreenStateChanged(true); 35484d962ec8f487f824214744498bba505a6db0c59Randy Pan 35584d962ec8f487f824214744498bba505a6db0c59Randy Pan // Set WiFi to connected state 35684d962ec8f487f824214744498bba505a6db0c59Randy Pan mWifiConnectivityManager.handleConnectionStateChanged( 35784d962ec8f487f824214744498bba505a6db0c59Randy Pan WifiConnectivityManager.WIFI_STATE_CONNECTED); 35884d962ec8f487f824214744498bba505a6db0c59Randy Pan 3599686c96d8d0c0bc21ca069e244e2570c169724e1Lorenzo Colitti verify(mWifiStateMachine).startConnectToNetwork( 3609686c96d8d0c0bc21ca069e244e2570c169724e1Lorenzo Colitti CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); 36184d962ec8f487f824214744498bba505a6db0c59Randy Pan } 36284d962ec8f487f824214744498bba505a6db0c59Randy Pan 36384d962ec8f487f824214744498bba505a6db0c59Randy Pan /** 36484d962ec8f487f824214744498bba505a6db0c59Randy Pan * Screen turned on while WiFi in disconnected state. 36584d962ec8f487f824214744498bba505a6db0c59Randy Pan * 36684d962ec8f487f824214744498bba505a6db0c59Randy Pan * Expected behavior: WifiConnectivityManager calls 367fe993ca46449a8aab3f7f55e2132456064bcee94Roshan Pius * WifiStateMachine.startConnectToNetwork() with the 36884d962ec8f487f824214744498bba505a6db0c59Randy Pan * expected candidate network ID and BSSID. 36984d962ec8f487f824214744498bba505a6db0c59Randy Pan */ 37084d962ec8f487f824214744498bba505a6db0c59Randy Pan @Test 37184d962ec8f487f824214744498bba505a6db0c59Randy Pan public void turnScreenOnWhenWifiInDisconnectedState() { 37284d962ec8f487f824214744498bba505a6db0c59Randy Pan // Set WiFi to disconnected state 37384d962ec8f487f824214744498bba505a6db0c59Randy Pan mWifiConnectivityManager.handleConnectionStateChanged( 37484d962ec8f487f824214744498bba505a6db0c59Randy Pan WifiConnectivityManager.WIFI_STATE_DISCONNECTED); 37584d962ec8f487f824214744498bba505a6db0c59Randy Pan 37684d962ec8f487f824214744498bba505a6db0c59Randy Pan // Set screen to on 37784d962ec8f487f824214744498bba505a6db0c59Randy Pan mWifiConnectivityManager.handleScreenStateChanged(true); 37884d962ec8f487f824214744498bba505a6db0c59Randy Pan 379fe993ca46449a8aab3f7f55e2132456064bcee94Roshan Pius verify(mWifiStateMachine, atLeastOnce()).startConnectToNetwork( 3809686c96d8d0c0bc21ca069e244e2570c169724e1Lorenzo Colitti CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); 38184d962ec8f487f824214744498bba505a6db0c59Randy Pan } 38284d962ec8f487f824214744498bba505a6db0c59Randy Pan 38384d962ec8f487f824214744498bba505a6db0c59Randy Pan /** 38484d962ec8f487f824214744498bba505a6db0c59Randy Pan * Screen turned on while WiFi in connected state. 38584d962ec8f487f824214744498bba505a6db0c59Randy Pan * 38684d962ec8f487f824214744498bba505a6db0c59Randy Pan * Expected behavior: WifiConnectivityManager calls 387fe993ca46449a8aab3f7f55e2132456064bcee94Roshan Pius * WifiStateMachine.startConnectToNetwork() with the 38884d962ec8f487f824214744498bba505a6db0c59Randy Pan * expected candidate network ID and BSSID. 38984d962ec8f487f824214744498bba505a6db0c59Randy Pan */ 39084d962ec8f487f824214744498bba505a6db0c59Randy Pan @Test 39184d962ec8f487f824214744498bba505a6db0c59Randy Pan public void turnScreenOnWhenWifiInConnectedState() { 39284d962ec8f487f824214744498bba505a6db0c59Randy Pan // Set WiFi to connected state 39384d962ec8f487f824214744498bba505a6db0c59Randy Pan mWifiConnectivityManager.handleConnectionStateChanged( 39484d962ec8f487f824214744498bba505a6db0c59Randy Pan WifiConnectivityManager.WIFI_STATE_CONNECTED); 39584d962ec8f487f824214744498bba505a6db0c59Randy Pan 39684d962ec8f487f824214744498bba505a6db0c59Randy Pan // Set screen to on 39784d962ec8f487f824214744498bba505a6db0c59Randy Pan mWifiConnectivityManager.handleScreenStateChanged(true); 39884d962ec8f487f824214744498bba505a6db0c59Randy Pan 399fe993ca46449a8aab3f7f55e2132456064bcee94Roshan Pius verify(mWifiStateMachine, atLeastOnce()).startConnectToNetwork( 4009686c96d8d0c0bc21ca069e244e2570c169724e1Lorenzo Colitti CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); 401fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius } 402fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius 403fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius /** 404a68f3e359ac27285b10332ea2461469e5e03bfd4Randy Pan * Screen turned on while WiFi in connected state but 405a68f3e359ac27285b10332ea2461469e5e03bfd4Randy Pan * auto roaming is disabled. 406a68f3e359ac27285b10332ea2461469e5e03bfd4Randy Pan * 407a68f3e359ac27285b10332ea2461469e5e03bfd4Randy Pan * Expected behavior: WifiConnectivityManager doesn't invoke 408fe993ca46449a8aab3f7f55e2132456064bcee94Roshan Pius * WifiStateMachine.startConnectToNetwork() because roaming 409a68f3e359ac27285b10332ea2461469e5e03bfd4Randy Pan * is turned off. 410a68f3e359ac27285b10332ea2461469e5e03bfd4Randy Pan */ 411a68f3e359ac27285b10332ea2461469e5e03bfd4Randy Pan @Test 412a68f3e359ac27285b10332ea2461469e5e03bfd4Randy Pan public void turnScreenOnWhenWifiInConnectedStateRoamingDisabled() { 41394eec4ff65e7e4c1c06c3e817655842b46c02b0aRoshan Pius // Turn off auto roaming 41494eec4ff65e7e4c1c06c3e817655842b46c02b0aRoshan Pius when(mResource.getBoolean( 41594eec4ff65e7e4c1c06c3e817655842b46c02b0aRoshan Pius R.bool.config_wifi_framework_enable_associated_network_selection)) 41694eec4ff65e7e4c1c06c3e817655842b46c02b0aRoshan Pius .thenReturn(false); 41794eec4ff65e7e4c1c06c3e817655842b46c02b0aRoshan Pius mWifiConnectivityManager = createConnectivityManager(); 41894eec4ff65e7e4c1c06c3e817655842b46c02b0aRoshan Pius 419a68f3e359ac27285b10332ea2461469e5e03bfd4Randy Pan // Set WiFi to connected state 420a68f3e359ac27285b10332ea2461469e5e03bfd4Randy Pan mWifiConnectivityManager.handleConnectionStateChanged( 421a68f3e359ac27285b10332ea2461469e5e03bfd4Randy Pan WifiConnectivityManager.WIFI_STATE_CONNECTED); 422a68f3e359ac27285b10332ea2461469e5e03bfd4Randy Pan 423a68f3e359ac27285b10332ea2461469e5e03bfd4Randy Pan // Set screen to on 424a68f3e359ac27285b10332ea2461469e5e03bfd4Randy Pan mWifiConnectivityManager.handleScreenStateChanged(true); 425a68f3e359ac27285b10332ea2461469e5e03bfd4Randy Pan 426fe993ca46449a8aab3f7f55e2132456064bcee94Roshan Pius verify(mWifiStateMachine, times(0)).startConnectToNetwork( 4279686c96d8d0c0bc21ca069e244e2570c169724e1Lorenzo Colitti CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); 428a68f3e359ac27285b10332ea2461469e5e03bfd4Randy Pan } 429a68f3e359ac27285b10332ea2461469e5e03bfd4Randy Pan 430a68f3e359ac27285b10332ea2461469e5e03bfd4Randy Pan /** 431fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius * Multiple back to back connection attempts within the rate interval should be rate limited. 432fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius * 433fe993ca46449a8aab3f7f55e2132456064bcee94Roshan Pius * Expected behavior: WifiConnectivityManager calls WifiStateMachine.startConnectToNetwork() 434fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius * with the expected candidate network ID and BSSID for only the expected number of times within 435fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius * the given interval. 436fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius */ 437fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius @Test 438fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius public void connectionAttemptRateLimitedWhenScreenOff() { 439fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius int maxAttemptRate = WifiConnectivityManager.MAX_CONNECTION_ATTEMPTS_RATE; 440fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius int timeInterval = WifiConnectivityManager.MAX_CONNECTION_ATTEMPTS_TIME_INTERVAL_MS; 441fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius int numAttempts = 0; 442fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius int connectionAttemptIntervals = timeInterval / maxAttemptRate; 443fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius 444fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius mWifiConnectivityManager.handleScreenStateChanged(false); 445fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius 446fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius // First attempt the max rate number of connections within the rate interval. 447fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius long currentTimeStamp = 0; 448fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius for (int attempt = 0; attempt < maxAttemptRate; attempt++) { 449fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius currentTimeStamp += connectionAttemptIntervals; 4505de29ec72c54cb73fdc1b59072f66a2627b8764cNingyuan Wang when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp); 451fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius // Set WiFi to disconnected state to trigger PNO scan 452fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius mWifiConnectivityManager.handleConnectionStateChanged( 453fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius WifiConnectivityManager.WIFI_STATE_DISCONNECTED); 454fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius numAttempts++; 455fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius } 456fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius // Now trigger another connection attempt before the rate interval, this should be 457fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius // skipped because we've crossed rate limit. 4585de29ec72c54cb73fdc1b59072f66a2627b8764cNingyuan Wang when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp); 459fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius // Set WiFi to disconnected state to trigger PNO scan 460fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius mWifiConnectivityManager.handleConnectionStateChanged( 461fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius WifiConnectivityManager.WIFI_STATE_DISCONNECTED); 462fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius 463fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius // Verify that we attempt to connect upto the rate. 464fe993ca46449a8aab3f7f55e2132456064bcee94Roshan Pius verify(mWifiStateMachine, times(numAttempts)).startConnectToNetwork( 4659686c96d8d0c0bc21ca069e244e2570c169724e1Lorenzo Colitti CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); 466fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius } 467fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius 468fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius /** 469fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius * Multiple back to back connection attempts outside the rate interval should not be rate 470fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius * limited. 471fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius * 472fe993ca46449a8aab3f7f55e2132456064bcee94Roshan Pius * Expected behavior: WifiConnectivityManager calls WifiStateMachine.startConnectToNetwork() 473fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius * with the expected candidate network ID and BSSID for only the expected number of times within 474fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius * the given interval. 475fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius */ 476fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius @Test 477fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius public void connectionAttemptNotRateLimitedWhenScreenOff() { 478fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius int maxAttemptRate = WifiConnectivityManager.MAX_CONNECTION_ATTEMPTS_RATE; 479fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius int timeInterval = WifiConnectivityManager.MAX_CONNECTION_ATTEMPTS_TIME_INTERVAL_MS; 480fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius int numAttempts = 0; 481fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius int connectionAttemptIntervals = timeInterval / maxAttemptRate; 482fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius 483fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius mWifiConnectivityManager.handleScreenStateChanged(false); 484fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius 485fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius // First attempt the max rate number of connections within the rate interval. 486fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius long currentTimeStamp = 0; 487fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius for (int attempt = 0; attempt < maxAttemptRate; attempt++) { 488fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius currentTimeStamp += connectionAttemptIntervals; 4895de29ec72c54cb73fdc1b59072f66a2627b8764cNingyuan Wang when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp); 490fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius // Set WiFi to disconnected state to trigger PNO scan 491fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius mWifiConnectivityManager.handleConnectionStateChanged( 492fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius WifiConnectivityManager.WIFI_STATE_DISCONNECTED); 493fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius numAttempts++; 494fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius } 495fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius // Now trigger another connection attempt after the rate interval, this should not be 496fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius // skipped because we should've evicted the older attempt. 4975de29ec72c54cb73fdc1b59072f66a2627b8764cNingyuan Wang when(mClock.getElapsedSinceBootMillis()).thenReturn( 498fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius currentTimeStamp + connectionAttemptIntervals * 2); 499fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius // Set WiFi to disconnected state to trigger PNO scan 500fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius mWifiConnectivityManager.handleConnectionStateChanged( 501fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius WifiConnectivityManager.WIFI_STATE_DISCONNECTED); 502fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius numAttempts++; 503fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius 504fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius // Verify that all the connection attempts went through 505fe993ca46449a8aab3f7f55e2132456064bcee94Roshan Pius verify(mWifiStateMachine, times(numAttempts)).startConnectToNetwork( 5069686c96d8d0c0bc21ca069e244e2570c169724e1Lorenzo Colitti CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); 507fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius } 508fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius 509fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius /** 510fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius * Multiple back to back connection attempts after a user selection should not be rate limited. 511fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius * 512fe993ca46449a8aab3f7f55e2132456064bcee94Roshan Pius * Expected behavior: WifiConnectivityManager calls WifiStateMachine.startConnectToNetwork() 513fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius * with the expected candidate network ID and BSSID for only the expected number of times within 514fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius * the given interval. 515fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius */ 516fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius @Test 517fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius public void connectionAttemptNotRateLimitedWhenScreenOffAfterUserSelection() { 518fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius int maxAttemptRate = WifiConnectivityManager.MAX_CONNECTION_ATTEMPTS_RATE; 519fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius int timeInterval = WifiConnectivityManager.MAX_CONNECTION_ATTEMPTS_TIME_INTERVAL_MS; 520fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius int numAttempts = 0; 521fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius int connectionAttemptIntervals = timeInterval / maxAttemptRate; 522fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius 523fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius mWifiConnectivityManager.handleScreenStateChanged(false); 524fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius 525fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius // First attempt the max rate number of connections within the rate interval. 526fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius long currentTimeStamp = 0; 527fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius for (int attempt = 0; attempt < maxAttemptRate; attempt++) { 528fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius currentTimeStamp += connectionAttemptIntervals; 5295de29ec72c54cb73fdc1b59072f66a2627b8764cNingyuan Wang when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp); 530fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius // Set WiFi to disconnected state to trigger PNO scan 531fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius mWifiConnectivityManager.handleConnectionStateChanged( 532fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius WifiConnectivityManager.WIFI_STATE_DISCONNECTED); 533fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius numAttempts++; 534fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius } 535fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius 536fa25be15a3dab0fda8d041798c4cac531d0d0866Roshan Pius mWifiConnectivityManager.setUserConnectChoice(CANDIDATE_NETWORK_ID); 537ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan mWifiConnectivityManager.prepareForForcedConnection(CANDIDATE_NETWORK_ID); 538fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius 539fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius for (int attempt = 0; attempt < maxAttemptRate; attempt++) { 540fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius currentTimeStamp += connectionAttemptIntervals; 5415de29ec72c54cb73fdc1b59072f66a2627b8764cNingyuan Wang when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp); 542fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius // Set WiFi to disconnected state to trigger PNO scan 543fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius mWifiConnectivityManager.handleConnectionStateChanged( 544fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius WifiConnectivityManager.WIFI_STATE_DISCONNECTED); 545fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius numAttempts++; 546fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius } 547fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius 548fa2ac2743307559e8dcc5aaf54873536315fbe62Roshan Pius // Verify that all the connection attempts went through 549fe993ca46449a8aab3f7f55e2132456064bcee94Roshan Pius verify(mWifiStateMachine, times(numAttempts)).startConnectToNetwork( 5509686c96d8d0c0bc21ca069e244e2570c169724e1Lorenzo Colitti CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); 55184d962ec8f487f824214744498bba505a6db0c59Randy Pan } 5523d09b9117df33608a43c1fbe0135123e2de9aea2Randy Pan 5533d09b9117df33608a43c1fbe0135123e2de9aea2Randy Pan /** 5543d09b9117df33608a43c1fbe0135123e2de9aea2Randy Pan * PNO retry for low RSSI networks. 5553d09b9117df33608a43c1fbe0135123e2de9aea2Randy Pan * 5563d09b9117df33608a43c1fbe0135123e2de9aea2Randy Pan * Expected behavior: WifiConnectivityManager doubles the low RSSI 5573d09b9117df33608a43c1fbe0135123e2de9aea2Randy Pan * network retry delay value after QNS skips the PNO scan results 5583d09b9117df33608a43c1fbe0135123e2de9aea2Randy Pan * because of their low RSSI values. 5593d09b9117df33608a43c1fbe0135123e2de9aea2Randy Pan */ 5603d09b9117df33608a43c1fbe0135123e2de9aea2Randy Pan @Test 561220d198691d07506137b6af0bae810ed47ac4ed6Randy Pan public void pnoRetryForLowRssiNetwork() { 562167b90b5e002698378728a54a417a08c317d29dcRandy Pan when(mWifiNS.selectNetwork(anyObject(), anyObject(), anyObject(), anyBoolean(), 563b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan anyBoolean(), anyBoolean())).thenReturn(null); 5643d09b9117df33608a43c1fbe0135123e2de9aea2Randy Pan 5653d09b9117df33608a43c1fbe0135123e2de9aea2Randy Pan // Set screen to off 5663d09b9117df33608a43c1fbe0135123e2de9aea2Randy Pan mWifiConnectivityManager.handleScreenStateChanged(false); 5673d09b9117df33608a43c1fbe0135123e2de9aea2Randy Pan 5683d09b9117df33608a43c1fbe0135123e2de9aea2Randy Pan // Get the current retry delay value 5693d09b9117df33608a43c1fbe0135123e2de9aea2Randy Pan int lowRssiNetworkRetryDelayStartValue = mWifiConnectivityManager 5703d09b9117df33608a43c1fbe0135123e2de9aea2Randy Pan .getLowRssiNetworkRetryDelay(); 5713d09b9117df33608a43c1fbe0135123e2de9aea2Randy Pan 5723d09b9117df33608a43c1fbe0135123e2de9aea2Randy Pan // Set WiFi to disconnected state to trigger PNO scan 5733d09b9117df33608a43c1fbe0135123e2de9aea2Randy Pan mWifiConnectivityManager.handleConnectionStateChanged( 5743d09b9117df33608a43c1fbe0135123e2de9aea2Randy Pan WifiConnectivityManager.WIFI_STATE_DISCONNECTED); 5753d09b9117df33608a43c1fbe0135123e2de9aea2Randy Pan 5763d09b9117df33608a43c1fbe0135123e2de9aea2Randy Pan // Get the retry delay value after QNS didn't select a 5773d09b9117df33608a43c1fbe0135123e2de9aea2Randy Pan // network candicate from the PNO scan results. 5783d09b9117df33608a43c1fbe0135123e2de9aea2Randy Pan int lowRssiNetworkRetryDelayAfterPnoValue = mWifiConnectivityManager 5793d09b9117df33608a43c1fbe0135123e2de9aea2Randy Pan .getLowRssiNetworkRetryDelay(); 5803d09b9117df33608a43c1fbe0135123e2de9aea2Randy Pan 5813d09b9117df33608a43c1fbe0135123e2de9aea2Randy Pan assertEquals(lowRssiNetworkRetryDelayStartValue * 2, 582220d198691d07506137b6af0bae810ed47ac4ed6Randy Pan lowRssiNetworkRetryDelayAfterPnoValue); 5833d09b9117df33608a43c1fbe0135123e2de9aea2Randy Pan } 5841d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius 5851d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius /** 5861d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius * Ensure that the watchdog bite increments the "Pno bad" metric. 5871d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius * 5881d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius * Expected behavior: WifiConnectivityManager detects that the PNO scan failed to find 5891d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius * a candidate while watchdog single scan did. 5901d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius */ 5911d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius @Test 5921d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius public void watchdogBitePnoBadIncrementsMetrics() { 5931d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius // Set screen to off 5941d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius mWifiConnectivityManager.handleScreenStateChanged(false); 5951d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius 5961d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius // Set WiFi to disconnected state to trigger PNO scan 5971d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius mWifiConnectivityManager.handleConnectionStateChanged( 5981d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius WifiConnectivityManager.WIFI_STATE_DISCONNECTED); 5991d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius 6001d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius // Now fire the watchdog alarm and verify the metrics were incremented. 6011d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius mAlarmManager.dispatch(WifiConnectivityManager.WATCHDOG_TIMER_TAG); 6021d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius mLooper.dispatchAll(); 6031d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius 6041d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius verify(mWifiMetrics).incrementNumConnectivityWatchdogPnoBad(); 6051d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius verify(mWifiMetrics, never()).incrementNumConnectivityWatchdogPnoGood(); 6061d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius } 6071d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius 6081d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius /** 6091d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius * Ensure that the watchdog bite increments the "Pno good" metric. 6101d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius * 6111d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius * Expected behavior: WifiConnectivityManager detects that the PNO scan failed to find 6121d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius * a candidate which was the same with watchdog single scan. 6131d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius */ 6141d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius @Test 6151d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius public void watchdogBitePnoGoodIncrementsMetrics() { 6161d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius // Qns returns no candidate after watchdog single scan. 617167b90b5e002698378728a54a417a08c317d29dcRandy Pan when(mWifiNS.selectNetwork(anyObject(), anyObject(), anyObject(), anyBoolean(), 618b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan anyBoolean(), anyBoolean())).thenReturn(null); 6191d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius 6201d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius // Set screen to off 6211d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius mWifiConnectivityManager.handleScreenStateChanged(false); 6221d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius 6231d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius // Set WiFi to disconnected state to trigger PNO scan 6241d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius mWifiConnectivityManager.handleConnectionStateChanged( 6251d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius WifiConnectivityManager.WIFI_STATE_DISCONNECTED); 6261d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius 6271d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius // Now fire the watchdog alarm and verify the metrics were incremented. 6281d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius mAlarmManager.dispatch(WifiConnectivityManager.WATCHDOG_TIMER_TAG); 6291d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius mLooper.dispatchAll(); 6301d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius 6311d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius verify(mWifiMetrics).incrementNumConnectivityWatchdogPnoGood(); 6321d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius verify(mWifiMetrics, never()).incrementNumConnectivityWatchdogPnoBad(); 6331d7d62393181cc36b6f87c3cf2151adc54275f9cRoshan Pius } 634b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan 635b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan /** 636ce76a17ac5010e0b7ff5dcf6d8c9db8b48280f9cStephen Chen * {@link OpenNetworkNotifier} handles scan results on network selection. 6373f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen * 6383f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen * Expected behavior: ONA handles scan results 6393f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen */ 6403f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen @Test 64108ffa580f6756129929667785408da377b363787Stephen Chen public void wifiDisconnected_noConnectionCandidate_openNetworkNotifierScanResultsHandled() { 6423f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen // no connection candidate selected 6433f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen when(mWifiNS.selectNetwork(anyObject(), anyObject(), anyObject(), anyBoolean(), 6443f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen anyBoolean(), anyBoolean())).thenReturn(null); 6453f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen 6463f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen List<ScanDetail> expectedOpenNetworks = new ArrayList<>(); 6473f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen expectedOpenNetworks.add( 6483f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen new ScanDetail( 6493f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen new ScanResult(WifiSsid.createFromAsciiEncoded(CANDIDATE_SSID), 6503f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen CANDIDATE_SSID, CANDIDATE_BSSID, 1245, 0, "some caps", -78, 2450, 6513f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen 1025, 22, 33, 20, 0, 0, true), null)); 6523f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen 6533f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen when(mWifiNS.getFilteredScanDetailsForOpenUnsavedNetworks()) 6543f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen .thenReturn(expectedOpenNetworks); 6553f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen 6563f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen // Set WiFi to disconnected state to trigger PNO scan 6573f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen mWifiConnectivityManager.handleConnectionStateChanged( 6583f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen WifiConnectivityManager.WIFI_STATE_DISCONNECTED); 6593f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen 660ce76a17ac5010e0b7ff5dcf6d8c9db8b48280f9cStephen Chen verify(mOpenNetworkNotifier).handleScanResults(expectedOpenNetworks); 6613f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen } 6623f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen 6633f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen /** 664b6103294dc1e6785c8ba236582e53801e1f9f2cdStephen Chen * When wifi is connected, {@link OpenNetworkNotifier} handles the Wi-Fi connected behavior. 6653f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen * 666b6103294dc1e6785c8ba236582e53801e1f9f2cdStephen Chen * Expected behavior: ONA handles connected behavior 6673f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen */ 6683f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen @Test 669b6103294dc1e6785c8ba236582e53801e1f9f2cdStephen Chen public void wifiConnected_openNetworkNotifierHandlesConnection() { 6703f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen // Set WiFi to connected state 6713f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen mWifiConnectivityManager.handleConnectionStateChanged( 6723f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen WifiConnectivityManager.WIFI_STATE_CONNECTED); 6733f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen 674b6103294dc1e6785c8ba236582e53801e1f9f2cdStephen Chen verify(mOpenNetworkNotifier).handleWifiConnected(); 6753f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen } 6763f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen 6773f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen /** 678ce76a17ac5010e0b7ff5dcf6d8c9db8b48280f9cStephen Chen * When wifi is connected, {@link OpenNetworkNotifier} handles connection state 6793f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen * change. 6803f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen * 6813f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen * Expected behavior: ONA does not clear pending notification. 6823f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen */ 6833f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen @Test 68408ffa580f6756129929667785408da377b363787Stephen Chen public void wifiDisconnected_openNetworkNotifierDoesNotClearPendingNotification() { 6853f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen // Set WiFi to disconnected state 6863f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen mWifiConnectivityManager.handleConnectionStateChanged( 6873f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen WifiConnectivityManager.WIFI_STATE_DISCONNECTED); 6883f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen 689ce76a17ac5010e0b7ff5dcf6d8c9db8b48280f9cStephen Chen verify(mOpenNetworkNotifier, never()).clearPendingNotification(anyBoolean()); 6903f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen } 6913f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen 6923f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen /** 69308ffa580f6756129929667785408da377b363787Stephen Chen * When a Wi-Fi connection attempt ends, {@link OpenNetworkNotifier} handles the connection 69408ffa580f6756129929667785408da377b363787Stephen Chen * failure. A failure code that is not {@link WifiMetrics.ConnectionEvent#FAILURE_NONE} 69508ffa580f6756129929667785408da377b363787Stephen Chen * represents a connection failure. 69608ffa580f6756129929667785408da377b363787Stephen Chen * 69708ffa580f6756129929667785408da377b363787Stephen Chen * Expected behavior: ONA handles connection failure. 69808ffa580f6756129929667785408da377b363787Stephen Chen */ 69908ffa580f6756129929667785408da377b363787Stephen Chen @Test 70008ffa580f6756129929667785408da377b363787Stephen Chen public void wifiConnectionEndsWithFailure_openNetworkNotifierHandlesConnectionFailure() { 70108ffa580f6756129929667785408da377b363787Stephen Chen mWifiConnectivityManager.handleConnectionAttemptEnded( 70208ffa580f6756129929667785408da377b363787Stephen Chen WifiMetrics.ConnectionEvent.FAILURE_CONNECT_NETWORK_FAILED); 70308ffa580f6756129929667785408da377b363787Stephen Chen 70408ffa580f6756129929667785408da377b363787Stephen Chen verify(mOpenNetworkNotifier).handleConnectionFailure(); 70508ffa580f6756129929667785408da377b363787Stephen Chen } 70608ffa580f6756129929667785408da377b363787Stephen Chen 70708ffa580f6756129929667785408da377b363787Stephen Chen /** 70808ffa580f6756129929667785408da377b363787Stephen Chen * When a Wi-Fi connection attempt ends, {@link OpenNetworkNotifier} does not handle connection 70908ffa580f6756129929667785408da377b363787Stephen Chen * failure after a successful connection. {@link WifiMetrics.ConnectionEvent#FAILURE_NONE} 71008ffa580f6756129929667785408da377b363787Stephen Chen * represents a successful connection. 71108ffa580f6756129929667785408da377b363787Stephen Chen * 71208ffa580f6756129929667785408da377b363787Stephen Chen * Expected behavior: ONA does nothing. 71308ffa580f6756129929667785408da377b363787Stephen Chen */ 71408ffa580f6756129929667785408da377b363787Stephen Chen @Test 71508ffa580f6756129929667785408da377b363787Stephen Chen public void wifiConnectionEndsWithSuccess_openNetworkNotifierDoesNotHandleConnectionFailure() { 71608ffa580f6756129929667785408da377b363787Stephen Chen mWifiConnectivityManager.handleConnectionAttemptEnded( 71708ffa580f6756129929667785408da377b363787Stephen Chen WifiMetrics.ConnectionEvent.FAILURE_NONE); 71808ffa580f6756129929667785408da377b363787Stephen Chen 71908ffa580f6756129929667785408da377b363787Stephen Chen verify(mOpenNetworkNotifier, never()).handleConnectionFailure(); 72008ffa580f6756129929667785408da377b363787Stephen Chen } 72108ffa580f6756129929667785408da377b363787Stephen Chen 72208ffa580f6756129929667785408da377b363787Stephen Chen /** 7233f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen * When Wi-Fi is disabled, clear the pending notification and reset notification repeat delay. 7243f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen * 7253f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen * Expected behavior: clear pending notification and reset notification repeat delay 7263f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen * */ 7273f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen @Test 72808ffa580f6756129929667785408da377b363787Stephen Chen public void openNetworkNotifierClearsPendingNotificationOnWifiDisabled() { 7293f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen mWifiConnectivityManager.setWifiEnabled(false); 7303f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen 73108ffa580f6756129929667785408da377b363787Stephen Chen verify(mOpenNetworkNotifier).clearPendingNotification(true /* resetRepeatDelay */); 7323f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen } 7333f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen 7343f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen /** 7350f41a6a3df4a2cedcad60324d91e1fffc968cfbbStephen Chen * Verify that the ONA controller tracks screen state changes. 7360f41a6a3df4a2cedcad60324d91e1fffc968cfbbStephen Chen */ 7370f41a6a3df4a2cedcad60324d91e1fffc968cfbbStephen Chen @Test 73808ffa580f6756129929667785408da377b363787Stephen Chen public void openNetworkNotifierTracksScreenStateChanges() { 7390f41a6a3df4a2cedcad60324d91e1fffc968cfbbStephen Chen mWifiConnectivityManager.handleScreenStateChanged(false); 7400f41a6a3df4a2cedcad60324d91e1fffc968cfbbStephen Chen 741ce76a17ac5010e0b7ff5dcf6d8c9db8b48280f9cStephen Chen verify(mOpenNetworkNotifier).handleScreenStateChanged(false); 7420f41a6a3df4a2cedcad60324d91e1fffc968cfbbStephen Chen 7430f41a6a3df4a2cedcad60324d91e1fffc968cfbbStephen Chen mWifiConnectivityManager.handleScreenStateChanged(true); 7440f41a6a3df4a2cedcad60324d91e1fffc968cfbbStephen Chen 745ce76a17ac5010e0b7ff5dcf6d8c9db8b48280f9cStephen Chen verify(mOpenNetworkNotifier).handleScreenStateChanged(true); 7460f41a6a3df4a2cedcad60324d91e1fffc968cfbbStephen Chen } 7470f41a6a3df4a2cedcad60324d91e1fffc968cfbbStephen Chen 7480f41a6a3df4a2cedcad60324d91e1fffc968cfbbStephen Chen /** 749664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh * {@link CarrierNetworkNotifier} handles scan results on network selection. 750664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh * 751664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh * Expected behavior: CarrierNetworkNotifier handles scan results 752664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh */ 753664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh @Test 754664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh public void wifiDisconnected_noConnectionCandidate_CarrierNetworkNotifierScanResultsHandled() { 755664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh // no connection candidate selected 756664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh when(mWifiNS.selectNetwork(anyObject(), anyObject(), anyObject(), anyBoolean(), 757664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh anyBoolean(), anyBoolean())).thenReturn(null); 758664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh 759664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh List<ScanDetail> expectedCarrierNetworks = new ArrayList<>(); 760664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh expectedCarrierNetworks.add( 761664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh new ScanDetail( 762664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh new ScanResult(WifiSsid.createFromAsciiEncoded(CANDIDATE_SSID), 763664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh CANDIDATE_SSID, CANDIDATE_BSSID, 1245, 0, "[EAP][ESS]", -78, 2450, 764664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh 1025, 22, 33, 20, 0, 0, true), null)); 765664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh 766664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh when(mWifiNS.getFilteredScanDetailsForCarrierUnsavedNetworks(any())) 767664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh .thenReturn(expectedCarrierNetworks); 768664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh 769664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh // Set WiFi to disconnected state to trigger PNO scan 770664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh mWifiConnectivityManager.handleConnectionStateChanged( 771664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh WifiConnectivityManager.WIFI_STATE_DISCONNECTED); 772664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh 773664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh verify(mCarrierNetworkNotifier).handleScanResults(expectedCarrierNetworks); 774664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh } 775664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh 776664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh /** 77784f6d8d25d5982b703a74113083e814c9fe5b28fMehdi Alizadeh * {@link CarrierNetworkNotifier} does not handle scan results on network selection if carrier 77884f6d8d25d5982b703a74113083e814c9fe5b28fMehdi Alizadeh * encryption info is not available. 77984f6d8d25d5982b703a74113083e814c9fe5b28fMehdi Alizadeh * 78084f6d8d25d5982b703a74113083e814c9fe5b28fMehdi Alizadeh * Expected behavior: CarrierNetworkNotifier does not handle scan results 78184f6d8d25d5982b703a74113083e814c9fe5b28fMehdi Alizadeh */ 78284f6d8d25d5982b703a74113083e814c9fe5b28fMehdi Alizadeh @Test 78384f6d8d25d5982b703a74113083e814c9fe5b28fMehdi Alizadeh public void whenNoEncryptionInfoAvailable_CarrierNetworkNotifierDoesNotHandleScanResults() { 78484f6d8d25d5982b703a74113083e814c9fe5b28fMehdi Alizadeh // no connection candidate selected 78584f6d8d25d5982b703a74113083e814c9fe5b28fMehdi Alizadeh when(mWifiNS.selectNetwork(anyObject(), anyObject(), anyObject(), anyBoolean(), 78684f6d8d25d5982b703a74113083e814c9fe5b28fMehdi Alizadeh anyBoolean(), anyBoolean())).thenReturn(null); 78784f6d8d25d5982b703a74113083e814c9fe5b28fMehdi Alizadeh 78884f6d8d25d5982b703a74113083e814c9fe5b28fMehdi Alizadeh List<ScanDetail> expectedCarrierNetworks = new ArrayList<>(); 78984f6d8d25d5982b703a74113083e814c9fe5b28fMehdi Alizadeh expectedCarrierNetworks.add( 79084f6d8d25d5982b703a74113083e814c9fe5b28fMehdi Alizadeh new ScanDetail( 79184f6d8d25d5982b703a74113083e814c9fe5b28fMehdi Alizadeh new ScanResult(WifiSsid.createFromAsciiEncoded(CANDIDATE_SSID), 79284f6d8d25d5982b703a74113083e814c9fe5b28fMehdi Alizadeh CANDIDATE_SSID, CANDIDATE_BSSID, 1245, 0, "[EAP][ESS]", -78, 2450, 79384f6d8d25d5982b703a74113083e814c9fe5b28fMehdi Alizadeh 1025, 22, 33, 20, 0, 0, true), null)); 79484f6d8d25d5982b703a74113083e814c9fe5b28fMehdi Alizadeh 79584f6d8d25d5982b703a74113083e814c9fe5b28fMehdi Alizadeh when(mWifiNS.getFilteredScanDetailsForCarrierUnsavedNetworks(any())) 79684f6d8d25d5982b703a74113083e814c9fe5b28fMehdi Alizadeh .thenReturn(expectedCarrierNetworks); 79784f6d8d25d5982b703a74113083e814c9fe5b28fMehdi Alizadeh when(mCarrierNetworkConfig.isCarrierEncryptionInfoAvailable()).thenReturn(false); 79884f6d8d25d5982b703a74113083e814c9fe5b28fMehdi Alizadeh 79984f6d8d25d5982b703a74113083e814c9fe5b28fMehdi Alizadeh // Set WiFi to disconnected state to trigger PNO scan 80084f6d8d25d5982b703a74113083e814c9fe5b28fMehdi Alizadeh mWifiConnectivityManager.handleConnectionStateChanged( 80184f6d8d25d5982b703a74113083e814c9fe5b28fMehdi Alizadeh WifiConnectivityManager.WIFI_STATE_DISCONNECTED); 80284f6d8d25d5982b703a74113083e814c9fe5b28fMehdi Alizadeh 80384f6d8d25d5982b703a74113083e814c9fe5b28fMehdi Alizadeh verify(mCarrierNetworkNotifier, never()).handleScanResults(expectedCarrierNetworks); 80484f6d8d25d5982b703a74113083e814c9fe5b28fMehdi Alizadeh } 80584f6d8d25d5982b703a74113083e814c9fe5b28fMehdi Alizadeh 80684f6d8d25d5982b703a74113083e814c9fe5b28fMehdi Alizadeh /** 807664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh * When wifi is connected, {@link CarrierNetworkNotifier} handles the Wi-Fi connected behavior. 808664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh * 809664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh * Expected behavior: CarrierNetworkNotifier handles connected behavior 810664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh */ 811664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh @Test 812664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh public void wifiConnected_carrierNetworkNotifierHandlesConnection() { 813664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh // Set WiFi to connected state 814664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh mWifiConnectivityManager.handleConnectionStateChanged( 815664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh WifiConnectivityManager.WIFI_STATE_CONNECTED); 816664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh 817664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh verify(mCarrierNetworkNotifier).handleWifiConnected(); 818664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh } 819664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh 820664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh /** 821664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh * When wifi is connected, {@link CarrierNetworkNotifier} handles connection state 822664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh * change. 823664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh * 824664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh * Expected behavior: CarrierNetworkNotifer does not clear pending notification. 825664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh */ 826664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh @Test 827664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh public void wifiDisconnected_carrierNetworkNotifierDoesNotClearPendingNotification() { 828664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh // Set WiFi to disconnected state 829664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh mWifiConnectivityManager.handleConnectionStateChanged( 830664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh WifiConnectivityManager.WIFI_STATE_DISCONNECTED); 831664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh 832664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh verify(mCarrierNetworkNotifier, never()).clearPendingNotification(anyBoolean()); 833664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh } 834664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh 835664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh /** 836664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh * When a Wi-Fi connection attempt ends, {@link CarrierNetworkNotifier} handles the connection 837664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh * failure. A failure code that is not {@link WifiMetrics.ConnectionEvent#FAILURE_NONE} 838664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh * represents a connection failure. 839664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh * 840664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh * Expected behavior: CarrierNetworkNotifier handles connection failure. 841664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh */ 842664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh @Test 843664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh public void wifiConnectionEndsWithFailure_carrierNetworkNotifierHandlesConnectionFailure() { 844664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh mWifiConnectivityManager.handleConnectionAttemptEnded( 845664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh WifiMetrics.ConnectionEvent.FAILURE_CONNECT_NETWORK_FAILED); 846664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh 847664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh verify(mCarrierNetworkNotifier).handleConnectionFailure(); 848664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh } 849664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh 850664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh /** 851664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh * When a Wi-Fi connection attempt ends, {@link CarrierNetworkNotifier} does not handle 852664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh * connection failure after a successful connection. 853664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh * {@link WifiMetrics.ConnectionEvent#FAILURE_NONE} represents a successful connection. 854664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh * 855664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh * Expected behavior: CarrierNetworkNotifier does nothing. 856664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh */ 857664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh @Test 858664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh public void 859664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh wifiConnectionEndsWithSuccess_carrierNetworkNotifierDoesNotHandleConnectionFailure() { 860664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh mWifiConnectivityManager.handleConnectionAttemptEnded( 861664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh WifiMetrics.ConnectionEvent.FAILURE_NONE); 862664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh 863664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh verify(mCarrierNetworkNotifier, never()).handleConnectionFailure(); 864664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh } 865664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh 866664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh /** 867664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh * When Wi-Fi is disabled, clear the pending notification and reset notification repeat delay. 868664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh * 869664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh * Expected behavior: clear pending notification and reset notification repeat delay 870664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh * */ 871664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh @Test 872664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh public void carrierNetworkNotifierClearsPendingNotificationOnWifiDisabled() { 873664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh mWifiConnectivityManager.setWifiEnabled(false); 874664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh 875664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh verify(mCarrierNetworkNotifier).clearPendingNotification(true /* resetRepeatDelay */); 876664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh } 877664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh 878664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh /** 879664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh * Verify that the CarrierNetworkNotifier tracks screen state changes. 880664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh */ 881664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh @Test 882664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh public void carrierNetworkNotifierTracksScreenStateChanges() { 883664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh mWifiConnectivityManager.handleScreenStateChanged(false); 884664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh 885664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh verify(mCarrierNetworkNotifier).handleScreenStateChanged(false); 886664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh 887664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh mWifiConnectivityManager.handleScreenStateChanged(true); 888664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh 889664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh verify(mCarrierNetworkNotifier).handleScreenStateChanged(true); 890664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh } 891664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh 892664a859a1cc81f6c679e7da44768238374e102f1Mehdi Alizadeh /** 893b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan * Verify that scan interval for screen on and wifi disconnected scenario 894b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan * is in the exponential backoff fashion. 895b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan * 896b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan * Expected behavior: WifiConnectivityManager doubles periodic 897b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan * scan interval. 898b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan */ 899b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan @Test 900b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan public void checkPeriodicScanIntervalWhenDisconnected() { 901c2963eb07660a06592c60224279685166390217dRandy Pan long currentTimeStamp = CURRENT_SYSTEM_TIME_MS; 9025de29ec72c54cb73fdc1b59072f66a2627b8764cNingyuan Wang when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp); 903b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan 904b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan // Set screen to ON 905b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan mWifiConnectivityManager.handleScreenStateChanged(true); 906b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan 907c2963eb07660a06592c60224279685166390217dRandy Pan // Wait for MAX_PERIODIC_SCAN_INTERVAL_MS so that any impact triggered 908c2963eb07660a06592c60224279685166390217dRandy Pan // by screen state change can settle 909c2963eb07660a06592c60224279685166390217dRandy Pan currentTimeStamp += WifiConnectivityManager.MAX_PERIODIC_SCAN_INTERVAL_MS; 9105de29ec72c54cb73fdc1b59072f66a2627b8764cNingyuan Wang when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp); 911c2963eb07660a06592c60224279685166390217dRandy Pan 912b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan // Set WiFi to disconnected state to trigger periodic scan 913b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan mWifiConnectivityManager.handleConnectionStateChanged( 914b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan WifiConnectivityManager.WIFI_STATE_DISCONNECTED); 915b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan 916b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan // Get the first periodic scan interval 917b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan long firstIntervalMs = mAlarmManager 918b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan .getTriggerTimeMillis(WifiConnectivityManager.PERIODIC_SCAN_TIMER_TAG) 919b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan - currentTimeStamp; 920b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan assertEquals(firstIntervalMs, WifiConnectivityManager.PERIODIC_SCAN_INTERVAL_MS); 921b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan 922c2963eb07660a06592c60224279685166390217dRandy Pan currentTimeStamp += firstIntervalMs; 9235de29ec72c54cb73fdc1b59072f66a2627b8764cNingyuan Wang when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp); 924c2963eb07660a06592c60224279685166390217dRandy Pan 925b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan // Now fire the first periodic scan alarm timer 926b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan mAlarmManager.dispatch(WifiConnectivityManager.PERIODIC_SCAN_TIMER_TAG); 927b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan mLooper.dispatchAll(); 928b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan 929b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan // Get the second periodic scan interval 930b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan long secondIntervalMs = mAlarmManager 931b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan .getTriggerTimeMillis(WifiConnectivityManager.PERIODIC_SCAN_TIMER_TAG) 932b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan - currentTimeStamp; 933b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan 934b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan // Verify the intervals are exponential back off 935b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan assertEquals(firstIntervalMs * 2, secondIntervalMs); 936b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan 937c2963eb07660a06592c60224279685166390217dRandy Pan currentTimeStamp += secondIntervalMs; 9385de29ec72c54cb73fdc1b59072f66a2627b8764cNingyuan Wang when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp); 939c2963eb07660a06592c60224279685166390217dRandy Pan 940b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan // Make sure we eventually stay at the maximum scan interval. 941b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan long intervalMs = 0; 942b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan for (int i = 0; i < 5; i++) { 943b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan mAlarmManager.dispatch(WifiConnectivityManager.PERIODIC_SCAN_TIMER_TAG); 944b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan mLooper.dispatchAll(); 945b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan intervalMs = mAlarmManager 946b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan .getTriggerTimeMillis(WifiConnectivityManager.PERIODIC_SCAN_TIMER_TAG) 947c2963eb07660a06592c60224279685166390217dRandy Pan - currentTimeStamp; 948c2963eb07660a06592c60224279685166390217dRandy Pan currentTimeStamp += intervalMs; 9495de29ec72c54cb73fdc1b59072f66a2627b8764cNingyuan Wang when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp); 950b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan } 951b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan 952b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan assertEquals(intervalMs, WifiConnectivityManager.MAX_PERIODIC_SCAN_INTERVAL_MS); 953b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan } 954b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan 955b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan /** 956b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan * Verify that scan interval for screen on and wifi connected scenario 957b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan * is in the exponential backoff fashion. 958b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan * 959b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan * Expected behavior: WifiConnectivityManager doubles periodic 960b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan * scan interval. 961b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan */ 962b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan @Test 963b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan public void checkPeriodicScanIntervalWhenConnected() { 964c2963eb07660a06592c60224279685166390217dRandy Pan long currentTimeStamp = CURRENT_SYSTEM_TIME_MS; 9655de29ec72c54cb73fdc1b59072f66a2627b8764cNingyuan Wang when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp); 966b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan 967b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan // Set screen to ON 968b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan mWifiConnectivityManager.handleScreenStateChanged(true); 969b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan 970c2963eb07660a06592c60224279685166390217dRandy Pan // Wait for MAX_PERIODIC_SCAN_INTERVAL_MS so that any impact triggered 971c2963eb07660a06592c60224279685166390217dRandy Pan // by screen state change can settle 972c2963eb07660a06592c60224279685166390217dRandy Pan currentTimeStamp += WifiConnectivityManager.MAX_PERIODIC_SCAN_INTERVAL_MS; 9735de29ec72c54cb73fdc1b59072f66a2627b8764cNingyuan Wang when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp); 974c2963eb07660a06592c60224279685166390217dRandy Pan 975b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan // Set WiFi to connected state to trigger periodic scan 976b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan mWifiConnectivityManager.handleConnectionStateChanged( 977b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan WifiConnectivityManager.WIFI_STATE_CONNECTED); 978b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan 979b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan // Get the first periodic scan interval 980b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan long firstIntervalMs = mAlarmManager 981b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan .getTriggerTimeMillis(WifiConnectivityManager.PERIODIC_SCAN_TIMER_TAG) 982b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan - currentTimeStamp; 983b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan assertEquals(firstIntervalMs, WifiConnectivityManager.PERIODIC_SCAN_INTERVAL_MS); 984b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan 985c2963eb07660a06592c60224279685166390217dRandy Pan currentTimeStamp += firstIntervalMs; 9865de29ec72c54cb73fdc1b59072f66a2627b8764cNingyuan Wang when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp); 987c2963eb07660a06592c60224279685166390217dRandy Pan 988b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan // Now fire the first periodic scan alarm timer 989b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan mAlarmManager.dispatch(WifiConnectivityManager.PERIODIC_SCAN_TIMER_TAG); 990b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan mLooper.dispatchAll(); 991b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan 992b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan // Get the second periodic scan interval 993b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan long secondIntervalMs = mAlarmManager 994b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan .getTriggerTimeMillis(WifiConnectivityManager.PERIODIC_SCAN_TIMER_TAG) 995b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan - currentTimeStamp; 996b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan 997b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan // Verify the intervals are exponential back off 998b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan assertEquals(firstIntervalMs * 2, secondIntervalMs); 999b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan 1000c2963eb07660a06592c60224279685166390217dRandy Pan currentTimeStamp += secondIntervalMs; 10015de29ec72c54cb73fdc1b59072f66a2627b8764cNingyuan Wang when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp); 1002c2963eb07660a06592c60224279685166390217dRandy Pan 1003b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan // Make sure we eventually stay at the maximum scan interval. 1004b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan long intervalMs = 0; 1005b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan for (int i = 0; i < 5; i++) { 1006b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan mAlarmManager.dispatch(WifiConnectivityManager.PERIODIC_SCAN_TIMER_TAG); 1007b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan mLooper.dispatchAll(); 1008b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan intervalMs = mAlarmManager 1009b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan .getTriggerTimeMillis(WifiConnectivityManager.PERIODIC_SCAN_TIMER_TAG) 1010c2963eb07660a06592c60224279685166390217dRandy Pan - currentTimeStamp; 1011c2963eb07660a06592c60224279685166390217dRandy Pan currentTimeStamp += intervalMs; 10125de29ec72c54cb73fdc1b59072f66a2627b8764cNingyuan Wang when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp); 1013b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan } 1014b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan 1015b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan assertEquals(intervalMs, WifiConnectivityManager.MAX_PERIODIC_SCAN_INTERVAL_MS); 1016b32b649c815b0b50fd0127d9d4a4563c54a536fbRandy Pan } 1017fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius 1018fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius /** 1019915a3782e33684562dff8a0897d1446227301b75Randy Pan * When screen on trigger a disconnected state change event then a connected state 1020915a3782e33684562dff8a0897d1446227301b75Randy Pan * change event back to back to verify that the minium scan interval is enforced. 1021c2963eb07660a06592c60224279685166390217dRandy Pan * 1022c2963eb07660a06592c60224279685166390217dRandy Pan * Expected behavior: WifiConnectivityManager start the second periodic single 1023c2963eb07660a06592c60224279685166390217dRandy Pan * scan PERIODIC_SCAN_INTERVAL_MS after the first one. 1024c2963eb07660a06592c60224279685166390217dRandy Pan */ 1025c2963eb07660a06592c60224279685166390217dRandy Pan @Test 1026915a3782e33684562dff8a0897d1446227301b75Randy Pan public void checkMinimumPeriodicScanIntervalWhenScreenOnAndConnected() { 1027c2963eb07660a06592c60224279685166390217dRandy Pan long currentTimeStamp = CURRENT_SYSTEM_TIME_MS; 10285de29ec72c54cb73fdc1b59072f66a2627b8764cNingyuan Wang when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp); 1029c2963eb07660a06592c60224279685166390217dRandy Pan 1030c2963eb07660a06592c60224279685166390217dRandy Pan // Set screen to ON 1031c2963eb07660a06592c60224279685166390217dRandy Pan mWifiConnectivityManager.handleScreenStateChanged(true); 1032c2963eb07660a06592c60224279685166390217dRandy Pan 1033c2963eb07660a06592c60224279685166390217dRandy Pan // Wait for MAX_PERIODIC_SCAN_INTERVAL_MS so that any impact triggered 1034c2963eb07660a06592c60224279685166390217dRandy Pan // by screen state change can settle 1035c2963eb07660a06592c60224279685166390217dRandy Pan currentTimeStamp += WifiConnectivityManager.MAX_PERIODIC_SCAN_INTERVAL_MS; 1036915a3782e33684562dff8a0897d1446227301b75Randy Pan long scanForDisconnectedTimeStamp = currentTimeStamp; 1037915a3782e33684562dff8a0897d1446227301b75Randy Pan when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp); 1038915a3782e33684562dff8a0897d1446227301b75Randy Pan 1039915a3782e33684562dff8a0897d1446227301b75Randy Pan // Set WiFi to disconnected state which triggers a scan immediately 1040915a3782e33684562dff8a0897d1446227301b75Randy Pan mWifiConnectivityManager.handleConnectionStateChanged( 1041915a3782e33684562dff8a0897d1446227301b75Randy Pan WifiConnectivityManager.WIFI_STATE_DISCONNECTED); 1042915a3782e33684562dff8a0897d1446227301b75Randy Pan verify(mWifiScanner, times(1)).startScan(anyObject(), anyObject(), anyObject()); 1043915a3782e33684562dff8a0897d1446227301b75Randy Pan 1044915a3782e33684562dff8a0897d1446227301b75Randy Pan // Set up time stamp for when entering CONNECTED state 1045915a3782e33684562dff8a0897d1446227301b75Randy Pan currentTimeStamp += 2000; 1046915a3782e33684562dff8a0897d1446227301b75Randy Pan when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp); 1047915a3782e33684562dff8a0897d1446227301b75Randy Pan 1048915a3782e33684562dff8a0897d1446227301b75Randy Pan // Set WiFi to connected state to trigger its periodic scan 1049915a3782e33684562dff8a0897d1446227301b75Randy Pan mWifiConnectivityManager.handleConnectionStateChanged( 1050915a3782e33684562dff8a0897d1446227301b75Randy Pan WifiConnectivityManager.WIFI_STATE_CONNECTED); 1051915a3782e33684562dff8a0897d1446227301b75Randy Pan 1052915a3782e33684562dff8a0897d1446227301b75Randy Pan // The very first scan triggered for connected state is actually via the alarm timer 1053915a3782e33684562dff8a0897d1446227301b75Randy Pan // and it obeys the minimum scan interval 1054915a3782e33684562dff8a0897d1446227301b75Randy Pan long firstScanForConnectedTimeStamp = mAlarmManager 1055915a3782e33684562dff8a0897d1446227301b75Randy Pan .getTriggerTimeMillis(WifiConnectivityManager.PERIODIC_SCAN_TIMER_TAG); 1056915a3782e33684562dff8a0897d1446227301b75Randy Pan 1057915a3782e33684562dff8a0897d1446227301b75Randy Pan // Verify that the first scan for connected state is scheduled PERIODIC_SCAN_INTERVAL_MS 1058915a3782e33684562dff8a0897d1446227301b75Randy Pan // after the scan for disconnected state 1059915a3782e33684562dff8a0897d1446227301b75Randy Pan assertEquals(firstScanForConnectedTimeStamp, scanForDisconnectedTimeStamp 1060915a3782e33684562dff8a0897d1446227301b75Randy Pan + WifiConnectivityManager.PERIODIC_SCAN_INTERVAL_MS); 1061915a3782e33684562dff8a0897d1446227301b75Randy Pan } 1062915a3782e33684562dff8a0897d1446227301b75Randy Pan 1063915a3782e33684562dff8a0897d1446227301b75Randy Pan /** 1064915a3782e33684562dff8a0897d1446227301b75Randy Pan * When screen on trigger a connected state change event then a disconnected state 1065915a3782e33684562dff8a0897d1446227301b75Randy Pan * change event back to back to verify that a scan is fired immediately for the 1066915a3782e33684562dff8a0897d1446227301b75Randy Pan * disconnected state change event. 1067915a3782e33684562dff8a0897d1446227301b75Randy Pan * 1068915a3782e33684562dff8a0897d1446227301b75Randy Pan * Expected behavior: WifiConnectivityManager directly starts the periodic immediately 1069915a3782e33684562dff8a0897d1446227301b75Randy Pan * for the disconnected state change event. The second scan for disconnected state is 1070915a3782e33684562dff8a0897d1446227301b75Randy Pan * via alarm timer. 1071915a3782e33684562dff8a0897d1446227301b75Randy Pan */ 1072915a3782e33684562dff8a0897d1446227301b75Randy Pan @Test 1073915a3782e33684562dff8a0897d1446227301b75Randy Pan public void scanImmediatelyWhenScreenOnAndDisconnected() { 1074915a3782e33684562dff8a0897d1446227301b75Randy Pan long currentTimeStamp = CURRENT_SYSTEM_TIME_MS; 1075915a3782e33684562dff8a0897d1446227301b75Randy Pan when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp); 1076915a3782e33684562dff8a0897d1446227301b75Randy Pan 1077915a3782e33684562dff8a0897d1446227301b75Randy Pan // Set screen to ON 1078915a3782e33684562dff8a0897d1446227301b75Randy Pan mWifiConnectivityManager.handleScreenStateChanged(true); 1079915a3782e33684562dff8a0897d1446227301b75Randy Pan 1080915a3782e33684562dff8a0897d1446227301b75Randy Pan // Wait for MAX_PERIODIC_SCAN_INTERVAL_MS so that any impact triggered 1081915a3782e33684562dff8a0897d1446227301b75Randy Pan // by screen state change can settle 1082915a3782e33684562dff8a0897d1446227301b75Randy Pan currentTimeStamp += WifiConnectivityManager.MAX_PERIODIC_SCAN_INTERVAL_MS; 1083915a3782e33684562dff8a0897d1446227301b75Randy Pan long scanForConnectedTimeStamp = currentTimeStamp; 10845de29ec72c54cb73fdc1b59072f66a2627b8764cNingyuan Wang when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp); 1085c2963eb07660a06592c60224279685166390217dRandy Pan 1086c2963eb07660a06592c60224279685166390217dRandy Pan // Set WiFi to connected state to trigger the periodic scan 1087c2963eb07660a06592c60224279685166390217dRandy Pan mWifiConnectivityManager.handleConnectionStateChanged( 1088c2963eb07660a06592c60224279685166390217dRandy Pan WifiConnectivityManager.WIFI_STATE_CONNECTED); 1089915a3782e33684562dff8a0897d1446227301b75Randy Pan verify(mWifiScanner, times(1)).startScan(anyObject(), anyObject(), anyObject()); 1090c2963eb07660a06592c60224279685166390217dRandy Pan 1091915a3782e33684562dff8a0897d1446227301b75Randy Pan // Set up the time stamp for when entering DISCONNECTED state 1092c2963eb07660a06592c60224279685166390217dRandy Pan currentTimeStamp += 2000; 1093915a3782e33684562dff8a0897d1446227301b75Randy Pan long enteringDisconnectedStateTimeStamp = currentTimeStamp; 10945de29ec72c54cb73fdc1b59072f66a2627b8764cNingyuan Wang when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp); 1095c2963eb07660a06592c60224279685166390217dRandy Pan 1096915a3782e33684562dff8a0897d1446227301b75Randy Pan // Set WiFi to disconnected state to trigger its periodic scan 1097c2963eb07660a06592c60224279685166390217dRandy Pan mWifiConnectivityManager.handleConnectionStateChanged( 1098c2963eb07660a06592c60224279685166390217dRandy Pan WifiConnectivityManager.WIFI_STATE_DISCONNECTED); 1099c2963eb07660a06592c60224279685166390217dRandy Pan 1100915a3782e33684562dff8a0897d1446227301b75Randy Pan // Verify the very first scan for DISCONNECTED state is fired immediately 1101915a3782e33684562dff8a0897d1446227301b75Randy Pan verify(mWifiScanner, times(2)).startScan(anyObject(), anyObject(), anyObject()); 1102915a3782e33684562dff8a0897d1446227301b75Randy Pan long secondScanForDisconnectedTimeStamp = mAlarmManager 1103915a3782e33684562dff8a0897d1446227301b75Randy Pan .getTriggerTimeMillis(WifiConnectivityManager.PERIODIC_SCAN_TIMER_TAG); 1104c2963eb07660a06592c60224279685166390217dRandy Pan 1105915a3782e33684562dff8a0897d1446227301b75Randy Pan // Verify that the second scan is scheduled PERIODIC_SCAN_INTERVAL_MS after 1106915a3782e33684562dff8a0897d1446227301b75Randy Pan // entering DISCONNECTED state. 1107915a3782e33684562dff8a0897d1446227301b75Randy Pan assertEquals(secondScanForDisconnectedTimeStamp, enteringDisconnectedStateTimeStamp 1108915a3782e33684562dff8a0897d1446227301b75Randy Pan + WifiConnectivityManager.PERIODIC_SCAN_INTERVAL_MS); 1109c2963eb07660a06592c60224279685166390217dRandy Pan } 1110c2963eb07660a06592c60224279685166390217dRandy Pan 1111c2963eb07660a06592c60224279685166390217dRandy Pan /** 1112016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan * When screen on trigger a connection state change event and a forced connectivity 1113016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan * scan event back to back to verify that the minimum scan interval is not applied 1114016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan * in this scenario. 1115016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan * 1116016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan * Expected behavior: WifiConnectivityManager starts the second periodic single 1117016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan * scan immediately. 1118016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan */ 1119016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan @Test 1120016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan public void checkMinimumPeriodicScanIntervalNotEnforced() { 1121016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan long currentTimeStamp = CURRENT_SYSTEM_TIME_MS; 11225967a15d36c76ba1aaeb89ce8bd66bb4bccfe998Paul Stewart when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp); 1123016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan 1124016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan // Set screen to ON 1125016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan mWifiConnectivityManager.handleScreenStateChanged(true); 1126016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan 1127016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan // Wait for MAX_PERIODIC_SCAN_INTERVAL_MS so that any impact triggered 1128016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan // by screen state change can settle 1129016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan currentTimeStamp += WifiConnectivityManager.MAX_PERIODIC_SCAN_INTERVAL_MS; 1130016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan long firstScanTimeStamp = currentTimeStamp; 11315967a15d36c76ba1aaeb89ce8bd66bb4bccfe998Paul Stewart when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp); 1132016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan 1133016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan // Set WiFi to connected state to trigger the periodic scan 1134016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan mWifiConnectivityManager.handleConnectionStateChanged( 1135016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan WifiConnectivityManager.WIFI_STATE_CONNECTED); 1136016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan 1137016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan // Set the second scan attempt time stamp 1138016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan currentTimeStamp += 2000; 11395967a15d36c76ba1aaeb89ce8bd66bb4bccfe998Paul Stewart when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp); 1140016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan 1141cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan // Allow untrusted networks so WifiConnectivityManager starts a periodic scan 1142cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan // immediately. 1143cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan mWifiConnectivityManager.setUntrustedConnectionAllowed(true); 1144016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan 1145016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan // Get the second periodic scan actual time stamp. Note, this scan is not 1146016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan // started from the AlarmManager. 1147016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan long secondScanTimeStamp = mWifiConnectivityManager.getLastPeriodicSingleScanTimeStamp(); 1148016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan 1149016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan // Verify that the second scan is fired immediately 1150016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan assertEquals(secondScanTimeStamp, currentTimeStamp); 1151016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan } 1152016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan 1153016ca1ae5e33eb9529ae10c2510a56fa5c7fec4dRandy Pan /** 1154fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius * Verify that we perform full band scan when the currently connected network's tx/rx success 1155fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius * rate is low. 1156fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius * 1157fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius * Expected behavior: WifiConnectivityManager does full band scan. 1158fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius */ 1159fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius @Test 1160fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius public void checkSingleScanSettingsWhenConnectedWithLowDataRate() { 1161fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius mWifiInfo.txSuccessRate = 0; 1162fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius mWifiInfo.rxSuccessRate = 0; 1163fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius 1164fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius final HashSet<Integer> channelList = new HashSet<>(); 1165fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius channelList.add(1); 1166fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius channelList.add(2); 1167fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius channelList.add(3); 1168fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius 1169fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius when(mWifiStateMachine.getCurrentWifiConfiguration()) 1170fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius .thenReturn(new WifiConfiguration()); 11713697d5ed11fea02e6369336d54e19145ba76425fRandy Pan when(mWifiConfigManager.fetchChannelSetForNetworkForPartialScan(anyInt(), anyLong(), 11723697d5ed11fea02e6369336d54e19145ba76425fRandy Pan anyInt())).thenReturn(channelList); 1173fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius 1174fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius doAnswer(new AnswerWithArguments() { 1175fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius public void answer(ScanSettings settings, ScanListener listener, 1176fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius WorkSource workSource) throws Exception { 1177026cb51837e4cf3aea30b903320b992a3f5d0d7bChristopher Wiley assertEquals(settings.band, WifiScanner.WIFI_BAND_BOTH_WITH_DFS); 1178fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius assertNull(settings.channels); 1179fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius }}).when(mWifiScanner).startScan(anyObject(), anyObject(), anyObject()); 1180fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius 1181fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius // Set screen to ON 1182fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius mWifiConnectivityManager.handleScreenStateChanged(true); 1183fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius 1184fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius // Set WiFi to connected state to trigger periodic scan 1185fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius mWifiConnectivityManager.handleConnectionStateChanged( 1186fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius WifiConnectivityManager.WIFI_STATE_CONNECTED); 1187fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius 1188fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius verify(mWifiScanner).startScan(anyObject(), anyObject(), anyObject()); 1189fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius } 1190fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius 1191fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius /** 1192fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius * Verify that we perform partial scan when the currently connected network's tx/rx success 1193fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius * rate is high and when the currently connected network is present in scan 1194fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius * cache in WifiConfigManager. 119554e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang * WifiConnectivityManager does partial scan only when firmware roaming is not supported. 1196fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius * 119754e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang * Expected behavior: WifiConnectivityManager does partial scan. 1198fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius */ 1199fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius @Test 120054e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang public void checkPartialScanRequestedWithHighDataRateWithoutFwRoaming() { 1201e4606e0f9532d250a1e06e8aba5fb48556225773Randy Pan mWifiInfo.txSuccessRate = mFullScanMaxTxPacketRate * 2; 1202e4606e0f9532d250a1e06e8aba5fb48556225773Randy Pan mWifiInfo.rxSuccessRate = mFullScanMaxRxPacketRate * 2; 1203fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius 1204fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius final HashSet<Integer> channelList = new HashSet<>(); 1205fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius channelList.add(1); 1206fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius channelList.add(2); 1207fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius channelList.add(3); 1208fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius 1209fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius when(mWifiStateMachine.getCurrentWifiConfiguration()) 1210fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius .thenReturn(new WifiConfiguration()); 12113697d5ed11fea02e6369336d54e19145ba76425fRandy Pan when(mWifiConfigManager.fetchChannelSetForNetworkForPartialScan(anyInt(), anyLong(), 121260ecc292c27e34df1a9414da0d6482cce718efbcRandy Pan anyInt())).thenReturn(channelList); 121354e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang when(mWifiConnectivityHelper.isFirmwareRoamingSupported()).thenReturn(false); 1214fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius 1215fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius doAnswer(new AnswerWithArguments() { 1216fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius public void answer(ScanSettings settings, ScanListener listener, 1217fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius WorkSource workSource) throws Exception { 1218fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius assertEquals(settings.band, WifiScanner.WIFI_BAND_UNSPECIFIED); 1219fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius assertEquals(settings.channels.length, channelList.size()); 1220fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius for (int chanIdx = 0; chanIdx < settings.channels.length; chanIdx++) { 1221fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius assertTrue(channelList.contains(settings.channels[chanIdx].frequency)); 1222fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius } 1223fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius }}).when(mWifiScanner).startScan(anyObject(), anyObject(), anyObject()); 1224fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius 1225fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius // Set screen to ON 1226fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius mWifiConnectivityManager.handleScreenStateChanged(true); 1227fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius 1228fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius // Set WiFi to connected state to trigger periodic scan 1229fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius mWifiConnectivityManager.handleConnectionStateChanged( 1230fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius WifiConnectivityManager.WIFI_STATE_CONNECTED); 1231fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius 1232fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius verify(mWifiScanner).startScan(anyObject(), anyObject(), anyObject()); 1233fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius } 1234fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius 1235fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius /** 123654e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang * Verify that we skip the partial scan when: 123754e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang * 1. The currently connected network's tx/rx success rate is high. 123854e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang * 2. When the currently connected network is present in scan 123954e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang * cache in WifiConfigManager. 124054e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang * 3. When firmware roaming is supported. 124154e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang * Expected behavior: WifiConnectivityManager does no scan, but periodic scans 124254e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang * are still scheduled. 124354e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang */ 124454e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang @Test 124554e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang public void checkPartialScanSkippedWithHighDataRateWithFwRoaming() { 124654e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang mWifiInfo.txSuccessRate = mFullScanMaxTxPacketRate * 2; 124754e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang mWifiInfo.rxSuccessRate = mFullScanMaxRxPacketRate * 2; 124854e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang 124954e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang long currentTimeStamp = CURRENT_SYSTEM_TIME_MS; 125054e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang when(mClock.getElapsedSinceBootMillis()).thenReturn(currentTimeStamp); 125154e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang 125254e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang final HashSet<Integer> channelList = new HashSet<>(); 125354e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang channelList.add(1); 125454e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang channelList.add(2); 125554e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang channelList.add(3); 125654e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang 125754e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang when(mWifiStateMachine.getCurrentWifiConfiguration()) 125854e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang .thenReturn(new WifiConfiguration()); 125954e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang when(mWifiConfigManager.fetchChannelSetForNetworkForPartialScan(anyInt(), anyLong(), 126054e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang anyInt())).thenReturn(channelList); 126154e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang // No scan will be requested when firmware roaming control is not supported. 126254e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang when(mWifiConnectivityHelper.isFirmwareRoamingSupported()).thenReturn(true); 126354e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang 126454e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang // Set screen to ON 126554e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang mWifiConnectivityManager.handleScreenStateChanged(true); 126654e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang 126754e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang // Set WiFi to connected state to trigger periodic scan 126854e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang mWifiConnectivityManager.handleConnectionStateChanged( 126954e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang WifiConnectivityManager.WIFI_STATE_CONNECTED); 127054e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang 127154e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang verify(mWifiScanner, never()).startScan(anyObject(), anyObject(), anyObject()); 127254e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang 127354e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang // Get the first periodic scan interval to check that we are still scheduling 127454e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang // periodic scans. 127554e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang long firstIntervalMs = mAlarmManager 127654e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang .getTriggerTimeMillis(WifiConnectivityManager.PERIODIC_SCAN_TIMER_TAG) 127754e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang - currentTimeStamp; 127854e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang assertEquals(firstIntervalMs, WifiConnectivityManager.PERIODIC_SCAN_INTERVAL_MS); 127954e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang } 128054e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang 128154e1f042c35507cefb8bb7b88c5d1dbd6f45aa97Ningyuan Wang /** 1282fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius * Verify that we fall back to full band scan when the currently connected network's tx/rx 1283fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius * success rate is high and the currently connected network is not present in scan cache in 1284fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius * WifiConfigManager. This is simulated by returning an empty hashset in |makeChannelList|. 1285fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius * 1286fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius * Expected behavior: WifiConnectivityManager does full band scan. 1287fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius */ 1288fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius @Test 1289fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius public void checkSingleScanSettingsWhenConnectedWithHighDataRateNotInCache() { 1290e4606e0f9532d250a1e06e8aba5fb48556225773Randy Pan mWifiInfo.txSuccessRate = mFullScanMaxTxPacketRate * 2; 1291e4606e0f9532d250a1e06e8aba5fb48556225773Randy Pan mWifiInfo.rxSuccessRate = mFullScanMaxRxPacketRate * 2; 1292fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius 1293fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius final HashSet<Integer> channelList = new HashSet<>(); 1294fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius 1295fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius when(mWifiStateMachine.getCurrentWifiConfiguration()) 1296fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius .thenReturn(new WifiConfiguration()); 12973697d5ed11fea02e6369336d54e19145ba76425fRandy Pan when(mWifiConfigManager.fetchChannelSetForNetworkForPartialScan(anyInt(), anyLong(), 129860ecc292c27e34df1a9414da0d6482cce718efbcRandy Pan anyInt())).thenReturn(channelList); 1299fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius 1300fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius doAnswer(new AnswerWithArguments() { 1301fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius public void answer(ScanSettings settings, ScanListener listener, 1302fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius WorkSource workSource) throws Exception { 1303026cb51837e4cf3aea30b903320b992a3f5d0d7bChristopher Wiley assertEquals(settings.band, WifiScanner.WIFI_BAND_BOTH_WITH_DFS); 1304fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius assertNull(settings.channels); 1305fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius }}).when(mWifiScanner).startScan(anyObject(), anyObject(), anyObject()); 1306fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius 1307fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius // Set screen to ON 1308fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius mWifiConnectivityManager.handleScreenStateChanged(true); 1309fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius 1310fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius // Set WiFi to connected state to trigger periodic scan 1311fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius mWifiConnectivityManager.handleConnectionStateChanged( 1312fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius WifiConnectivityManager.WIFI_STATE_CONNECTED); 1313fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius 1314fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius verify(mWifiScanner).startScan(anyObject(), anyObject(), anyObject()); 1315fb196453c07daad5e525520cecad84cec5d89fb7Roshan Pius } 1316de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan 1317de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan /** 1318de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan * Verify that we retry connectivity scan up to MAX_SCAN_RESTART_ALLOWED times 1319de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan * when Wifi somehow gets into a bad state and fails to scan. 1320de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan * 1321de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan * Expected behavior: WifiConnectivityManager schedules connectivity scan 1322de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan * MAX_SCAN_RESTART_ALLOWED times. 1323de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan */ 1324de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan @Test 1325de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan public void checkMaximumScanRetry() { 1326de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan // Set screen to ON 1327de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan mWifiConnectivityManager.handleScreenStateChanged(true); 1328de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan 1329de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan doAnswer(new AnswerWithArguments() { 1330de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan public void answer(ScanSettings settings, ScanListener listener, 1331de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan WorkSource workSource) throws Exception { 1332de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan listener.onFailure(-1, "ScanFailure"); 1333de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan }}).when(mWifiScanner).startScan(anyObject(), anyObject(), anyObject()); 1334de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan 1335de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan // Set WiFi to disconnected state to trigger the single scan based periodic scan 1336de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan mWifiConnectivityManager.handleConnectionStateChanged( 1337de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan WifiConnectivityManager.WIFI_STATE_DISCONNECTED); 1338de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan 1339de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan // Fire the alarm timer 2x timers 1340de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan for (int i = 0; i < (WifiConnectivityManager.MAX_SCAN_RESTART_ALLOWED * 2); i++) { 1341de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan mAlarmManager.dispatch(WifiConnectivityManager.RESTART_SINGLE_SCAN_TIMER_TAG); 1342de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan mLooper.dispatchAll(); 1343de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan } 1344de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan 1345de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan // Verify that the connectivity scan has been retried for MAX_SCAN_RESTART_ALLOWED 1346de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan // times. Note, WifiScanner.startScan() is invoked MAX_SCAN_RESTART_ALLOWED + 1 times. 1347de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan // The very first scan is the initial one, and the other MAX_SCAN_RESTART_ALLOWED 1348de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan // are the retrial ones. 1349de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan verify(mWifiScanner, times(WifiConnectivityManager.MAX_SCAN_RESTART_ALLOWED + 1)).startScan( 1350de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan anyObject(), anyObject(), anyObject()); 1351de5fadf2e5c7bb769705c830efb04133b1e0219dRandy Pan } 1352cb26f07ae9c558f8c6136c951a7f633d0ccfe79fRandy Pan 1353cb26f07ae9c558f8c6136c951a7f633d0ccfe79fRandy Pan /** 1354cb26f07ae9c558f8c6136c951a7f633d0ccfe79fRandy Pan * Listen to scan results not requested by WifiConnectivityManager and 1355cb26f07ae9c558f8c6136c951a7f633d0ccfe79fRandy Pan * act on them. 1356cb26f07ae9c558f8c6136c951a7f633d0ccfe79fRandy Pan * 1357cb26f07ae9c558f8c6136c951a7f633d0ccfe79fRandy Pan * Expected behavior: WifiConnectivityManager calls 1358fe993ca46449a8aab3f7f55e2132456064bcee94Roshan Pius * WifiStateMachine.startConnectToNetwork() with the 1359cb26f07ae9c558f8c6136c951a7f633d0ccfe79fRandy Pan * expected candidate network ID and BSSID. 1360cb26f07ae9c558f8c6136c951a7f633d0ccfe79fRandy Pan */ 1361cb26f07ae9c558f8c6136c951a7f633d0ccfe79fRandy Pan @Test 1362cb26f07ae9c558f8c6136c951a7f633d0ccfe79fRandy Pan public void listenToAllSingleScanResults() { 1363cb26f07ae9c558f8c6136c951a7f633d0ccfe79fRandy Pan ScanSettings settings = new ScanSettings(); 1364cb26f07ae9c558f8c6136c951a7f633d0ccfe79fRandy Pan ScanListener scanListener = mock(ScanListener.class); 1365cb26f07ae9c558f8c6136c951a7f633d0ccfe79fRandy Pan 1366cb26f07ae9c558f8c6136c951a7f633d0ccfe79fRandy Pan // Request a single scan outside of WifiConnectivityManager. 1367cb26f07ae9c558f8c6136c951a7f633d0ccfe79fRandy Pan mWifiScanner.startScan(settings, scanListener, WIFI_WORK_SOURCE); 1368cb26f07ae9c558f8c6136c951a7f633d0ccfe79fRandy Pan 1369cb26f07ae9c558f8c6136c951a7f633d0ccfe79fRandy Pan // Verify that WCM receives the scan results and initiates a connection 1370cb26f07ae9c558f8c6136c951a7f633d0ccfe79fRandy Pan // to the network. 13719686c96d8d0c0bc21ca069e244e2570c169724e1Lorenzo Colitti verify(mWifiStateMachine).startConnectToNetwork( 13729686c96d8d0c0bc21ca069e244e2570c169724e1Lorenzo Colitti CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); 1373cb26f07ae9c558f8c6136c951a7f633d0ccfe79fRandy Pan } 1374cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan 1375cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan /** 1376cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan * Verify that a forced connectivity scan waits for full band scan 1377cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan * results. 1378cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan * 1379cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan * Expected behavior: WifiConnectivityManager doesn't invoke 1380cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan * WifiStateMachine.startConnectToNetwork() when full band scan 1381cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan * results are not available. 1382cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan */ 1383cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan @Test 1384cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan public void waitForFullBandScanResults() { 1385cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan // Set WiFi to connected state. 1386cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan mWifiConnectivityManager.handleConnectionStateChanged( 1387cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan WifiConnectivityManager.WIFI_STATE_CONNECTED); 1388cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan 1389cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan // Set up as partial scan results. 1390cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan when(mScanData.isAllChannelsScanned()).thenReturn(false); 1391cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan 1392cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan // Force a connectivity scan which enables WifiConnectivityManager 1393cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan // to wait for full band scan results. 1394470817b13e56d915805729ab4f51075f3fa2ec15Ningyuan Wang mWifiConnectivityManager.forceConnectivityScan(WIFI_WORK_SOURCE); 1395cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan 1396cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan // No roaming because no full band scan results. 1397cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan verify(mWifiStateMachine, times(0)).startConnectToNetwork( 13989686c96d8d0c0bc21ca069e244e2570c169724e1Lorenzo Colitti CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); 1399cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan 1400cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan // Set up as full band scan results. 1401cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan when(mScanData.isAllChannelsScanned()).thenReturn(true); 1402cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan 1403cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan // Force a connectivity scan which enables WifiConnectivityManager 1404cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan // to wait for full band scan results. 1405470817b13e56d915805729ab4f51075f3fa2ec15Ningyuan Wang mWifiConnectivityManager.forceConnectivityScan(WIFI_WORK_SOURCE); 1406cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan 1407cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan // Roaming attempt because full band scan results are available. 14089686c96d8d0c0bc21ca069e244e2570c169724e1Lorenzo Colitti verify(mWifiStateMachine).startConnectToNetwork( 14099686c96d8d0c0bc21ca069e244e2570c169724e1Lorenzo Colitti CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); 1410cf69e50f5344898a0a89f838f63322a2df01bf5dRandy Pan } 1411167b90b5e002698378728a54a417a08c317d29dcRandy Pan 1412167b90b5e002698378728a54a417a08c317d29dcRandy Pan /** 1413167b90b5e002698378728a54a417a08c317d29dcRandy Pan * Verify the BSSID blacklist implementation. 1414167b90b5e002698378728a54a417a08c317d29dcRandy Pan * 1415167b90b5e002698378728a54a417a08c317d29dcRandy Pan * Expected behavior: A BSSID gets blacklisted after being disabled 1416ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan * for 3 times, and becomes available after being re-enabled. Firmware 1417ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan * controlled roaming is supported, its roaming configuration needs to be 1418ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan * updated as well. 1419167b90b5e002698378728a54a417a08c317d29dcRandy Pan */ 1420167b90b5e002698378728a54a417a08c317d29dcRandy Pan @Test 1421167b90b5e002698378728a54a417a08c317d29dcRandy Pan public void blacklistAndReenableBssid() { 1422167b90b5e002698378728a54a417a08c317d29dcRandy Pan String bssid = "6c:f3:7f:ae:8c:f3"; 1423167b90b5e002698378728a54a417a08c317d29dcRandy Pan 1424ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan when(mWifiConnectivityHelper.isFirmwareRoamingSupported()).thenReturn(true); 1425167b90b5e002698378728a54a417a08c317d29dcRandy Pan // Verify that a BSSID gets blacklisted only after being disabled 1426167b90b5e002698378728a54a417a08c317d29dcRandy Pan // for BSSID_BLACKLIST_THRESHOLD times for reasons other than 1427167b90b5e002698378728a54a417a08c317d29dcRandy Pan // REASON_CODE_AP_UNABLE_TO_HANDLE_NEW_STA. 1428167b90b5e002698378728a54a417a08c317d29dcRandy Pan for (int i = 0; i < WifiConnectivityManager.BSSID_BLACKLIST_THRESHOLD; i++) { 1429167b90b5e002698378728a54a417a08c317d29dcRandy Pan assertFalse(mWifiConnectivityManager.isBssidDisabled(bssid)); 1430167b90b5e002698378728a54a417a08c317d29dcRandy Pan mWifiConnectivityManager.trackBssid(bssid, false, 1); 1431167b90b5e002698378728a54a417a08c317d29dcRandy Pan } 1432167b90b5e002698378728a54a417a08c317d29dcRandy Pan 1433ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan // Verify the BSSID is now blacklisted. 1434167b90b5e002698378728a54a417a08c317d29dcRandy Pan assertTrue(mWifiConnectivityManager.isBssidDisabled(bssid)); 1435ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan // Verify the BSSID gets sent to firmware. 1436ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan verify(mWifiConnectivityHelper).setFirmwareRoamingConfiguration( 1437ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan mBssidBlacklistCaptor.capture(), mSsidWhitelistCaptor.capture()); 1438ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan assertTrue(mBssidBlacklistCaptor.getValue().contains(bssid)); 1439ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan assertTrue(mSsidWhitelistCaptor.getValue().isEmpty()); 1440167b90b5e002698378728a54a417a08c317d29dcRandy Pan 1441167b90b5e002698378728a54a417a08c317d29dcRandy Pan // Re-enable the bssid. 1442167b90b5e002698378728a54a417a08c317d29dcRandy Pan mWifiConnectivityManager.trackBssid(bssid, true, 1); 1443167b90b5e002698378728a54a417a08c317d29dcRandy Pan 1444ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan // Verify the bssid is no longer blacklisted. 1445167b90b5e002698378728a54a417a08c317d29dcRandy Pan assertFalse(mWifiConnectivityManager.isBssidDisabled(bssid)); 1446ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan // Verify the BSSID gets cleared from firmware. 1447ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan verify(mWifiConnectivityHelper, times(2)).setFirmwareRoamingConfiguration( 1448ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan mBssidBlacklistCaptor.capture(), mSsidWhitelistCaptor.capture()); 1449ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan assertFalse(mBssidBlacklistCaptor.getValue().contains(bssid)); 1450ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan assertTrue(mSsidWhitelistCaptor.getValue().isEmpty()); 1451167b90b5e002698378728a54a417a08c317d29dcRandy Pan } 1452167b90b5e002698378728a54a417a08c317d29dcRandy Pan 1453167b90b5e002698378728a54a417a08c317d29dcRandy Pan /** 1454167b90b5e002698378728a54a417a08c317d29dcRandy Pan * Verify that a network gets blacklisted immediately if it is unable 1455167b90b5e002698378728a54a417a08c317d29dcRandy Pan * to handle new stations. 1456167b90b5e002698378728a54a417a08c317d29dcRandy Pan */ 1457167b90b5e002698378728a54a417a08c317d29dcRandy Pan @Test 1458167b90b5e002698378728a54a417a08c317d29dcRandy Pan public void blacklistNetworkImmediatelyIfApHasNoCapacityForNewStation() { 1459167b90b5e002698378728a54a417a08c317d29dcRandy Pan String bssid = "6c:f3:7f:ae:8c:f3"; 1460167b90b5e002698378728a54a417a08c317d29dcRandy Pan 1461ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan when(mWifiConnectivityHelper.isFirmwareRoamingSupported()).thenReturn(true); 1462ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan // Blacklist the BSSID 1463167b90b5e002698378728a54a417a08c317d29dcRandy Pan mWifiConnectivityManager.trackBssid(bssid, false, 1464167b90b5e002698378728a54a417a08c317d29dcRandy Pan WifiConnectivityManager.REASON_CODE_AP_UNABLE_TO_HANDLE_NEW_STA); 1465167b90b5e002698378728a54a417a08c317d29dcRandy Pan 1466ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan // Verify the BSSID is now blacklisted. 1467167b90b5e002698378728a54a417a08c317d29dcRandy Pan assertTrue(mWifiConnectivityManager.isBssidDisabled(bssid)); 1468ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan // Verify the BSSID gets sent to firmware. 1469ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan verify(mWifiConnectivityHelper).setFirmwareRoamingConfiguration( 1470ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan mBssidBlacklistCaptor.capture(), mSsidWhitelistCaptor.capture()); 1471ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan assertTrue(mBssidBlacklistCaptor.getValue().contains(bssid)); 1472ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan assertTrue(mSsidWhitelistCaptor.getValue().isEmpty()); 1473167b90b5e002698378728a54a417a08c317d29dcRandy Pan } 1474167b90b5e002698378728a54a417a08c317d29dcRandy Pan 1475167b90b5e002698378728a54a417a08c317d29dcRandy Pan /** 1476167b90b5e002698378728a54a417a08c317d29dcRandy Pan * Verify that a blacklisted BSSID becomes available only after 1477167b90b5e002698378728a54a417a08c317d29dcRandy Pan * BSSID_BLACKLIST_EXPIRE_TIME_MS. 1478167b90b5e002698378728a54a417a08c317d29dcRandy Pan */ 1479167b90b5e002698378728a54a417a08c317d29dcRandy Pan @Test 1480167b90b5e002698378728a54a417a08c317d29dcRandy Pan public void verifyBlacklistRefreshedAfterScanResults() { 1481167b90b5e002698378728a54a417a08c317d29dcRandy Pan String bssid = "6c:f3:7f:ae:8c:f3"; 1482167b90b5e002698378728a54a417a08c317d29dcRandy Pan 1483ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan when(mWifiConnectivityHelper.isFirmwareRoamingSupported()).thenReturn(true); 1484ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan // Blacklist the BSSID. 1485167b90b5e002698378728a54a417a08c317d29dcRandy Pan mWifiConnectivityManager.trackBssid(bssid, false, 1486167b90b5e002698378728a54a417a08c317d29dcRandy Pan WifiConnectivityManager.REASON_CODE_AP_UNABLE_TO_HANDLE_NEW_STA); 1487ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan 1488ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan // Verify the BSSID is now blacklisted. 1489167b90b5e002698378728a54a417a08c317d29dcRandy Pan assertTrue(mWifiConnectivityManager.isBssidDisabled(bssid)); 1490ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan // Verify the BSSID gets sent to firmware. 1491ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan verify(mWifiConnectivityHelper).setFirmwareRoamingConfiguration( 1492ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan mBssidBlacklistCaptor.capture(), mSsidWhitelistCaptor.capture()); 1493ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan assertTrue(mBssidBlacklistCaptor.getValue().contains(bssid)); 1494ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan assertTrue(mSsidWhitelistCaptor.getValue().isEmpty()); 1495167b90b5e002698378728a54a417a08c317d29dcRandy Pan 1496167b90b5e002698378728a54a417a08c317d29dcRandy Pan // Force a connectivity scan in less than BSSID_BLACKLIST_EXPIRE_TIME_MS. 1497167b90b5e002698378728a54a417a08c317d29dcRandy Pan // Arrival of scan results will trigger WifiConnectivityManager to refresh its 1498167b90b5e002698378728a54a417a08c317d29dcRandy Pan // BSSID blacklist. Verify that the blacklisted BSSId is not freed because 1499167b90b5e002698378728a54a417a08c317d29dcRandy Pan // its blacklist expiration time hasn't reached yet. 1500167b90b5e002698378728a54a417a08c317d29dcRandy Pan when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime() 1501167b90b5e002698378728a54a417a08c317d29dcRandy Pan + WifiConnectivityManager.BSSID_BLACKLIST_EXPIRE_TIME_MS / 2); 1502470817b13e56d915805729ab4f51075f3fa2ec15Ningyuan Wang mWifiConnectivityManager.forceConnectivityScan(WIFI_WORK_SOURCE); 1503167b90b5e002698378728a54a417a08c317d29dcRandy Pan assertTrue(mWifiConnectivityManager.isBssidDisabled(bssid)); 1504167b90b5e002698378728a54a417a08c317d29dcRandy Pan 1505167b90b5e002698378728a54a417a08c317d29dcRandy Pan // Force another connectivity scan at BSSID_BLACKLIST_EXPIRE_TIME_MS from when the 1506167b90b5e002698378728a54a417a08c317d29dcRandy Pan // BSSID was blacklisted. Verify that the blacklisted BSSId is freed. 1507167b90b5e002698378728a54a417a08c317d29dcRandy Pan when(mClock.getElapsedSinceBootMillis()).thenReturn(SystemClock.elapsedRealtime() 1508167b90b5e002698378728a54a417a08c317d29dcRandy Pan + WifiConnectivityManager.BSSID_BLACKLIST_EXPIRE_TIME_MS); 1509470817b13e56d915805729ab4f51075f3fa2ec15Ningyuan Wang mWifiConnectivityManager.forceConnectivityScan(WIFI_WORK_SOURCE); 1510ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan 1511ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan // Verify the BSSID is no longer blacklisted. 1512ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan assertFalse(mWifiConnectivityManager.isBssidDisabled(bssid)); 1513ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan // Verify the BSSID gets cleared from firmware. 1514ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan verify(mWifiConnectivityHelper, times(2)).setFirmwareRoamingConfiguration( 1515ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan mBssidBlacklistCaptor.capture(), mSsidWhitelistCaptor.capture()); 1516ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan assertFalse(mBssidBlacklistCaptor.getValue().contains(bssid)); 1517ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan assertTrue(mSsidWhitelistCaptor.getValue().isEmpty()); 1518ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan } 1519ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan 1520ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan /** 1521ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan * Verify that BSSID blacklist gets cleared when exiting Wifi client mode. 1522ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan */ 1523ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan @Test 1524ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan public void clearBssidBlacklistWhenExitingWifiClientMode() { 1525ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan String bssid = "6c:f3:7f:ae:8c:f3"; 1526ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan 1527ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan when(mWifiConnectivityHelper.isFirmwareRoamingSupported()).thenReturn(true); 1528ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan 1529ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan // Blacklist the BSSID. 1530ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan mWifiConnectivityManager.trackBssid(bssid, false, 1531ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan WifiConnectivityManager.REASON_CODE_AP_UNABLE_TO_HANDLE_NEW_STA); 1532ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan 1533ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan // Verify the BSSID is now blacklisted. 1534ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan assertTrue(mWifiConnectivityManager.isBssidDisabled(bssid)); 1535ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan // Verify the BSSID gets sent to firmware. 1536ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan verify(mWifiConnectivityHelper).setFirmwareRoamingConfiguration( 1537ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan mBssidBlacklistCaptor.capture(), mSsidWhitelistCaptor.capture()); 1538ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan assertTrue(mBssidBlacklistCaptor.getValue().contains(bssid)); 1539ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan assertTrue(mSsidWhitelistCaptor.getValue().isEmpty()); 1540ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan 1541ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan // Exit Wifi client mode. 1542ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan mWifiConnectivityManager.setWifiEnabled(false); 1543ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan 1544ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan // Verify the BSSID blacklist is empty. 1545ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan assertFalse(mWifiConnectivityManager.isBssidDisabled(bssid)); 1546ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan verify(mWifiConnectivityHelper, times(2)).setFirmwareRoamingConfiguration( 1547ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan mBssidBlacklistCaptor.capture(), mSsidWhitelistCaptor.capture()); 1548ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan assertTrue(mBssidBlacklistCaptor.getValue().isEmpty()); 1549ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan assertTrue(mSsidWhitelistCaptor.getValue().isEmpty()); 1550ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan } 1551ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan 1552ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan /** 1553ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan * Verify that BSSID blacklist gets cleared when preparing for a forced connection 1554ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan * initiated by user/app. 1555ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan */ 1556ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan @Test 1557ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan public void clearBssidBlacklistWhenPreparingForForcedConnection() { 1558ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan String bssid = "6c:f3:7f:ae:8c:f3"; 1559ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan 1560ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan when(mWifiConnectivityHelper.isFirmwareRoamingSupported()).thenReturn(true); 1561ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan 1562ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan // Blacklist the BSSID. 1563ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan mWifiConnectivityManager.trackBssid(bssid, false, 1564ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan WifiConnectivityManager.REASON_CODE_AP_UNABLE_TO_HANDLE_NEW_STA); 1565ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan 1566ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan // Verify the BSSID is now blacklisted. 1567ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan assertTrue(mWifiConnectivityManager.isBssidDisabled(bssid)); 1568ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan // Verify the BSSID gets sent to firmware. 1569ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan verify(mWifiConnectivityHelper).setFirmwareRoamingConfiguration( 1570ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan mBssidBlacklistCaptor.capture(), mSsidWhitelistCaptor.capture()); 1571ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan assertTrue(mBssidBlacklistCaptor.getValue().contains(bssid)); 1572ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan assertTrue(mSsidWhitelistCaptor.getValue().isEmpty()); 1573ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan 1574ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan // Prepare for a forced connection attempt. 1575ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan mWifiConnectivityManager.prepareForForcedConnection(1); 1576ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan 1577ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan // Verify the BSSID blacklist is empty. 1578167b90b5e002698378728a54a417a08c317d29dcRandy Pan assertFalse(mWifiConnectivityManager.isBssidDisabled(bssid)); 1579ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan verify(mWifiConnectivityHelper, times(2)).setFirmwareRoamingConfiguration( 1580ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan mBssidBlacklistCaptor.capture(), mSsidWhitelistCaptor.capture()); 1581ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan assertTrue(mBssidBlacklistCaptor.getValue().isEmpty()); 1582ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan assertTrue(mSsidWhitelistCaptor.getValue().isEmpty()); 1583ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan } 1584ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan 1585ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan /** 1586ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan /** 1587ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan * Verify that BSSID blacklist gets trimmed down to fit firmware capability. 1588ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan */ 1589ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan @Test 1590ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan public void trimDownBssidBlacklistForFirmware() { 1591ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan when(mWifiConnectivityHelper.isFirmwareRoamingSupported()).thenReturn(true); 1592ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan 1593ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan // Blacklist more than MAX_BSSID_BLACKLIST_SIZE BSSIDs. 1594ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan for (int i = 0; i < MAX_BSSID_BLACKLIST_SIZE + 6; i++) { 1595ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan StringBuilder bssid = new StringBuilder("55:44:33:22:11:00"); 1596ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan bssid.setCharAt(16, (char) ('0' + i)); 1597ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan mWifiConnectivityManager.trackBssid(bssid.toString(), false, 1598ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan WifiConnectivityManager.REASON_CODE_AP_UNABLE_TO_HANDLE_NEW_STA); 1599ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan // Verify that up to MAX_BSSID_BLACKLIST_SIZE BSSIDs gets sent to firmware. 1600ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan verify(mWifiConnectivityHelper, times(i + 1)).setFirmwareRoamingConfiguration( 1601ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan mBssidBlacklistCaptor.capture(), mSsidWhitelistCaptor.capture()); 1602ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan assertEquals((i + 1) < MAX_BSSID_BLACKLIST_SIZE ? (i + 1) : MAX_BSSID_BLACKLIST_SIZE, 1603ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan mBssidBlacklistCaptor.getValue().size()); 1604ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan assertTrue(mSsidWhitelistCaptor.getValue().isEmpty()); 1605ab8c62a5c348702090aceee23de12945cc3fdb0dRandy Pan } 1606167b90b5e002698378728a54a417a08c317d29dcRandy Pan } 1607a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 1608a54399f6da655dfbe440333ca3682b9199060a27Randy Pan /** 1609a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * When WifiConnectivityManager is on and Wifi client mode is enabled, framework 1610a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * queries firmware via WifiConnectivityHelper to check if firmware roaming is 1611a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * supported and its capability. 1612a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * 1613a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * Expected behavior: WifiConnectivityManager#setWifiEnabled calls into 1614a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * WifiConnectivityHelper#getFirmwareRoamingInfo 1615a54399f6da655dfbe440333ca3682b9199060a27Randy Pan */ 1616a54399f6da655dfbe440333ca3682b9199060a27Randy Pan @Test 1617a54399f6da655dfbe440333ca3682b9199060a27Randy Pan public void verifyGetFirmwareRoamingInfoIsCalledWhenEnableWiFiAndWcmOn() { 1618a54399f6da655dfbe440333ca3682b9199060a27Randy Pan reset(mWifiConnectivityHelper); 1619a54399f6da655dfbe440333ca3682b9199060a27Randy Pan // WifiConnectivityManager is on by default 1620a54399f6da655dfbe440333ca3682b9199060a27Randy Pan mWifiConnectivityManager.setWifiEnabled(true); 1621a54399f6da655dfbe440333ca3682b9199060a27Randy Pan verify(mWifiConnectivityHelper).getFirmwareRoamingInfo(); 1622a54399f6da655dfbe440333ca3682b9199060a27Randy Pan } 1623a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 1624a54399f6da655dfbe440333ca3682b9199060a27Randy Pan /** 1625a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * When WifiConnectivityManager is off, verify that framework does not 1626a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * query firmware via WifiConnectivityHelper to check if firmware roaming is 1627a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * supported and its capability when enabling Wifi client mode. 1628a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * 1629a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * Expected behavior: WifiConnectivityManager#setWifiEnabled does not call into 1630a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * WifiConnectivityHelper#getFirmwareRoamingInfo 1631a54399f6da655dfbe440333ca3682b9199060a27Randy Pan */ 1632a54399f6da655dfbe440333ca3682b9199060a27Randy Pan @Test 1633a54399f6da655dfbe440333ca3682b9199060a27Randy Pan public void verifyGetFirmwareRoamingInfoIsNotCalledWhenEnableWiFiAndWcmOff() { 1634a54399f6da655dfbe440333ca3682b9199060a27Randy Pan reset(mWifiConnectivityHelper); 1635a54399f6da655dfbe440333ca3682b9199060a27Randy Pan mWifiConnectivityManager.enable(false); 1636a54399f6da655dfbe440333ca3682b9199060a27Randy Pan mWifiConnectivityManager.setWifiEnabled(true); 1637a54399f6da655dfbe440333ca3682b9199060a27Randy Pan verify(mWifiConnectivityHelper, times(0)).getFirmwareRoamingInfo(); 1638a54399f6da655dfbe440333ca3682b9199060a27Randy Pan } 1639a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 1640a54399f6da655dfbe440333ca3682b9199060a27Randy Pan /* 1641a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * Firmware supports controlled roaming. 1642a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * Connect to a network which doesn't have a config specified BSSID. 1643a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * 1644a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * Expected behavior: WifiConnectivityManager calls 1645a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * WifiStateMachine.startConnectToNetwork() with the 1646a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * expected candidate network ID, and the BSSID value should be 1647a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * 'any' since firmware controls the roaming. 1648a54399f6da655dfbe440333ca3682b9199060a27Randy Pan */ 1649a54399f6da655dfbe440333ca3682b9199060a27Randy Pan @Test 1650a54399f6da655dfbe440333ca3682b9199060a27Randy Pan public void useAnyBssidToConnectWhenFirmwareRoamingOnAndConfigHasNoBssidSpecified() { 1651a54399f6da655dfbe440333ca3682b9199060a27Randy Pan // Firmware controls roaming 1652a54399f6da655dfbe440333ca3682b9199060a27Randy Pan when(mWifiConnectivityHelper.isFirmwareRoamingSupported()).thenReturn(true); 1653a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 1654a54399f6da655dfbe440333ca3682b9199060a27Randy Pan // Set screen to on 1655a54399f6da655dfbe440333ca3682b9199060a27Randy Pan mWifiConnectivityManager.handleScreenStateChanged(true); 1656a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 1657a54399f6da655dfbe440333ca3682b9199060a27Randy Pan // Set WiFi to disconnected state 1658a54399f6da655dfbe440333ca3682b9199060a27Randy Pan mWifiConnectivityManager.handleConnectionStateChanged( 1659a54399f6da655dfbe440333ca3682b9199060a27Randy Pan WifiConnectivityManager.WIFI_STATE_DISCONNECTED); 1660a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 1661a54399f6da655dfbe440333ca3682b9199060a27Randy Pan verify(mWifiStateMachine).startConnectToNetwork( 16629686c96d8d0c0bc21ca069e244e2570c169724e1Lorenzo Colitti CANDIDATE_NETWORK_ID, Process.WIFI_UID, WifiStateMachine.SUPPLICANT_BSSID_ANY); 1663a54399f6da655dfbe440333ca3682b9199060a27Randy Pan } 1664a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 1665a54399f6da655dfbe440333ca3682b9199060a27Randy Pan /* 1666a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * Firmware supports controlled roaming. 1667a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * Connect to a network which has a config specified BSSID. 1668a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * 1669a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * Expected behavior: WifiConnectivityManager calls 1670a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * WifiStateMachine.startConnectToNetwork() with the 1671a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * expected candidate network ID, and the BSSID value should be 1672b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan * the config specified one. 1673a54399f6da655dfbe440333ca3682b9199060a27Randy Pan */ 1674a54399f6da655dfbe440333ca3682b9199060a27Randy Pan @Test 1675b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan public void useConfigSpecifiedBssidToConnectWhenFirmwareRoamingOn() { 1676a54399f6da655dfbe440333ca3682b9199060a27Randy Pan // Firmware controls roaming 1677a54399f6da655dfbe440333ca3682b9199060a27Randy Pan when(mWifiConnectivityHelper.isFirmwareRoamingSupported()).thenReturn(true); 1678a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 1679a54399f6da655dfbe440333ca3682b9199060a27Randy Pan // Set up the candidate configuration such that it has a BSSID specified. 1680a54399f6da655dfbe440333ca3682b9199060a27Randy Pan WifiConfiguration candidate = generateWifiConfig( 1681a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 0, CANDIDATE_NETWORK_ID, CANDIDATE_SSID, false, true, null, null); 1682a54399f6da655dfbe440333ca3682b9199060a27Randy Pan candidate.BSSID = CANDIDATE_BSSID; // config specified 1683a54399f6da655dfbe440333ca3682b9199060a27Randy Pan ScanResult candidateScanResult = new ScanResult(); 1684a54399f6da655dfbe440333ca3682b9199060a27Randy Pan candidateScanResult.SSID = CANDIDATE_SSID; 1685a54399f6da655dfbe440333ca3682b9199060a27Randy Pan candidateScanResult.BSSID = CANDIDATE_BSSID; 1686a54399f6da655dfbe440333ca3682b9199060a27Randy Pan candidate.getNetworkSelectionStatus().setCandidate(candidateScanResult); 1687a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 1688a54399f6da655dfbe440333ca3682b9199060a27Randy Pan when(mWifiNS.selectNetwork(anyObject(), anyObject(), anyObject(), anyBoolean(), 1689b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan anyBoolean(), anyBoolean())).thenReturn(candidate); 1690a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 1691a54399f6da655dfbe440333ca3682b9199060a27Randy Pan // Set screen to on 1692a54399f6da655dfbe440333ca3682b9199060a27Randy Pan mWifiConnectivityManager.handleScreenStateChanged(true); 1693a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 1694a54399f6da655dfbe440333ca3682b9199060a27Randy Pan // Set WiFi to disconnected state 1695a54399f6da655dfbe440333ca3682b9199060a27Randy Pan mWifiConnectivityManager.handleConnectionStateChanged( 1696a54399f6da655dfbe440333ca3682b9199060a27Randy Pan WifiConnectivityManager.WIFI_STATE_DISCONNECTED); 1697a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 16989686c96d8d0c0bc21ca069e244e2570c169724e1Lorenzo Colitti verify(mWifiStateMachine).startConnectToNetwork( 16999686c96d8d0c0bc21ca069e244e2570c169724e1Lorenzo Colitti CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); 1700a54399f6da655dfbe440333ca3682b9199060a27Randy Pan } 1701a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 1702a54399f6da655dfbe440333ca3682b9199060a27Randy Pan /* 1703a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * Firmware does not support controlled roaming. 1704a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * Connect to a network which doesn't have a config specified BSSID. 1705a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * 1706a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * Expected behavior: WifiConnectivityManager calls 1707a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * WifiStateMachine.startConnectToNetwork() with the expected candidate network ID, 1708a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * and the BSSID value should be the candidate scan result specified. 1709a54399f6da655dfbe440333ca3682b9199060a27Randy Pan */ 1710a54399f6da655dfbe440333ca3682b9199060a27Randy Pan @Test 1711a54399f6da655dfbe440333ca3682b9199060a27Randy Pan public void useScanResultBssidToConnectWhenFirmwareRoamingOffAndConfigHasNoBssidSpecified() { 1712a54399f6da655dfbe440333ca3682b9199060a27Randy Pan // Set screen to on 1713a54399f6da655dfbe440333ca3682b9199060a27Randy Pan mWifiConnectivityManager.handleScreenStateChanged(true); 1714a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 1715a54399f6da655dfbe440333ca3682b9199060a27Randy Pan // Set WiFi to disconnected state 1716a54399f6da655dfbe440333ca3682b9199060a27Randy Pan mWifiConnectivityManager.handleConnectionStateChanged( 1717a54399f6da655dfbe440333ca3682b9199060a27Randy Pan WifiConnectivityManager.WIFI_STATE_DISCONNECTED); 1718a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 17199686c96d8d0c0bc21ca069e244e2570c169724e1Lorenzo Colitti verify(mWifiStateMachine).startConnectToNetwork( 17209686c96d8d0c0bc21ca069e244e2570c169724e1Lorenzo Colitti CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); 1721a54399f6da655dfbe440333ca3682b9199060a27Randy Pan } 1722a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 1723a54399f6da655dfbe440333ca3682b9199060a27Randy Pan /* 1724a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * Firmware does not support controlled roaming. 1725a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * Connect to a network which has a config specified BSSID. 1726a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * 1727a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * Expected behavior: WifiConnectivityManager calls 1728a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * WifiStateMachine.startConnectToNetwork() with the expected candidate network ID, 1729a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * and the BSSID value should be the config specified one. 1730a54399f6da655dfbe440333ca3682b9199060a27Randy Pan */ 1731a54399f6da655dfbe440333ca3682b9199060a27Randy Pan @Test 1732a54399f6da655dfbe440333ca3682b9199060a27Randy Pan public void useConfigSpecifiedBssidToConnectionWhenFirmwareRoamingOff() { 1733a54399f6da655dfbe440333ca3682b9199060a27Randy Pan // Set up the candidate configuration such that it has a BSSID specified. 1734a54399f6da655dfbe440333ca3682b9199060a27Randy Pan WifiConfiguration candidate = generateWifiConfig( 1735a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 0, CANDIDATE_NETWORK_ID, CANDIDATE_SSID, false, true, null, null); 1736a54399f6da655dfbe440333ca3682b9199060a27Randy Pan candidate.BSSID = CANDIDATE_BSSID; // config specified 1737a54399f6da655dfbe440333ca3682b9199060a27Randy Pan ScanResult candidateScanResult = new ScanResult(); 1738a54399f6da655dfbe440333ca3682b9199060a27Randy Pan candidateScanResult.SSID = CANDIDATE_SSID; 1739a54399f6da655dfbe440333ca3682b9199060a27Randy Pan candidateScanResult.BSSID = CANDIDATE_BSSID; 1740a54399f6da655dfbe440333ca3682b9199060a27Randy Pan candidate.getNetworkSelectionStatus().setCandidate(candidateScanResult); 1741a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 1742a54399f6da655dfbe440333ca3682b9199060a27Randy Pan when(mWifiNS.selectNetwork(anyObject(), anyObject(), anyObject(), anyBoolean(), 1743b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan anyBoolean(), anyBoolean())).thenReturn(candidate); 1744a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 1745a54399f6da655dfbe440333ca3682b9199060a27Randy Pan // Set screen to on 1746a54399f6da655dfbe440333ca3682b9199060a27Randy Pan mWifiConnectivityManager.handleScreenStateChanged(true); 1747a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 1748a54399f6da655dfbe440333ca3682b9199060a27Randy Pan // Set WiFi to disconnected state 1749a54399f6da655dfbe440333ca3682b9199060a27Randy Pan mWifiConnectivityManager.handleConnectionStateChanged( 1750a54399f6da655dfbe440333ca3682b9199060a27Randy Pan WifiConnectivityManager.WIFI_STATE_DISCONNECTED); 1751a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 17529686c96d8d0c0bc21ca069e244e2570c169724e1Lorenzo Colitti verify(mWifiStateMachine).startConnectToNetwork( 17539686c96d8d0c0bc21ca069e244e2570c169724e1Lorenzo Colitti CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); 1754a54399f6da655dfbe440333ca3682b9199060a27Randy Pan } 1755a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 1756a54399f6da655dfbe440333ca3682b9199060a27Randy Pan /** 1757a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * Firmware does not support controlled roaming. 1758a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * WiFi in connected state, framework triggers roaming. 1759a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * 1760a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * Expected behavior: WifiConnectivityManager invokes 1761a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * WifiStateMachine.startRoamToNetwork(). 1762a54399f6da655dfbe440333ca3682b9199060a27Randy Pan */ 1763a54399f6da655dfbe440333ca3682b9199060a27Randy Pan @Test 1764a54399f6da655dfbe440333ca3682b9199060a27Randy Pan public void frameworkInitiatedRoaming() { 1765a54399f6da655dfbe440333ca3682b9199060a27Randy Pan // Mock the currently connected network which has the same networkID and 1766a54399f6da655dfbe440333ca3682b9199060a27Randy Pan // SSID as the one to be selected. 1767a54399f6da655dfbe440333ca3682b9199060a27Randy Pan WifiConfiguration currentNetwork = generateWifiConfig( 1768a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 0, CANDIDATE_NETWORK_ID, CANDIDATE_SSID, false, true, null, null); 1769a54399f6da655dfbe440333ca3682b9199060a27Randy Pan when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(currentNetwork); 1770a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 1771a54399f6da655dfbe440333ca3682b9199060a27Randy Pan // Set WiFi to connected state 1772a54399f6da655dfbe440333ca3682b9199060a27Randy Pan mWifiConnectivityManager.handleConnectionStateChanged( 1773a54399f6da655dfbe440333ca3682b9199060a27Randy Pan WifiConnectivityManager.WIFI_STATE_CONNECTED); 1774a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 1775a54399f6da655dfbe440333ca3682b9199060a27Randy Pan // Set screen to on 1776a54399f6da655dfbe440333ca3682b9199060a27Randy Pan mWifiConnectivityManager.handleScreenStateChanged(true); 1777a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 1778a54399f6da655dfbe440333ca3682b9199060a27Randy Pan verify(mWifiStateMachine).startRoamToNetwork(eq(CANDIDATE_NETWORK_ID), 1779a54399f6da655dfbe440333ca3682b9199060a27Randy Pan mCandidateScanResultCaptor.capture()); 1780a54399f6da655dfbe440333ca3682b9199060a27Randy Pan assertEquals(mCandidateScanResultCaptor.getValue().BSSID, CANDIDATE_BSSID); 1781a54399f6da655dfbe440333ca3682b9199060a27Randy Pan } 1782a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 1783a54399f6da655dfbe440333ca3682b9199060a27Randy Pan /** 1784a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * Firmware supports controlled roaming. 1785a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * WiFi in connected state, framework does not trigger roaming 1786a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * as it's handed off to the firmware. 1787a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * 1788a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * Expected behavior: WifiConnectivityManager doesn't invoke 1789a54399f6da655dfbe440333ca3682b9199060a27Randy Pan * WifiStateMachine.startRoamToNetwork(). 1790a54399f6da655dfbe440333ca3682b9199060a27Randy Pan */ 1791a54399f6da655dfbe440333ca3682b9199060a27Randy Pan @Test 1792a54399f6da655dfbe440333ca3682b9199060a27Randy Pan public void noFrameworkRoamingIfConnectedAndFirmwareRoamingSupported() { 1793a54399f6da655dfbe440333ca3682b9199060a27Randy Pan // Mock the currently connected network which has the same networkID and 1794a54399f6da655dfbe440333ca3682b9199060a27Randy Pan // SSID as the one to be selected. 1795a54399f6da655dfbe440333ca3682b9199060a27Randy Pan WifiConfiguration currentNetwork = generateWifiConfig( 1796a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 0, CANDIDATE_NETWORK_ID, CANDIDATE_SSID, false, true, null, null); 1797a54399f6da655dfbe440333ca3682b9199060a27Randy Pan when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(currentNetwork); 1798a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 1799a54399f6da655dfbe440333ca3682b9199060a27Randy Pan // Firmware controls roaming 1800a54399f6da655dfbe440333ca3682b9199060a27Randy Pan when(mWifiConnectivityHelper.isFirmwareRoamingSupported()).thenReturn(true); 1801a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 1802a54399f6da655dfbe440333ca3682b9199060a27Randy Pan // Set WiFi to connected state 1803a54399f6da655dfbe440333ca3682b9199060a27Randy Pan mWifiConnectivityManager.handleConnectionStateChanged( 1804a54399f6da655dfbe440333ca3682b9199060a27Randy Pan WifiConnectivityManager.WIFI_STATE_CONNECTED); 1805a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 1806a54399f6da655dfbe440333ca3682b9199060a27Randy Pan // Set screen to on 1807a54399f6da655dfbe440333ca3682b9199060a27Randy Pan mWifiConnectivityManager.handleScreenStateChanged(true); 1808a54399f6da655dfbe440333ca3682b9199060a27Randy Pan 1809b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan verify(mWifiStateMachine, times(0)).startRoamToNetwork(anyInt(), anyObject()); 1810b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan } 1811b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan 1812b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan /* 1813b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan * Wifi in disconnected state. Drop the connection attempt if the recommended 1814b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan * network configuration has a BSSID specified but the scan result BSSID doesn't 1815b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan * match it. 1816b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan * 1817b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan * Expected behavior: WifiConnectivityManager doesn't invoke 1818b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan * WifiStateMachine.startConnectToNetwork(). 1819b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan */ 1820b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan @Test 1821b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan public void dropConnectAttemptIfConfigSpecifiedBssidDifferentFromScanResultBssid() { 1822b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan // Set up the candidate configuration such that it has a BSSID specified. 1823b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan WifiConfiguration candidate = generateWifiConfig( 1824b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan 0, CANDIDATE_NETWORK_ID, CANDIDATE_SSID, false, true, null, null); 1825b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan candidate.BSSID = CANDIDATE_BSSID; // config specified 1826b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan ScanResult candidateScanResult = new ScanResult(); 1827b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan candidateScanResult.SSID = CANDIDATE_SSID; 1828b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan // Set up the scan result BSSID to be different from the config specified one. 1829b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan candidateScanResult.BSSID = INVALID_SCAN_RESULT_BSSID; 1830b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan candidate.getNetworkSelectionStatus().setCandidate(candidateScanResult); 1831b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan 1832b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan when(mWifiNS.selectNetwork(anyObject(), anyObject(), anyObject(), anyBoolean(), 1833b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan anyBoolean(), anyBoolean())).thenReturn(candidate); 1834b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan 1835b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan // Set screen to on 1836b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan mWifiConnectivityManager.handleScreenStateChanged(true); 1837b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan 1838b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan // Set WiFi to disconnected state 1839b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan mWifiConnectivityManager.handleConnectionStateChanged( 1840b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan WifiConnectivityManager.WIFI_STATE_DISCONNECTED); 1841b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan 1842b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan verify(mWifiStateMachine, times(0)).startConnectToNetwork( 18439686c96d8d0c0bc21ca069e244e2570c169724e1Lorenzo Colitti CANDIDATE_NETWORK_ID, Process.WIFI_UID, CANDIDATE_BSSID); 1844b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan } 1845b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan 1846b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan /* 1847b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan * Wifi in connected state. Drop the roaming attempt if the recommended 1848b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan * network configuration has a BSSID specified but the scan result BSSID doesn't 1849b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan * match it. 1850b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan * 1851b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan * Expected behavior: WifiConnectivityManager doesn't invoke 1852b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan * WifiStateMachine.startRoamToNetwork(). 1853b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan */ 1854b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan @Test 1855b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan public void dropRoamingAttemptIfConfigSpecifiedBssidDifferentFromScanResultBssid() { 1856b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan // Mock the currently connected network which has the same networkID and 1857b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan // SSID as the one to be selected. 1858b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan WifiConfiguration currentNetwork = generateWifiConfig( 1859b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan 0, CANDIDATE_NETWORK_ID, CANDIDATE_SSID, false, true, null, null); 1860b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan when(mWifiConfigManager.getConfiguredNetwork(anyInt())).thenReturn(currentNetwork); 1861b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan 1862b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan // Set up the candidate configuration such that it has a BSSID specified. 1863b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan WifiConfiguration candidate = generateWifiConfig( 1864b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan 0, CANDIDATE_NETWORK_ID, CANDIDATE_SSID, false, true, null, null); 1865b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan candidate.BSSID = CANDIDATE_BSSID; // config specified 1866b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan ScanResult candidateScanResult = new ScanResult(); 1867b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan candidateScanResult.SSID = CANDIDATE_SSID; 1868b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan // Set up the scan result BSSID to be different from the config specified one. 1869b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan candidateScanResult.BSSID = INVALID_SCAN_RESULT_BSSID; 1870b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan candidate.getNetworkSelectionStatus().setCandidate(candidateScanResult); 1871b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan 1872b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan when(mWifiNS.selectNetwork(anyObject(), anyObject(), anyObject(), anyBoolean(), 1873b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan anyBoolean(), anyBoolean())).thenReturn(candidate); 1874b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan 1875b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan // Set WiFi to connected state 1876b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan mWifiConnectivityManager.handleConnectionStateChanged( 1877b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan WifiConnectivityManager.WIFI_STATE_CONNECTED); 1878b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan 1879b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan // Set screen to on 1880b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan mWifiConnectivityManager.handleScreenStateChanged(true); 1881b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan 1882b6686e9d42895f9c2b9f4278cd892149bee04e3aRandy Pan verify(mWifiStateMachine, times(0)).startRoamToNetwork(anyInt(), anyObject()); 1883a54399f6da655dfbe440333ca3682b9199060a27Randy Pan } 188417c2a7b30e5680b11fc0073ce322ee7bc14ef2c5Randy Pan 188517c2a7b30e5680b11fc0073ce322ee7bc14ef2c5Randy Pan /** 188617c2a7b30e5680b11fc0073ce322ee7bc14ef2c5Randy Pan * Dump local log buffer. 188717c2a7b30e5680b11fc0073ce322ee7bc14ef2c5Randy Pan * 188817c2a7b30e5680b11fc0073ce322ee7bc14ef2c5Randy Pan * Expected behavior: Logs dumped from WifiConnectivityManager.dump() 188917c2a7b30e5680b11fc0073ce322ee7bc14ef2c5Randy Pan * contain the message we put in mLocalLog. 189017c2a7b30e5680b11fc0073ce322ee7bc14ef2c5Randy Pan */ 189117c2a7b30e5680b11fc0073ce322ee7bc14ef2c5Randy Pan @Test 189217c2a7b30e5680b11fc0073ce322ee7bc14ef2c5Randy Pan public void dumpLocalLog() { 189317c2a7b30e5680b11fc0073ce322ee7bc14ef2c5Randy Pan final String localLogMessage = "This is a message from the test"; 189417c2a7b30e5680b11fc0073ce322ee7bc14ef2c5Randy Pan mLocalLog.log(localLogMessage); 189517c2a7b30e5680b11fc0073ce322ee7bc14ef2c5Randy Pan 189617c2a7b30e5680b11fc0073ce322ee7bc14ef2c5Randy Pan StringWriter sw = new StringWriter(); 189717c2a7b30e5680b11fc0073ce322ee7bc14ef2c5Randy Pan PrintWriter pw = new PrintWriter(sw); 189817c2a7b30e5680b11fc0073ce322ee7bc14ef2c5Randy Pan mWifiConnectivityManager.dump(new FileDescriptor(), pw, new String[]{}); 189917c2a7b30e5680b11fc0073ce322ee7bc14ef2c5Randy Pan assertTrue(sw.toString().contains(localLogMessage)); 190017c2a7b30e5680b11fc0073ce322ee7bc14ef2c5Randy Pan } 19013f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen 19023f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen /** 19033f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen * Dump ONA controller. 19043f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen * 1905ce76a17ac5010e0b7ff5dcf6d8c9db8b48280f9cStephen Chen * Expected behavior: {@link OpenNetworkNotifier#dump(FileDescriptor, PrintWriter, 19063f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen * String[])} is invoked. 19073f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen */ 19083f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen @Test 19093f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen public void dumpNotificationController() { 19103f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen StringWriter sw = new StringWriter(); 19113f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen PrintWriter pw = new PrintWriter(sw); 19123f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen mWifiConnectivityManager.dump(new FileDescriptor(), pw, new String[]{}); 19133f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen 1914ce76a17ac5010e0b7ff5dcf6d8c9db8b48280f9cStephen Chen verify(mOpenNetworkNotifier).dump(any(), any(), any()); 19153f8483262cf59572d0c0b3c42e72d8ce65a096ffStephen Chen } 1916652381b37461a4aa793327365e144bb4335cbd27Roshan Pius 1917652381b37461a4aa793327365e144bb4335cbd27Roshan Pius /** 191886ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius * Create scan data with different radio chain infos: 191986ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius * First scan result has null radio chain info (No DBS support). 192086ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius * Second scan result has empty radio chain info (No DBS support). 192186ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius * Third scan result has 1 radio chain info (DBS scan). 192286ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius * Fourth scan result has 2 radio chain info (non-DBS scan). 192386ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius */ 192486ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius private ScanData createScanDataWithDifferentRadioChainInfos() { 192586ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius // Create 4 scan results. 192686ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius ScanData[] scanDatas = 192786ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius ScanTestUtil.createScanDatas(new int[][]{{5150, 5175, 2412, 2400}}, new int[]{0}); 192886ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius // WCM barfs if the scan result does not have an IE. 192986ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius scanDatas[0].getResults()[0].informationElements = new InformationElement[0]; 193086ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius scanDatas[0].getResults()[1].informationElements = new InformationElement[0]; 193186ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius scanDatas[0].getResults()[2].informationElements = new InformationElement[0]; 193286ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius scanDatas[0].getResults()[3].informationElements = new InformationElement[0]; 193386ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius scanDatas[0].getResults()[0].radioChainInfos = null; 193486ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius scanDatas[0].getResults()[1].radioChainInfos = new ScanResult.RadioChainInfo[0]; 193586ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius scanDatas[0].getResults()[2].radioChainInfos = new ScanResult.RadioChainInfo[1]; 193686ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius scanDatas[0].getResults()[3].radioChainInfos = new ScanResult.RadioChainInfo[2]; 193786ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius 193886ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius return scanDatas[0]; 193986ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius } 194086ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius 194186ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius /** 194286ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius * If |config_wifi_framework_use_single_radio_chain_scan_results_network_selection| flag is 194386ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius * false, WifiConnectivityManager should filter scan results which contain scans from a single 194486ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius * radio chain (i.e DBS scan). 1945652381b37461a4aa793327365e144bb4335cbd27Roshan Pius * Note: 1946652381b37461a4aa793327365e144bb4335cbd27Roshan Pius * a) ScanResult with no radio chain indicates a lack of DBS support on the device. 1947652381b37461a4aa793327365e144bb4335cbd27Roshan Pius * b) ScanResult with 2 radio chain info indicates a scan done using both the radio chains 1948652381b37461a4aa793327365e144bb4335cbd27Roshan Pius * on a DBS supported device. 1949652381b37461a4aa793327365e144bb4335cbd27Roshan Pius * 1950652381b37461a4aa793327365e144bb4335cbd27Roshan Pius * Expected behavior: WifiConnectivityManager invokes 1951652381b37461a4aa793327365e144bb4335cbd27Roshan Pius * {@link WifiNetworkSelector#selectNetwork(List, HashSet, WifiInfo, boolean, boolean, boolean)} 1952652381b37461a4aa793327365e144bb4335cbd27Roshan Pius * after filtering out the scan results obtained via DBS scan. 1953652381b37461a4aa793327365e144bb4335cbd27Roshan Pius */ 1954652381b37461a4aa793327365e144bb4335cbd27Roshan Pius @Test 195586ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius public void filterScanResultsWithOneRadioChainInfoForNetworkSelectionIfConfigDisabled() { 195686ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius when(mResource.getBoolean( 195786ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius R.bool.config_wifi_framework_use_single_radio_chain_scan_results_network_selection)) 195886ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius .thenReturn(false); 1959652381b37461a4aa793327365e144bb4335cbd27Roshan Pius when(mWifiNS.selectNetwork(any(), any(), any(), anyBoolean(), anyBoolean(), anyBoolean())) 1960652381b37461a4aa793327365e144bb4335cbd27Roshan Pius .thenReturn(null); 196186ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius mWifiConnectivityManager = createConnectivityManager(); 1962652381b37461a4aa793327365e144bb4335cbd27Roshan Pius 196386ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius mScanData = createScanDataWithDifferentRadioChainInfos(); 1964652381b37461a4aa793327365e144bb4335cbd27Roshan Pius 1965652381b37461a4aa793327365e144bb4335cbd27Roshan Pius // Capture scan details which were sent to network selector. 1966652381b37461a4aa793327365e144bb4335cbd27Roshan Pius final List<ScanDetail> capturedScanDetails = new ArrayList<>(); 1967652381b37461a4aa793327365e144bb4335cbd27Roshan Pius doAnswer(new AnswerWithArguments() { 1968652381b37461a4aa793327365e144bb4335cbd27Roshan Pius public WifiConfiguration answer( 1969652381b37461a4aa793327365e144bb4335cbd27Roshan Pius List<ScanDetail> scanDetails, HashSet<String> bssidBlacklist, WifiInfo wifiInfo, 1970652381b37461a4aa793327365e144bb4335cbd27Roshan Pius boolean connected, boolean disconnected, boolean untrustedNetworkAllowed) 1971652381b37461a4aa793327365e144bb4335cbd27Roshan Pius throws Exception { 1972652381b37461a4aa793327365e144bb4335cbd27Roshan Pius capturedScanDetails.addAll(scanDetails); 1973652381b37461a4aa793327365e144bb4335cbd27Roshan Pius return null; 1974652381b37461a4aa793327365e144bb4335cbd27Roshan Pius }}).when(mWifiNS).selectNetwork( 1975652381b37461a4aa793327365e144bb4335cbd27Roshan Pius any(), any(), any(), anyBoolean(), anyBoolean(), anyBoolean()); 1976652381b37461a4aa793327365e144bb4335cbd27Roshan Pius 1977652381b37461a4aa793327365e144bb4335cbd27Roshan Pius // Set WiFi to disconnected state with screen on which triggers a scan immediately. 197886ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius mWifiConnectivityManager.setWifiEnabled(true); 1979652381b37461a4aa793327365e144bb4335cbd27Roshan Pius mWifiConnectivityManager.handleScreenStateChanged(true); 1980652381b37461a4aa793327365e144bb4335cbd27Roshan Pius mWifiConnectivityManager.handleConnectionStateChanged( 1981652381b37461a4aa793327365e144bb4335cbd27Roshan Pius WifiConnectivityManager.WIFI_STATE_DISCONNECTED); 1982652381b37461a4aa793327365e144bb4335cbd27Roshan Pius 1983652381b37461a4aa793327365e144bb4335cbd27Roshan Pius // We should have filtered out the 3rd scan result. 1984652381b37461a4aa793327365e144bb4335cbd27Roshan Pius assertEquals(3, capturedScanDetails.size()); 1985652381b37461a4aa793327365e144bb4335cbd27Roshan Pius List<ScanResult> capturedScanResults = 1986652381b37461a4aa793327365e144bb4335cbd27Roshan Pius capturedScanDetails.stream().map(ScanDetail::getScanResult) 1987652381b37461a4aa793327365e144bb4335cbd27Roshan Pius .collect(Collectors.toList()); 1988652381b37461a4aa793327365e144bb4335cbd27Roshan Pius 1989652381b37461a4aa793327365e144bb4335cbd27Roshan Pius assertEquals(3, capturedScanResults.size()); 1990652381b37461a4aa793327365e144bb4335cbd27Roshan Pius assertTrue(capturedScanResults.contains(mScanData.getResults()[0])); 1991652381b37461a4aa793327365e144bb4335cbd27Roshan Pius assertTrue(capturedScanResults.contains(mScanData.getResults()[1])); 1992652381b37461a4aa793327365e144bb4335cbd27Roshan Pius assertFalse(capturedScanResults.contains(mScanData.getResults()[2])); 1993652381b37461a4aa793327365e144bb4335cbd27Roshan Pius assertTrue(capturedScanResults.contains(mScanData.getResults()[3])); 1994652381b37461a4aa793327365e144bb4335cbd27Roshan Pius } 1995652381b37461a4aa793327365e144bb4335cbd27Roshan Pius 199686ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius /** 199786ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius * If |config_wifi_framework_use_single_radio_chain_scan_results_network_selection| flag is 199886ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius * true, WifiConnectivityManager should not filter scan results which contain scans from a 199986ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius * single radio chain (i.e DBS scan). 200086ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius * Note: 200186ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius * a) ScanResult with no radio chain indicates a lack of DBS support on the device. 200286ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius * b) ScanResult with 2 radio chain info indicates a scan done using both the radio chains 200386ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius * on a DBS supported device. 200486ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius * 200586ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius * Expected behavior: WifiConnectivityManager invokes 200686ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius * {@link WifiNetworkSelector#selectNetwork(List, HashSet, WifiInfo, boolean, boolean, boolean)} 200786ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius * after filtering out the scan results obtained via DBS scan. 200886ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius */ 200986ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius @Test 201086ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius public void dontFilterScanResultsWithOneRadioChainInfoForNetworkSelectionIfConfigEnabled() { 201186ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius when(mResource.getBoolean( 201286ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius R.bool.config_wifi_framework_use_single_radio_chain_scan_results_network_selection)) 201386ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius .thenReturn(true); 201486ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius when(mWifiNS.selectNetwork(any(), any(), any(), anyBoolean(), anyBoolean(), anyBoolean())) 201586ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius .thenReturn(null); 201686ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius mWifiConnectivityManager = createConnectivityManager(); 201786ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius 201886ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius mScanData = createScanDataWithDifferentRadioChainInfos(); 201986ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius 202086ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius // Capture scan details which were sent to network selector. 202186ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius final List<ScanDetail> capturedScanDetails = new ArrayList<>(); 202286ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius doAnswer(new AnswerWithArguments() { 202386ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius public WifiConfiguration answer( 202486ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius List<ScanDetail> scanDetails, HashSet<String> bssidBlacklist, WifiInfo wifiInfo, 202586ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius boolean connected, boolean disconnected, boolean untrustedNetworkAllowed) 202686ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius throws Exception { 202786ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius capturedScanDetails.addAll(scanDetails); 202886ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius return null; 202986ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius }}).when(mWifiNS).selectNetwork( 203086ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius any(), any(), any(), anyBoolean(), anyBoolean(), anyBoolean()); 203186ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius 203286ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius // Set WiFi to disconnected state with screen on which triggers a scan immediately. 203386ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius mWifiConnectivityManager.setWifiEnabled(true); 203486ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius mWifiConnectivityManager.handleScreenStateChanged(true); 203586ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius mWifiConnectivityManager.handleConnectionStateChanged( 203686ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius WifiConnectivityManager.WIFI_STATE_DISCONNECTED); 203786ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius 203886ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius // We should not filter any of the scan results. 203986ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius assertEquals(4, capturedScanDetails.size()); 204086ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius List<ScanResult> capturedScanResults = 204186ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius capturedScanDetails.stream().map(ScanDetail::getScanResult) 204286ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius .collect(Collectors.toList()); 204386ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius 204486ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius assertEquals(4, capturedScanResults.size()); 204586ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius assertTrue(capturedScanResults.contains(mScanData.getResults()[0])); 204686ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius assertTrue(capturedScanResults.contains(mScanData.getResults()[1])); 204786ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius assertTrue(capturedScanResults.contains(mScanData.getResults()[2])); 204886ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius assertTrue(capturedScanResults.contains(mScanData.getResults()[3])); 204986ea918f785f665e0fa41ddd5d6803d73ad72650Roshan Pius } 2050095121ada1c9ea6034e86606395de20cddcad9baRoshan Pius 2051095121ada1c9ea6034e86606395de20cddcad9baRoshan Pius /** 2052095121ada1c9ea6034e86606395de20cddcad9baRoshan Pius * Disabling the network temporarily due to lack of internet is a special reason for which we 2053095121ada1c9ea6034e86606395de20cddcad9baRoshan Pius * don't want WCM to trigger a disconnect (by removing the network from supplicant). 2054095121ada1c9ea6034e86606395de20cddcad9baRoshan Pius */ 2055095121ada1c9ea6034e86606395de20cddcad9baRoshan Pius @Test 2056095121ada1c9ea6034e86606395de20cddcad9baRoshan Pius public void dontDisconnectIfNetworkTemporarilyDisabledDueToNoInternet() { 2057095121ada1c9ea6034e86606395de20cddcad9baRoshan Pius assertNotNull(mSavedNetworkUpdateListenerCaptor.getValue()); 2058095121ada1c9ea6034e86606395de20cddcad9baRoshan Pius 2059095121ada1c9ea6034e86606395de20cddcad9baRoshan Pius mSavedNetworkUpdateListenerCaptor.getValue() 2060095121ada1c9ea6034e86606395de20cddcad9baRoshan Pius .onSavedNetworkPermanentlyDisabled(0, DISABLED_AUTHENTICATION_FAILURE); 2061095121ada1c9ea6034e86606395de20cddcad9baRoshan Pius verify(mWifiConnectivityHelper).removeNetworkIfCurrent(0); 2062095121ada1c9ea6034e86606395de20cddcad9baRoshan Pius 2063095121ada1c9ea6034e86606395de20cddcad9baRoshan Pius mSavedNetworkUpdateListenerCaptor.getValue() 2064095121ada1c9ea6034e86606395de20cddcad9baRoshan Pius .onSavedNetworkPermanentlyDisabled(0, DISABLED_NO_INTERNET_TEMPORARY); 2065095121ada1c9ea6034e86606395de20cddcad9baRoshan Pius // Don't remove network. 2066095121ada1c9ea6034e86606395de20cddcad9baRoshan Pius } 206784d962ec8f487f824214744498bba505a6db0c59Randy Pan} 2068