WifiLastResortWatchdogTest.java revision 91a8893f047b8a193e4516ab772b6f43882777f5
1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.wifi; 18 19import static org.junit.Assert.assertEquals; 20import static org.junit.Assert.assertTrue; 21import static org.mockito.Mockito.*; 22 23import android.net.wifi.WifiConfiguration; 24import android.net.wifi.WifiSsid; 25import android.test.suitebuilder.annotation.SmallTest; 26import android.util.Pair; 27 28import org.junit.Before; 29import org.junit.Test; 30 31import java.util.ArrayList; 32import java.util.Arrays; 33import java.util.List; 34 35/** 36 * Unit tests for {@link com.android.server.wifi.WifiLastResortWatchdog}. 37 */ 38@SmallTest 39public class WifiLastResortWatchdogTest { 40 WifiLastResortWatchdog mLastResortWatchdog; 41 WifiMetrics mWifiMetrics; 42 private String[] mSsids = {"\"test1\"", "\"test2\"", "\"test3\"", "\"test4\""}; 43 private String[] mBssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4", "de:ad:ba:b1:e5:55", 44 "c0:ff:ee:ee:e3:ee"}; 45 private int[] mFrequencies = {2437, 5180, 5180, 2437}; 46 private String[] mCaps = {"[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]", 47 "[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]"}; 48 private int[] mLevels = {-60, -86, -50, -62}; 49 private boolean[] mIsEphemeral = {false, false, false, false}; 50 private boolean[] mHasEverConnected = {false, false, false, false}; 51 52 @Before 53 public void setUp() throws Exception { 54 mWifiMetrics = mock(WifiMetrics.class); 55 mLastResortWatchdog = new WifiLastResortWatchdog(mWifiMetrics); 56 } 57 58 private List<Pair<ScanDetail, WifiConfiguration>> createFilteredQnsCandidates(String[] ssids, 59 String[] bssids, int[] frequencies, String[] caps, int[] levels, 60 boolean[] isEphemeral) { 61 List<Pair<ScanDetail, WifiConfiguration>> candidates = new ArrayList<>(); 62 long timeStamp = System.currentTimeMillis(); 63 for (int index = 0; index < ssids.length; index++) { 64 String ssid = ssids[index].replaceAll("^\"+", "").replaceAll("\"+$", ""); 65 ScanDetail scanDetail = new ScanDetail(WifiSsid.createFromAsciiEncoded(ssid), 66 bssids[index], caps[index], levels[index], frequencies[index], timeStamp, 67 0); 68 WifiConfiguration config = null; 69 if (!isEphemeral[index]) { 70 config = mock(WifiConfiguration.class); 71 WifiConfiguration.NetworkSelectionStatus networkSelectionStatus = 72 mock(WifiConfiguration.NetworkSelectionStatus.class); 73 when(config.getNetworkSelectionStatus()).thenReturn(networkSelectionStatus); 74 when(networkSelectionStatus.getHasEverConnected()).thenReturn(true); 75 } 76 candidates.add(Pair.create(scanDetail, config)); 77 } 78 return candidates; 79 } 80 81 private List<Pair<ScanDetail, WifiConfiguration>> createFilteredQnsCandidates(String[] ssids, 82 String[] bssids, int[] frequencies, String[] caps, int[] levels, 83 boolean[] isEphemeral, boolean[] hasEverConnected) { 84 List<Pair<ScanDetail, WifiConfiguration>> candidates = 85 new ArrayList<Pair<ScanDetail, WifiConfiguration>>(); 86 long timeStamp = System.currentTimeMillis(); 87 for (int index = 0; index < ssids.length; index++) { 88 String ssid = ssids[index].replaceAll("^\"+", "").replaceAll("\"+$", ""); 89 ScanDetail scanDetail = new ScanDetail(WifiSsid.createFromAsciiEncoded(ssid), 90 bssids[index], caps[index], levels[index], frequencies[index], timeStamp, 91 0); 92 WifiConfiguration config = null; 93 if (!isEphemeral[index]) { 94 config = mock(WifiConfiguration.class); 95 WifiConfiguration.NetworkSelectionStatus networkSelectionStatus = 96 mock(WifiConfiguration.NetworkSelectionStatus.class); 97 when(config.getNetworkSelectionStatus()).thenReturn(networkSelectionStatus); 98 when(networkSelectionStatus.getHasEverConnected()) 99 .thenReturn(hasEverConnected[index]); 100 } 101 candidates.add(Pair.create(scanDetail, config)); 102 } 103 return candidates; 104 } 105 106 private void assertFailureCountEquals( 107 String bssid, int associationRejections, int authenticationFailures, int dhcpFailures) { 108 assertEquals(associationRejections, mLastResortWatchdog.getFailureCount(bssid, 109 WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION)); 110 assertEquals(authenticationFailures, mLastResortWatchdog.getFailureCount(bssid, 111 WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION)); 112 assertEquals(dhcpFailures, mLastResortWatchdog.getFailureCount(bssid, 113 WifiLastResortWatchdog.FAILURE_CODE_DHCP)); 114 } 115 116 /** 117 * Case #1: Test aging works in available network buffering 118 * This test simulates 4 networks appearing in a scan result, and then only the first 2 119 * appearing in successive scans results. 120 * Expected Behavior: 121 * 4 networks appear in recentAvailalbeNetworks, after N=MAX_BSSID_AGE scans, only 2 remain 122 */ 123 @Test 124 public void testAvailableNetworkBuffering_ageCullingWorks() throws Exception { 125 // Buffer potential candidates 1,2,3 & 4 126 List<Pair<ScanDetail, WifiConfiguration>> candidates = createFilteredQnsCandidates(mSsids, 127 mBssids, mFrequencies, mCaps, mLevels, mIsEphemeral); 128 mLastResortWatchdog.updateAvailableNetworks(candidates); 129 assertEquals(mLastResortWatchdog.getRecentAvailableNetworks().size(), 4); 130 131 // Repeatedly buffer candidates 1 & 2, MAX_BSSID_AGE - 1 times 132 candidates = createFilteredQnsCandidates(Arrays.copyOfRange(mSsids, 0, 2), 133 Arrays.copyOfRange(mBssids, 0, 2), 134 Arrays.copyOfRange(mFrequencies, 0, 2), 135 Arrays.copyOfRange(mCaps, 0, 2), 136 Arrays.copyOfRange(mLevels, 0, 2), 137 Arrays.copyOfRange(mIsEphemeral, 0, 2)); 138 for (int i = 0; i < WifiLastResortWatchdog.MAX_BSSID_AGE - 1; i++) { 139 mLastResortWatchdog.updateAvailableNetworks(candidates); 140 assertEquals(mLastResortWatchdog.getRecentAvailableNetworks().get(mBssids[0]).age, 0); 141 assertEquals(mLastResortWatchdog.getRecentAvailableNetworks().get(mBssids[1]).age, 0); 142 assertEquals(mLastResortWatchdog.getRecentAvailableNetworks().get(mBssids[2]).age, 143 i + 1); 144 assertEquals(mLastResortWatchdog.getRecentAvailableNetworks().get(mBssids[3]).age, 145 i + 1); 146 } 147 assertEquals(mLastResortWatchdog.getRecentAvailableNetworks().size(), 4); 148 149 // One more buffering should age and cull candidates 2 & 3 150 mLastResortWatchdog.updateAvailableNetworks(candidates); 151 assertEquals(mLastResortWatchdog.getRecentAvailableNetworks().size(), 2); 152 }; 153 154 /** 155 * Case #2: Culling of old networks 156 * Part 1: 157 * This test starts with 4 networks seen, it then buffers N=MAX_BSSID_AGE empty scans 158 * Expected behaviour: All networks are culled from recentAvailableNetworks 159 * 160 * Part 2: 161 * Buffer some more empty scans just to make sure nothing breaks 162 */ 163 @Test 164 public void testAvailableNetworkBuffering_emptyBufferWithEmptyScanResults() throws Exception { 165 // Buffer potential candidates 1,2,3 & 4 166 List<Pair<ScanDetail, WifiConfiguration>> candidates = createFilteredQnsCandidates(mSsids, 167 mBssids, mFrequencies, mCaps, mLevels, mIsEphemeral); 168 mLastResortWatchdog.updateAvailableNetworks(candidates); 169 assertEquals(mLastResortWatchdog.getRecentAvailableNetworks().size(), 4); 170 171 // Repeatedly buffer with no candidates 172 candidates = createFilteredQnsCandidates(Arrays.copyOfRange(mSsids, 0, 0), 173 Arrays.copyOfRange(mBssids, 0, 0), 174 Arrays.copyOfRange(mFrequencies, 0, 0), 175 Arrays.copyOfRange(mCaps, 0, 0), 176 Arrays.copyOfRange(mLevels, 0, 0), 177 Arrays.copyOfRange(mIsEphemeral, 0, 0)); 178 for (int i = 0; i < WifiLastResortWatchdog.MAX_BSSID_AGE; i++) { 179 mLastResortWatchdog.updateAvailableNetworks(candidates); 180 } 181 assertEquals(mLastResortWatchdog.getRecentAvailableNetworks().size(), 0); 182 for (int i = 0; i < WifiLastResortWatchdog.MAX_BSSID_AGE; i++) { 183 mLastResortWatchdog.updateAvailableNetworks(candidates); 184 } 185 assertEquals(mLastResortWatchdog.getRecentAvailableNetworks().size(), 0); 186 }; 187 188 /** 189 * Case 3: Adding more networks over time 190 * In this test, each successive (4 total) scan result buffers one more network. 191 * Expected behavior: recentAvailableNetworks grows with number of scan results 192 */ 193 @Test 194 public void testAvailableNetworkBuffering_addNewNetworksOverTime() throws Exception { 195 List<Pair<ScanDetail, WifiConfiguration>> candidates; 196 // Buffer (i) scan results with each successive scan result 197 for (int i = 1; i <= mSsids.length; i++) { 198 candidates = createFilteredQnsCandidates(Arrays.copyOfRange(mSsids, 0, i), 199 Arrays.copyOfRange(mBssids, 0, i), 200 Arrays.copyOfRange(mFrequencies, 0, i), 201 Arrays.copyOfRange(mCaps, 0, i), 202 Arrays.copyOfRange(mLevels, 0, i), 203 Arrays.copyOfRange(mIsEphemeral, 0, i)); 204 mLastResortWatchdog.updateAvailableNetworks(candidates); 205 assertEquals(mLastResortWatchdog.getRecentAvailableNetworks().size(), i); 206 for (int j = 0; j < i; j++) { 207 assertEquals( 208 mLastResortWatchdog.getRecentAvailableNetworks().get(mBssids[j]).age, 0); 209 } 210 } 211 }; 212 213 /** 214 * Case 4: Test buffering with ephemeral networks & toString() 215 * This test is the same as Case 1, but it also includes ephemeral networks. toString is also 216 * smoke tested at various places in this test 217 * Expected behaviour: 4 networks added initially (2 ephemeral). After MAX_BSSID_AGE more 218 * bufferings, 2 are culled (leaving 1 ephemeral, one normal). toString method should execute 219 * without breaking anything. 220 */ 221 @Test 222 public void testAvailableNetworkBuffering_multipleNetworksSomeEphemeral() throws Exception { 223 boolean[] isEphemeral = {true, false, true, false}; 224 225 // Buffer potential candidates 1,2,3 & 4 226 List<Pair<ScanDetail, WifiConfiguration>> candidates = createFilteredQnsCandidates(mSsids, 227 mBssids, mFrequencies, mCaps, mLevels, isEphemeral); 228 mLastResortWatchdog.updateAvailableNetworks(candidates); 229 assertEquals(mLastResortWatchdog.getRecentAvailableNetworks().size(), 4); 230 231 // Repeatedly buffer candidates 1 & 2, MAX_BSSID_AGE - 1 times 232 candidates = createFilteredQnsCandidates(Arrays.copyOfRange(mSsids, 0, 2), 233 Arrays.copyOfRange(mBssids, 0, 2), 234 Arrays.copyOfRange(mFrequencies, 0, 2), 235 Arrays.copyOfRange(mCaps, 0, 2), 236 Arrays.copyOfRange(mLevels, 0, 2), 237 Arrays.copyOfRange(isEphemeral, 0, 2)); 238 for (int i = 0; i < WifiLastResortWatchdog.MAX_BSSID_AGE - 1; i++) { 239 mLastResortWatchdog.updateAvailableNetworks(candidates); 240 mLastResortWatchdog.toString(); 241 assertEquals(mLastResortWatchdog.getRecentAvailableNetworks().get(mBssids[0]).age, 0); 242 assertEquals(mLastResortWatchdog.getRecentAvailableNetworks().get(mBssids[1]).age, 0); 243 assertEquals(mLastResortWatchdog.getRecentAvailableNetworks().get(mBssids[2]).age, 244 i + 1); 245 assertEquals(mLastResortWatchdog.getRecentAvailableNetworks().get(mBssids[3]).age, 246 i + 1); 247 } 248 assertEquals(mLastResortWatchdog.getRecentAvailableNetworks().size(), 4); 249 250 // One more buffering should age and cull candidates 2 & 3 251 mLastResortWatchdog.updateAvailableNetworks(candidates); 252 assertEquals(mLastResortWatchdog.getRecentAvailableNetworks().size(), 2); 253 mLastResortWatchdog.toString(); 254 }; 255 256 /** 257 * Case 5: Test failure counting, incrementing a specific BSSID 258 * Test has 4 networks buffered, increment each different failure type on one of them 259 * Expected behaviour: See failure counts for the specific failures rise to the appropriate 260 * level for the specific network 261 */ 262 @Test 263 public void testFailureCounting_countFailuresForSingleBssid() throws Exception { 264 int associationRejections = 5; 265 int authenticationFailures = 9; 266 int dhcpFailures = 11; 267 // Buffer potential candidates 1,2,3 & 4 268 List<Pair<ScanDetail, WifiConfiguration>> candidates = createFilteredQnsCandidates(mSsids, 269 mBssids, mFrequencies, mCaps, mLevels, mIsEphemeral, mHasEverConnected); 270 mLastResortWatchdog.updateAvailableNetworks(candidates); 271 272 // Ensure new networks have zero'ed failure counts 273 for (int i = 0; i < mSsids.length; i++) { 274 assertFailureCountEquals(mBssids[i], 0, 0, 0); 275 } 276 277 //Increment failure count for each network and failure type 278 int net = 0; 279 for (int i = 0; i < associationRejections; i++) { 280 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(mSsids[net], mBssids[net], 281 WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 282 assertEquals(i + 1, mLastResortWatchdog.getRecentAvailableNetworks() 283 .get(mBssids[net]).associationRejection); 284 } 285 net = 1; 286 for (int i = 0; i < authenticationFailures; i++) { 287 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(mSsids[net], mBssids[net], 288 WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION); 289 assertEquals(i + 1, mLastResortWatchdog.getRecentAvailableNetworks() 290 .get(mBssids[net]).authenticationFailure); 291 } 292 net = 2; 293 for (int i = 0; i < dhcpFailures; i++) { 294 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(mSsids[net], mBssids[net], 295 WifiLastResortWatchdog.FAILURE_CODE_DHCP); 296 assertEquals(i + 1, mLastResortWatchdog.getRecentAvailableNetworks() 297 .get(mBssids[net]).dhcpFailure); 298 } 299 assertFailureCountEquals(mBssids[0], associationRejections, 0, 0); 300 assertFailureCountEquals(mBssids[1], 0, authenticationFailures, 0); 301 assertFailureCountEquals(mBssids[2], 0, 0, dhcpFailures); 302 assertFailureCountEquals(mBssids[3], 0, 0, 0); 303 } 304 305 /** 306 * Case 6: Test failure counting, incrementing a specific BSSID, with some ephemeral networks 307 * Almost identical to test case 5. 308 * Test has 4 networks buffered (two are ephemeral), increment each different failure type on 309 * one of them. 310 * Expected behavior: See failure counts for the specific failures rise to the appropriate 311 * level for the specific network 312 */ 313 @Test 314 public void testFailureCounting_countFailuresForSingleBssidWithEphemeral() throws Exception { 315 int associationRejections = 5; 316 int authenticationFailures = 9; 317 int dhcpFailures = 11; 318 boolean[] mIsEphemeral = {false, true, false, true}; 319 // Buffer potential candidates 1,2,3 & 4 320 List<Pair<ScanDetail, WifiConfiguration>> candidates = createFilteredQnsCandidates(mSsids, 321 mBssids, mFrequencies, mCaps, mLevels, mIsEphemeral, mHasEverConnected); 322 mLastResortWatchdog.updateAvailableNetworks(candidates); 323 324 // Ensure new networks have zero'ed failure counts 325 for (int i = 0; i < mSsids.length; i++) { 326 assertFailureCountEquals(mBssids[i], 0, 0, 0); 327 } 328 329 //Increment failure count for each network and failure type 330 int net = 0; 331 for (int i = 0; i < associationRejections; i++) { 332 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(mSsids[net], mBssids[net], 333 WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 334 assertEquals(mLastResortWatchdog.getRecentAvailableNetworks() 335 .get(mBssids[net]).associationRejection, i + 1); 336 } 337 net = 1; 338 for (int i = 0; i < authenticationFailures; i++) { 339 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(mSsids[net], mBssids[net], 340 WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION); 341 assertEquals(mLastResortWatchdog.getRecentAvailableNetworks() 342 .get(mBssids[net]).authenticationFailure, i + 1); 343 } 344 net = 2; 345 for (int i = 0; i < dhcpFailures; i++) { 346 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(mSsids[net], mBssids[net], 347 WifiLastResortWatchdog.FAILURE_CODE_DHCP); 348 assertEquals(mLastResortWatchdog.getRecentAvailableNetworks() 349 .get(mBssids[net]).dhcpFailure, i + 1); 350 } 351 assertFailureCountEquals(mBssids[0], associationRejections, 0, 0); 352 assertFailureCountEquals(mBssids[1], 0, authenticationFailures, 0); 353 assertFailureCountEquals(mBssids[2], 0, 0, dhcpFailures); 354 assertFailureCountEquals(mBssids[3], 0, 0, 0); 355 } 356 357 /** 358 * Case 7: Test failure counting, incrementing a specific BSSID but with the wrong SSID given 359 * Test has 4 networks buffered, increment each different failure type on one of them but using 360 * the wrong ssid. 361 * Expected behavior: Failure counts will remain at zero for all networks 362 */ 363 @Test 364 public void testFailureCounting_countFailuresForSingleBssidWrongSsid() throws Exception { 365 String badSsid = "ItHertzWhenIP"; 366 int associationRejections = 5; 367 int authenticationFailures = 9; 368 int dhcpFailures = 11; 369 // Buffer potential candidates 1,2,3 & 4 370 List<Pair<ScanDetail, WifiConfiguration>> candidates = createFilteredQnsCandidates(mSsids, 371 mBssids, mFrequencies, mCaps, mLevels, mIsEphemeral, mHasEverConnected); 372 mLastResortWatchdog.updateAvailableNetworks(candidates); 373 374 // Ensure new networks have zero'ed failure counts 375 for (int i = 0; i < mSsids.length; i++) { 376 assertFailureCountEquals(mBssids[i], 0, 0, 0); 377 } 378 379 //Increment failure count for each network and failure type 380 int net = 0; 381 for (int i = 0; i < associationRejections; i++) { 382 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(badSsid, mBssids[net], 383 WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 384 } 385 net = 1; 386 for (int i = 0; i < authenticationFailures; i++) { 387 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(badSsid, mBssids[net], 388 WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION); 389 } 390 net = 2; 391 for (int i = 0; i < dhcpFailures; i++) { 392 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(badSsid, mBssids[net], 393 WifiLastResortWatchdog.FAILURE_CODE_DHCP); 394 } 395 396 // Ensure all networks still have zero failure count 397 for (int i = 0; i < mSsids.length; i++) { 398 assertFailureCountEquals(mBssids[i], 0, 0, 0); 399 } 400 } 401 402 /** 403 * Case 8: Test failure counting, increment a bssid that does not exist 404 * Test has 4 networks buffered, increment each failure type, but using the wrong bssid 405 * Expected behavior: Failure counts will remain at zero for all networks 406 */ 407 @Test 408 public void testFailureCounting_countFailuresForNonexistentBssid() throws Exception { 409 String badBssid = "de:ad:be:ee:e3:ef"; 410 int associationRejections = 5; 411 int authenticationFailures = 9; 412 int dhcpFailures = 11; 413 // Buffer potential candidates 1,2,3 & 4 414 List<Pair<ScanDetail, WifiConfiguration>> candidates = createFilteredQnsCandidates(mSsids, 415 mBssids, mFrequencies, mCaps, mLevels, mIsEphemeral, mHasEverConnected); 416 mLastResortWatchdog.updateAvailableNetworks(candidates); 417 418 // Ensure new networks have zero'ed failure counts 419 for (int i = 0; i < mSsids.length; i++) { 420 assertFailureCountEquals(mBssids[i], 0, 0, 0); 421 } 422 423 //Increment failure count for each network and failure type 424 int net = 0; 425 for (int i = 0; i < associationRejections; i++) { 426 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(mSsids[net], badBssid, 427 WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 428 } 429 net = 1; 430 for (int i = 0; i < authenticationFailures; i++) { 431 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(mSsids[net], badBssid, 432 WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION); 433 } 434 net = 2; 435 for (int i = 0; i < dhcpFailures; i++) { 436 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(mSsids[net], badBssid, 437 WifiLastResortWatchdog.FAILURE_CODE_DHCP); 438 } 439 440 // Ensure all networks still have zero failure count 441 for (int i = 0; i < mSsids.length; i++) { 442 assertFailureCountEquals(mBssids[i], 0, 0, 0); 443 } 444 } 445 446 /** 447 * Case 9: Test Failure Counting, using the "Any" BSSID 448 * Test has 4 buffered networks, two of which share the same SSID (different mBssids) 449 * Each failure type is incremented for the shared SSID, but with BSSID "any" 450 * Expected Behavior: Both networks increment their counts in tandem 451 */ 452 @Test 453 public void testFailureCounting_countFailuresForAnyBssid() throws Exception { 454 String[] ssids = {"\"test1\"", "\"test2\"", "\"test1\"", "\"test4\""}; 455 int associationRejections = 5; 456 int authenticationFailures = 9; 457 int dhcpFailures = 11; 458 // Buffer potential candidates 1,2,3 & 4 459 List<Pair<ScanDetail, WifiConfiguration>> candidates = createFilteredQnsCandidates(ssids, 460 mBssids, mFrequencies, mCaps, mLevels, mIsEphemeral, mHasEverConnected); 461 mLastResortWatchdog.updateAvailableNetworks(candidates); 462 463 // Ensure new networks have zero'ed failure counts 464 for (int i = 0; i < ssids.length; i++) { 465 assertFailureCountEquals(mBssids[i], 0, 0, 0); 466 } 467 468 //Increment failure count for each network and failure type 469 int net = 0; 470 for (int i = 0; i < associationRejections; i++) { 471 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 472 ssids[0], WifiLastResortWatchdog.BSSID_ANY, 473 WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 474 } 475 net = 1; 476 for (int i = 0; i < authenticationFailures; i++) { 477 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 478 ssids[0], WifiLastResortWatchdog.BSSID_ANY, 479 WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION); 480 } 481 net = 2; 482 for (int i = 0; i < dhcpFailures; i++) { 483 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 484 ssids[0], WifiLastResortWatchdog.BSSID_ANY, 485 WifiLastResortWatchdog.FAILURE_CODE_DHCP); 486 } 487 assertFailureCountEquals(mBssids[0], associationRejections, authenticationFailures, 488 dhcpFailures); 489 assertFailureCountEquals(mBssids[1], 0, 0, 0); 490 assertFailureCountEquals(mBssids[2], associationRejections, authenticationFailures, 491 dhcpFailures); 492 assertFailureCountEquals(mBssids[3], 0, 0, 0); 493 } 494 495 /** 496 * Case 10: Test Failure Counting, using the "Any" BSSID for nonexistent SSID 497 * Test has 4 buffered networks, two of which share the same SSID (different mBssids) 498 * Each failure type is incremented for a bad SSID (doesn't exist), but with BSSID "any" 499 * Expected Behavior: No Failures counted 500 */ 501 @Test 502 public void testFailureCounting_countFailuresForAnyBssidNonexistentSsid() throws Exception { 503 int associationRejections = 5; 504 int authenticationFailures = 9; 505 int dhcpFailures = 11; 506 String badSsid = "DropItLikeIt'sHotSpot"; 507 // Buffer potential candidates 1,2,3 & 4 508 List<Pair<ScanDetail, WifiConfiguration>> candidates = createFilteredQnsCandidates(mSsids, 509 mBssids, mFrequencies, mCaps, mLevels, mIsEphemeral, mHasEverConnected); 510 mLastResortWatchdog.updateAvailableNetworks(candidates); 511 512 // Ensure new networks have zero'ed failure counts 513 for (int i = 0; i < mSsids.length; i++) { 514 assertFailureCountEquals(mBssids[i], 0, 0, 0); 515 } 516 517 //Increment failure count for each network and failure type 518 int net = 0; 519 for (int i = 0; i < associationRejections; i++) { 520 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 521 badSsid, WifiLastResortWatchdog.BSSID_ANY, 522 WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 523 } 524 net = 1; 525 for (int i = 0; i < authenticationFailures; i++) { 526 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 527 badSsid, WifiLastResortWatchdog.BSSID_ANY, 528 WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION); 529 } 530 net = 2; 531 for (int i = 0; i < dhcpFailures; i++) { 532 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 533 badSsid, WifiLastResortWatchdog.BSSID_ANY, 534 WifiLastResortWatchdog.FAILURE_CODE_DHCP); 535 } 536 // Check that all network failure counts are still zero 537 for (int i = 0; i < mSsids.length; i++) { 538 assertFailureCountEquals(mBssids[i], 0, 0, 0); 539 } 540 } 541 542 /** 543 * Case 11: Test Failure Counting, over failure Threshold check 544 * Test has 4 buffered networks, cause FAILURE_THRESHOLD failures for each failure type to one 545 * of each network (leaving one unfailed). 546 * Expected Behavior: 3 of the Available Networks report OverFailureThreshold 547 */ 548 @Test 549 public void testFailureCounting_failureOverThresholdCheck() throws Exception { 550 int associationRejections = WifiLastResortWatchdog.FAILURE_THRESHOLD; 551 int authenticationFailures = WifiLastResortWatchdog.FAILURE_THRESHOLD; 552 int dhcpFailures = WifiLastResortWatchdog.FAILURE_THRESHOLD; 553 // Buffer potential candidates 1,2,3 & 4 554 List<Pair<ScanDetail, WifiConfiguration>> candidates = createFilteredQnsCandidates(mSsids, 555 mBssids, mFrequencies, mCaps, mLevels, mIsEphemeral, mHasEverConnected); 556 mLastResortWatchdog.updateAvailableNetworks(candidates); 557 558 // Ensure new networks have zero'ed failure counts 559 for (int i = 0; i < mSsids.length; i++) { 560 assertFailureCountEquals(mBssids[i], 0, 0, 0); 561 } 562 563 //Increment failure count for each network and failure type 564 int net = 0; 565 for (int i = 0; i < associationRejections; i++) { 566 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(mSsids[net], mBssids[net], 567 WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 568 } 569 net = 1; 570 for (int i = 0; i < authenticationFailures; i++) { 571 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(mSsids[net], mBssids[net], 572 WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION); 573 } 574 net = 2; 575 for (int i = 0; i < dhcpFailures; i++) { 576 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(mSsids[net], mBssids[net], 577 WifiLastResortWatchdog.FAILURE_CODE_DHCP); 578 } 579 assertEquals(true, mLastResortWatchdog.isOverFailureThreshold(mBssids[0])); 580 assertEquals(true, mLastResortWatchdog.isOverFailureThreshold(mBssids[1])); 581 assertEquals(true, mLastResortWatchdog.isOverFailureThreshold(mBssids[2])); 582 assertEquals(false, mLastResortWatchdog.isOverFailureThreshold(mBssids[3])); 583 } 584 585 /** 586 * Case 12: Test Failure Counting, under failure Threshold check 587 * Test has 4 buffered networks, cause FAILURE_THRESHOLD - 1 failures for each failure type to 588 * one of each network (leaving one unfailed). 589 * Expected Behavior: 0 of the Available Networks report OverFailureThreshold 590 */ 591 @Test 592 public void testFailureCounting_failureUnderThresholdCheck() throws Exception { 593 int associationRejections = WifiLastResortWatchdog.FAILURE_THRESHOLD - 1; 594 int authenticationFailures = WifiLastResortWatchdog.FAILURE_THRESHOLD - 1; 595 int dhcpFailures = WifiLastResortWatchdog.FAILURE_THRESHOLD - 1; 596 // Buffer potential candidates 1,2,3 & 4 597 List<Pair<ScanDetail, WifiConfiguration>> candidates = createFilteredQnsCandidates(mSsids, 598 mBssids, mFrequencies, mCaps, mLevels, mIsEphemeral, mHasEverConnected); 599 mLastResortWatchdog.updateAvailableNetworks(candidates); 600 601 // Ensure new networks have zero'ed failure counts 602 for (int i = 0; i < mSsids.length; i++) { 603 assertFailureCountEquals(mBssids[i], 0, 0, 0); 604 } 605 606 //Increment failure count for each network and failure type 607 int net = 0; 608 for (int i = 0; i < associationRejections; i++) { 609 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(mSsids[net], mBssids[net], 610 WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 611 } 612 net = 1; 613 for (int i = 0; i < authenticationFailures; i++) { 614 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(mSsids[net], mBssids[net], 615 WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION); 616 } 617 net = 2; 618 for (int i = 0; i < dhcpFailures; i++) { 619 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(mSsids[net], mBssids[net], 620 WifiLastResortWatchdog.FAILURE_CODE_DHCP); 621 } 622 assertEquals(false, mLastResortWatchdog.isOverFailureThreshold(mBssids[0])); 623 assertEquals(false, mLastResortWatchdog.isOverFailureThreshold(mBssids[1])); 624 assertEquals(false, mLastResortWatchdog.isOverFailureThreshold(mBssids[2])); 625 assertEquals(false, mLastResortWatchdog.isOverFailureThreshold(mBssids[3])); 626 } 627 628 /** 629 * Case 13: Test Failure Counting, available network buffering does not affect counts 630 * In this test: 631 * 4 networks are buffered 632 * Some number of failures are counted 633 * networks are buffered again 634 * Expected Behavior: Failure counts are not modified by buffering 635 */ 636 @Test 637 public void testAvailableNetworkBuffering_doesNotAffectFailureCounts() throws Exception { 638 int associationRejections = 5; 639 int authenticationFailures = 9; 640 int dhcpFailures = 11; 641 // Buffer potential candidates 1,2,3 & 4 642 List<Pair<ScanDetail, WifiConfiguration>> candidates = createFilteredQnsCandidates(mSsids, 643 mBssids, mFrequencies, mCaps, mLevels, mIsEphemeral, mHasEverConnected); 644 mLastResortWatchdog.updateAvailableNetworks(candidates); 645 646 // Ensure new networks have zero'ed failure counts 647 for (int i = 0; i < mSsids.length; i++) { 648 assertFailureCountEquals(mBssids[i], 0, 0, 0); 649 } 650 651 //Increment failure count for each network and failure type 652 int net = 0; 653 for (int i = 0; i < associationRejections; i++) { 654 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(mSsids[net], mBssids[net], 655 WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 656 assertEquals(i + 1, mLastResortWatchdog.getRecentAvailableNetworks() 657 .get(mBssids[net]).associationRejection); 658 } 659 net = 1; 660 for (int i = 0; i < authenticationFailures; i++) { 661 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(mSsids[net], mBssids[net], 662 WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION); 663 assertEquals(i + 1, mLastResortWatchdog.getRecentAvailableNetworks() 664 .get(mBssids[net]).authenticationFailure); 665 } 666 net = 2; 667 for (int i = 0; i < dhcpFailures; i++) { 668 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(mSsids[net], mBssids[net], 669 WifiLastResortWatchdog.FAILURE_CODE_DHCP); 670 assertEquals(i + 1, mLastResortWatchdog.getRecentAvailableNetworks() 671 .get(mBssids[net]).dhcpFailure); 672 } 673 // Check Each Network has appropriate failure count 674 assertFailureCountEquals(mBssids[0], associationRejections, 0, 0); 675 assertFailureCountEquals(mBssids[1], 0, authenticationFailures, 0); 676 assertFailureCountEquals(mBssids[2], 0, 0, dhcpFailures); 677 assertFailureCountEquals(mBssids[3], 0, 0, 0); 678 679 // Re-buffer all networks 680 for (int i = 0; i < WifiLastResortWatchdog.MAX_BSSID_AGE; i++) { 681 mLastResortWatchdog.updateAvailableNetworks(candidates); 682 } 683 684 // Check Each Network still has appropriate failure count 685 assertFailureCountEquals(mBssids[0], associationRejections, 0, 0); 686 assertFailureCountEquals(mBssids[1], 0, authenticationFailures, 0); 687 assertFailureCountEquals(mBssids[2], 0, 0, dhcpFailures); 688 assertFailureCountEquals(mBssids[3], 0, 0, 0); 689 } 690 691 /** 692 * Case 14: Test Failure Counting, culling of an old network will remove its failure counts 693 * In this test: 694 * 4 networks are buffered 695 * Some number of failures are counted for all networks 696 * 3 of the networks are buffered until the 4th dies of old age 697 * The 4th network is re-buffered 698 * Expected Behavior: Failure counts for the 4th network are cleared after re-buffering 699 */ 700 @Test 701 public void testAvailableNetworkBuffering_rebufferWipesCounts() throws Exception { 702 int associationRejections = 5; 703 int authenticationFailures = 9; 704 int dhcpFailures = 11; 705 // Buffer potential candidates 1,2,3 & 4 706 List<Pair<ScanDetail, WifiConfiguration>> candidates = createFilteredQnsCandidates(mSsids, 707 mBssids, mFrequencies, mCaps, mLevels, mIsEphemeral, mHasEverConnected); 708 mLastResortWatchdog.updateAvailableNetworks(candidates); 709 710 // Ensure new networks have zero'ed failure counts 711 for (int i = 0; i < mSsids.length; i++) { 712 assertFailureCountEquals(mBssids[i], 0, 0, 0); 713 } 714 715 //Increment failure count for each network and failure type 716 int net = 0; 717 for (int i = 0; i < associationRejections; i++) { 718 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(mSsids[net], mBssids[net], 719 WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 720 assertEquals(i + 1, mLastResortWatchdog.getRecentAvailableNetworks() 721 .get(mBssids[net]).associationRejection); 722 } 723 net = 1; 724 for (int i = 0; i < authenticationFailures; i++) { 725 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(mSsids[net], mBssids[net], 726 WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION); 727 assertEquals(i + 1, mLastResortWatchdog.getRecentAvailableNetworks() 728 .get(mBssids[net]).authenticationFailure); 729 } 730 net = 2; 731 for (int i = 0; i < dhcpFailures; i++) { 732 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(mSsids[net], mBssids[net], 733 WifiLastResortWatchdog.FAILURE_CODE_DHCP); 734 assertEquals(i + 1, mLastResortWatchdog.getRecentAvailableNetworks() 735 .get(mBssids[net]).dhcpFailure); 736 } 737 // Check Each Network has appropriate failure count 738 assertFailureCountEquals(mBssids[0], associationRejections, 0, 0); 739 assertFailureCountEquals(mBssids[1], 0, authenticationFailures, 0); 740 assertFailureCountEquals(mBssids[2], 0, 0, dhcpFailures); 741 assertFailureCountEquals(mBssids[3], 0, 0, 0); 742 743 // Re-buffer all networks except 'test1' until it dies of old age 744 candidates = createFilteredQnsCandidates(Arrays.copyOfRange(mSsids, 1, 4), 745 Arrays.copyOfRange(mBssids, 1, 4), 746 Arrays.copyOfRange(mFrequencies, 1, 4), 747 Arrays.copyOfRange(mCaps, 1, 4), 748 Arrays.copyOfRange(mLevels, 1, 4), 749 Arrays.copyOfRange(mIsEphemeral, 1, 4)); 750 for (int i = 0; i < WifiLastResortWatchdog.MAX_BSSID_AGE; i++) { 751 mLastResortWatchdog.updateAvailableNetworks(candidates); 752 } 753 assertEquals(3, mLastResortWatchdog.getRecentAvailableNetworks().size()); 754 // Re-buffer All networks, with 'test1' again 755 candidates = createFilteredQnsCandidates(mSsids, 756 mBssids, mFrequencies, mCaps, mLevels, mIsEphemeral, mHasEverConnected); 757 mLastResortWatchdog.updateAvailableNetworks(candidates); 758 759 // Check Each Network has appropriate failure count (network 1 should be zero'd) 760 assertFailureCountEquals(mBssids[0], 0, 0, 0); 761 assertFailureCountEquals(mBssids[1], 0, authenticationFailures, 0); 762 assertFailureCountEquals(mBssids[2], 0, 0, dhcpFailures); 763 assertFailureCountEquals(mBssids[3], 0, 0, 0); 764 } 765 766 /** 767 * Case 26: Test Failure Counting, null failure incrementation 768 * In this test: 769 * 4 networks are buffered 770 * Attempt to increment failures with null BSSID & SSID 771 * Expected behavior: Nothing breaks, no counts incremented 772 */ 773 @Test 774 public void testFailureCounting_nullInputsNoBreaky() { 775 int associationRejections = 5; 776 int authenticationFailures = 9; 777 int dhcpFailures = 11; 778 // Buffer potential candidates 1,2,3 & 4 779 List<Pair<ScanDetail, WifiConfiguration>> candidates = createFilteredQnsCandidates(mSsids, 780 mBssids, mFrequencies, mCaps, mLevels, mIsEphemeral, mHasEverConnected); 781 mLastResortWatchdog.updateAvailableNetworks(candidates); 782 783 // Ensure new networks have zero'ed failure counts 784 for (int i = 0; i < mSsids.length; i++) { 785 assertFailureCountEquals(mBssids[i], 0, 0, 0); 786 } 787 788 //Increment failure count for each network and failure type 789 int net = 0; 790 for (int i = 0; i < associationRejections; i++) { 791 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(null, mBssids[net], 792 WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 793 } 794 net = 1; 795 for (int i = 0; i < authenticationFailures; i++) { 796 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(mSsids[net], null, 797 WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION); 798 } 799 net = 2; 800 for (int i = 0; i < dhcpFailures; i++) { 801 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(null, null, 802 WifiLastResortWatchdog.FAILURE_CODE_DHCP); 803 } 804 805 // Ensure new networks have zero'ed failure counts 806 for (int i = 0; i < mSsids.length; i++) { 807 assertFailureCountEquals(mBssids[i], 0, 0, 0); 808 } 809 } 810 811 /** 812 * Case 27: Test Failure Counting, test all failures are counted across SSID 813 * In this test there are 8 networks, 814 * the first 4 networks have unique SSIDs amongst themselves, 815 * the last 4 networks share these SSIDs respectively, so there are 2 networks per SSID 816 * In this test we increment failure counts for the 'test1' ssid for a specific BSSID, and for 817 * the 'test2' ssid for BSSID_ANY. 818 * Expected behaviour: Failure counts for both networks on the same SSID are mirrored via both 819 * incrementation methods 820 */ 821 @Test 822 public void testFailureCounting_countFailuresAcrossSsids() throws Exception { 823 String[] ssids = {"\"test1\"", "\"test2\"", "\"test3\"", "\"test4\"", 824 "\"test1\"", "\"test2\"", "\"test3\"", "\"test4\""}; 825 String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4", "de:ad:ba:b1:e5:55", 826 "c0:ff:ee:ee:e3:ee", "6c:f3:7f:ae:3c:f3", "6c:f3:7f:ae:3c:f4", "d3:ad:ba:b1:35:55", 827 "c0:ff:ee:ee:33:ee"}; 828 int[] frequencies = {2437, 5180, 5180, 2437, 2437, 5180, 5180, 2437}; 829 String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]", 830 "[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]", 831 "[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]"}; 832 int[] levels = {-60, -86, -50, -62, -60, -86, -50, -62}; 833 boolean[] isEphemeral = {false, false, false, false, false, false, false, false}; 834 boolean[] hasEverConnected = {false, false, false, false, false, false, false, 835 false}; 836 int firstNetFails = 13; 837 int secondNetFails = 8; 838 // Buffer potential candidates 1,2,3 & 4 839 List<Pair<ScanDetail, WifiConfiguration>> candidates = createFilteredQnsCandidates(ssids, 840 bssids, frequencies, caps, levels, isEphemeral, hasEverConnected); 841 mLastResortWatchdog.updateAvailableNetworks(candidates); 842 843 // Ensure new networks have zero'ed failure counts 844 for (int i = 0; i < ssids.length; i++) { 845 assertFailureCountEquals(bssids[i], 0, 0, 0); 846 } 847 848 //Increment failure count for the first test network ssid & bssid 849 for (int i = 0; i < firstNetFails; i++) { 850 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 851 ssids[0], bssids[0], WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 852 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 853 ssids[0], bssids[0], WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION); 854 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 855 ssids[0], bssids[0], WifiLastResortWatchdog.FAILURE_CODE_DHCP); 856 } 857 //Increment failure count for the first test network ssid & BSSID_ANY 858 for (int i = 0; i < secondNetFails; i++) { 859 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 860 ssids[1], WifiLastResortWatchdog.BSSID_ANY, 861 WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 862 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 863 ssids[1], WifiLastResortWatchdog.BSSID_ANY, 864 WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION); 865 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 866 ssids[1], WifiLastResortWatchdog.BSSID_ANY, 867 WifiLastResortWatchdog.FAILURE_CODE_DHCP); 868 } 869 assertFailureCountEquals(bssids[0], firstNetFails, firstNetFails, firstNetFails); 870 assertFailureCountEquals(bssids[1], secondNetFails, secondNetFails, secondNetFails); 871 assertFailureCountEquals(bssids[2], 0, 0, 0); 872 assertFailureCountEquals(bssids[3], 0, 0, 0); 873 assertFailureCountEquals(bssids[4], firstNetFails, firstNetFails, firstNetFails); 874 assertFailureCountEquals(bssids[5], secondNetFails, secondNetFails, secondNetFails); 875 assertFailureCountEquals(bssids[6], 0, 0, 0); 876 assertFailureCountEquals(bssids[7], 0, 0, 0); 877 } 878 879 /** 880 * Case 15: Test failure counting, ensure failures still counted while connected 881 * Although failures should not occur while wifi is connected, race conditions are a thing, and 882 * I'd like the count to be incremented even while connected (Later test verifies that this 883 * can't cause a trigger though) 884 * Expected behavior: Failure counts increment like normal 885 */ 886 @Test 887 public void testFailureCounting_wifiIsConnectedDoesNotAffectCounting() throws Exception { 888 int associationRejections = 5; 889 int authenticationFailures = 9; 890 int dhcpFailures = 11; 891 892 // Set Watchdogs internal wifi state tracking to 'connected' 893 mLastResortWatchdog.connectedStateTransition(true); 894 895 // Buffer potential candidates 1,2,3 & 4 896 List<Pair<ScanDetail, WifiConfiguration>> candidates = createFilteredQnsCandidates(mSsids, 897 mBssids, mFrequencies, mCaps, mLevels, mIsEphemeral, mHasEverConnected); 898 mLastResortWatchdog.updateAvailableNetworks(candidates); 899 900 // Ensure new networks have zero'ed failure counts 901 for (int i = 0; i < mSsids.length; i++) { 902 assertFailureCountEquals(mBssids[i], 0, 0, 0); 903 } 904 905 //Increment failure count for each network and failure type 906 int net = 0; 907 for (int i = 0; i < associationRejections; i++) { 908 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(mSsids[net], mBssids[net], 909 WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 910 assertEquals(i + 1, mLastResortWatchdog.getRecentAvailableNetworks() 911 .get(mBssids[net]).associationRejection); 912 } 913 net = 1; 914 for (int i = 0; i < authenticationFailures; i++) { 915 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(mSsids[net], mBssids[net], 916 WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION); 917 assertEquals(i + 1, mLastResortWatchdog.getRecentAvailableNetworks() 918 .get(mBssids[net]).authenticationFailure); 919 } 920 net = 2; 921 for (int i = 0; i < dhcpFailures; i++) { 922 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(mSsids[net], mBssids[net], 923 WifiLastResortWatchdog.FAILURE_CODE_DHCP); 924 assertEquals(i + 1, mLastResortWatchdog.getRecentAvailableNetworks() 925 .get(mBssids[net]).dhcpFailure); 926 } 927 assertFailureCountEquals(mBssids[0], associationRejections, 0, 0); 928 assertFailureCountEquals(mBssids[1], 0, authenticationFailures, 0); 929 assertFailureCountEquals(mBssids[2], 0, 0, dhcpFailures); 930 assertFailureCountEquals(mBssids[3], 0, 0, 0); 931 } 932 933 /** 934 * Case 16: Test Failure Counting, entering ConnectedState clears all failure counts 935 * 4 Networks are buffered, cause various failures to 3 of them. Transition to ConnectedState 936 * Expected behavior: After transitioning, failure counts are reset to 0 937 */ 938 @Test 939 public void testFailureCounting_enteringWifiConnectedStateClearsCounts() throws Exception { 940 int associationRejections = 5; 941 int authenticationFailures = 9; 942 int dhcpFailures = 11; 943 944 // Buffer potential candidates 1,2,3 & 4 945 List<Pair<ScanDetail, WifiConfiguration>> candidates = createFilteredQnsCandidates(mSsids, 946 mBssids, mFrequencies, mCaps, mLevels, mIsEphemeral, mHasEverConnected); 947 mLastResortWatchdog.updateAvailableNetworks(candidates); 948 949 //Increment failure count for each network and failure type 950 int net = 0; 951 for (int i = 0; i < associationRejections; i++) { 952 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(mSsids[net], mBssids[net], 953 WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 954 } 955 net = 1; 956 for (int i = 0; i < authenticationFailures; i++) { 957 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(mSsids[net], mBssids[net], 958 WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION); 959 } 960 net = 2; 961 for (int i = 0; i < dhcpFailures; i++) { 962 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded(mSsids[net], mBssids[net], 963 WifiLastResortWatchdog.FAILURE_CODE_DHCP); 964 } 965 966 // Check that we have Failures 967 assertFailureCountEquals(mBssids[0], associationRejections, 0, 0); 968 assertFailureCountEquals(mBssids[1], 0, authenticationFailures, 0); 969 assertFailureCountEquals(mBssids[2], 0, 0, dhcpFailures); 970 971 // Transition to 'ConnectedState' 972 mLastResortWatchdog.connectedStateTransition(true); 973 974 // Check that we have no failures 975 for (int i = 0; i < mSsids.length; i++) { 976 assertFailureCountEquals(mBssids[i], 0, 0, 0); 977 } 978 } 979 980 /** 981 * Case 17: Test Trigger Condition, only some networks over threshold 982 * We have 4 buffered networks, increment failure counts on 3 of them, until all 3 are over 983 * threshold. 984 * Expected Behavior: Watchdog does not trigger 985 */ 986 @Test 987 public void testTriggerCondition_someNetworksOverFailureThreshold_allHaveEverConnected() 988 throws Exception { 989 int associationRejections = WifiLastResortWatchdog.FAILURE_THRESHOLD; 990 int authenticationFailures = WifiLastResortWatchdog.FAILURE_THRESHOLD + 2; 991 int dhcpFailures = WifiLastResortWatchdog.FAILURE_THRESHOLD + 3; 992 boolean[] hasEverConnected = {true, true, true, true}; 993 994 // Buffer potential candidates 1,2,3 & 4 995 List<Pair<ScanDetail, WifiConfiguration>> candidates = createFilteredQnsCandidates(mSsids, 996 mBssids, mFrequencies, mCaps, mLevels, mIsEphemeral, hasEverConnected); 997 mLastResortWatchdog.updateAvailableNetworks(candidates); 998 999 // Increment failure count for 3 networks and failure types, asserting each time that it 1000 // does not trigger, with only 3 over threshold 1001 boolean watchdogTriggered = false; 1002 int net = 0; 1003 for (int i = 0; i < associationRejections; i++) { 1004 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1005 mSsids[net], mBssids[net], WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 1006 assertEquals(false, watchdogTriggered); 1007 } 1008 net = 1; 1009 for (int i = 0; i < authenticationFailures; i++) { 1010 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1011 mSsids[net], mBssids[net], WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION); 1012 assertEquals(false, watchdogTriggered); 1013 } 1014 net = 2; 1015 for (int i = 0; i < dhcpFailures; i++) { 1016 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1017 mSsids[net], mBssids[net], WifiLastResortWatchdog.FAILURE_CODE_DHCP); 1018 assertEquals(false, watchdogTriggered); 1019 } 1020 1021 // Check that we have Failures 1022 assertFailureCountEquals(mBssids[0], associationRejections, 0, 0); 1023 assertFailureCountEquals(mBssids[1], 0, authenticationFailures, 0); 1024 assertFailureCountEquals(mBssids[2], 0, 0, dhcpFailures); 1025 1026 // Add one more failure to one of the already over threshold networks, assert that it 1027 // does not trigger 1028 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1029 mSsids[0], mBssids[0], WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 1030 assertEquals(false, watchdogTriggered); 1031 } 1032 1033 /** 1034 * Case 18: Test Trigger Condition, watchdog fires once, then deactivates 1035 * In this test we have 4 networks, which we have connected to in the past. Failures are 1036 * incremented until all networks but one are over failure threshold, and then a few more times. 1037 * 1038 * Expected behavior: The watchdog triggers once as soon as all failures are over threshold, 1039 * but stops triggering for subsequent failures 1040 */ 1041 @Test 1042 public void testTriggerCondition_allNetworksOverFailureThreshold_allHaveEverConnected() 1043 throws Exception { 1044 int associationRejections = WifiLastResortWatchdog.FAILURE_THRESHOLD; 1045 int authenticationFailures = WifiLastResortWatchdog.FAILURE_THRESHOLD + 2; 1046 int dhcpFailures = WifiLastResortWatchdog.FAILURE_THRESHOLD + 3; 1047 boolean[] hasEverConnected = {true, true, true, true}; 1048 1049 // Buffer potential candidates 1,2,3 & 4 1050 List<Pair<ScanDetail, WifiConfiguration>> candidates = createFilteredQnsCandidates(mSsids, 1051 mBssids, mFrequencies, mCaps, mLevels, mIsEphemeral, hasEverConnected); 1052 mLastResortWatchdog.updateAvailableNetworks(candidates); 1053 1054 // Bring 3 of the 4 networks over failure Threshold without triggering watchdog 1055 boolean watchdogTriggered = false; 1056 int net = 0; 1057 for (int i = 0; i < associationRejections; i++) { 1058 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1059 mSsids[net], mBssids[net], WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 1060 assertEquals(false, watchdogTriggered); 1061 } 1062 net = 1; 1063 for (int i = 0; i < authenticationFailures; i++) { 1064 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1065 mSsids[net], mBssids[net], WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION); 1066 assertEquals(false, watchdogTriggered); 1067 } 1068 net = 2; 1069 for (int i = 0; i < dhcpFailures; i++) { 1070 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1071 mSsids[net], mBssids[net], WifiLastResortWatchdog.FAILURE_CODE_DHCP); 1072 assertEquals(false, watchdogTriggered); 1073 } 1074 1075 // Bring the remaining unfailed network upto 1 less than the failure threshold 1076 net = 3; 1077 for (int i = 0; i < WifiLastResortWatchdog.FAILURE_THRESHOLD - 1; i++) { 1078 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1079 mSsids[net], mBssids[net], WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 1080 assertEquals(false, watchdogTriggered); 1081 } 1082 // Increment failure count once more, check that watchdog triggered this time 1083 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1084 mSsids[net], mBssids[net], WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 1085 mLastResortWatchdog.updateAvailableNetworks(candidates); 1086 assertEquals(true, watchdogTriggered); 1087 1088 // Increment failure count 5 more times, watchdog should not trigger 1089 for (int i = 0; i < 5; i++) { 1090 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1091 mSsids[net], mBssids[net], WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 1092 assertEquals(false, watchdogTriggered); 1093 } 1094 } 1095 1096 /** 1097 * Case 19: Test Trigger Condition, all networks over failure threshold, one has ever connected 1098 * In this test we have 4 networks, only one has connected in the past. Failures are 1099 * incremented until all networks but one are over failure threshold, and then a few more times. 1100 * 1101 * Expected behavior: The watchdog triggers once as soon as all failures are over threshold, 1102 * but stops triggering for subsequent failures 1103 */ 1104 @Test 1105 public void testTriggerCondition_allNetworksOverFailureThreshold_oneHaveEverConnected() 1106 throws Exception { 1107 int associationRejections = WifiLastResortWatchdog.FAILURE_THRESHOLD; 1108 int authenticationFailures = WifiLastResortWatchdog.FAILURE_THRESHOLD + 2; 1109 int dhcpFailures = WifiLastResortWatchdog.FAILURE_THRESHOLD + 3; 1110 boolean[] hasEverConnected = {false, true, false, false}; 1111 1112 // Buffer potential candidates 1,2,3 & 4 1113 List<Pair<ScanDetail, WifiConfiguration>> candidates = createFilteredQnsCandidates(mSsids, 1114 mBssids, mFrequencies, mCaps, mLevels, mIsEphemeral, hasEverConnected); 1115 mLastResortWatchdog.updateAvailableNetworks(candidates); 1116 1117 // Bring 3 of the 4 networks over failure Threshold without triggering watchdog 1118 boolean watchdogTriggered = false; 1119 int net = 0; 1120 for (int i = 0; i < associationRejections; i++) { 1121 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1122 mSsids[net], mBssids[net], WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 1123 assertEquals(false, watchdogTriggered); 1124 } 1125 net = 1; 1126 for (int i = 0; i < authenticationFailures; i++) { 1127 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1128 mSsids[net], mBssids[net], WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION); 1129 assertEquals(false, watchdogTriggered); 1130 } 1131 net = 2; 1132 for (int i = 0; i < dhcpFailures; i++) { 1133 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1134 mSsids[net], mBssids[net], WifiLastResortWatchdog.FAILURE_CODE_DHCP); 1135 assertEquals(false, watchdogTriggered); 1136 } 1137 1138 // Bring the remaining unfailed network upto 1 less than the failure threshold 1139 net = 3; 1140 for (int i = 0; i < WifiLastResortWatchdog.FAILURE_THRESHOLD - 1; i++) { 1141 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1142 mSsids[net], mBssids[net], WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 1143 assertEquals(false, watchdogTriggered); 1144 } 1145 // Increment failure count once more, check that watchdog triggered this time 1146 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1147 mSsids[net], mBssids[net], WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 1148 mLastResortWatchdog.updateAvailableNetworks(candidates); 1149 assertEquals(true, watchdogTriggered); 1150 1151 // Increment failure count 5 more times, watchdog should not trigger 1152 for (int i = 0; i < 5; i++) { 1153 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1154 mSsids[net], mBssids[net], WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 1155 assertEquals(false, watchdogTriggered); 1156 } 1157 } 1158 1159 /** 1160 * Case 20: Test Trigger Condition, all networks over failure threshold, 0 have ever connected 1161 * In this test we have 4 networks, none have ever connected. Failures are 1162 * incremented until all networks but one are over failure threshold, and then a few more times. 1163 * 1164 * Expected behavior: The watchdog does not trigger 1165 */ 1166 @Test 1167 public void testTriggerCondition_allNetworksOverFailureThreshold_zeroHaveEverConnected() 1168 throws Exception { 1169 int associationRejections = WifiLastResortWatchdog.FAILURE_THRESHOLD + 1; 1170 int authenticationFailures = WifiLastResortWatchdog.FAILURE_THRESHOLD + 2; 1171 int dhcpFailures = WifiLastResortWatchdog.FAILURE_THRESHOLD + 3; 1172 1173 // Buffer potential candidates 1,2,3 & 4 1174 List<Pair<ScanDetail, WifiConfiguration>> candidates = createFilteredQnsCandidates(mSsids, 1175 mBssids, mFrequencies, mCaps, mLevels, mIsEphemeral, mHasEverConnected); 1176 mLastResortWatchdog.updateAvailableNetworks(candidates); 1177 1178 // Count failures on all 4 networks until all of them are over the failure threshold 1179 boolean watchdogTriggered = false; 1180 int net = 0; 1181 for (int i = 0; i < associationRejections; i++) { 1182 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1183 mSsids[net], mBssids[net], WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 1184 assertEquals(false, watchdogTriggered); 1185 } 1186 net = 1; 1187 for (int i = 0; i < authenticationFailures; i++) { 1188 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1189 mSsids[net], mBssids[net], WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION); 1190 assertEquals(false, watchdogTriggered); 1191 } 1192 net = 2; 1193 for (int i = 0; i < dhcpFailures; i++) { 1194 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1195 mSsids[net], mBssids[net], WifiLastResortWatchdog.FAILURE_CODE_DHCP); 1196 assertEquals(false, watchdogTriggered); 1197 } 1198 net = 3; 1199 for (int i = 0; i < WifiLastResortWatchdog.FAILURE_THRESHOLD + 1; i++) { 1200 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1201 mSsids[net], mBssids[net], WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 1202 assertEquals(false, watchdogTriggered); 1203 } 1204 } 1205 1206 /** 1207 * Case 21: Test Trigger Condition, Conditions right to trigger, but wifi is connected 1208 * In this test we have 4 networks, all have connected in the past 1209 * incremented until all networks but one are over failure threshold, and then a few more times. 1210 * 1211 * Expected behavior: The watchdog does not trigger 1212 */ 1213 @Test 1214 public void testTriggerCondition_allNetworksOverFailureThreshold_isConnected() 1215 throws Exception { 1216 int associationRejections = WifiLastResortWatchdog.FAILURE_THRESHOLD + 1; 1217 int authenticationFailures = WifiLastResortWatchdog.FAILURE_THRESHOLD + 2; 1218 int dhcpFailures = WifiLastResortWatchdog.FAILURE_THRESHOLD + 3; 1219 1220 // Buffer potential candidates 1,2,3 & 4 1221 List<Pair<ScanDetail, WifiConfiguration>> candidates = createFilteredQnsCandidates(mSsids, 1222 mBssids, mFrequencies, mCaps, mLevels, mIsEphemeral, mHasEverConnected); 1223 mLastResortWatchdog.updateAvailableNetworks(candidates); 1224 1225 // Set Watchdogs internal wifi state tracking to 'connected' 1226 mLastResortWatchdog.connectedStateTransition(true); 1227 1228 // Count failures on all 4 networks until all of them are over the failure threshold 1229 boolean watchdogTriggered = false; 1230 int net = 0; 1231 for (int i = 0; i < associationRejections; i++) { 1232 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1233 mSsids[net], mBssids[net], WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 1234 assertEquals(false, watchdogTriggered); 1235 } 1236 net = 1; 1237 for (int i = 0; i < authenticationFailures; i++) { 1238 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1239 mSsids[net], mBssids[net], WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION); 1240 assertEquals(false, watchdogTriggered); 1241 } 1242 net = 2; 1243 for (int i = 0; i < dhcpFailures; i++) { 1244 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1245 mSsids[net], mBssids[net], WifiLastResortWatchdog.FAILURE_CODE_DHCP); 1246 assertEquals(false, watchdogTriggered); 1247 } 1248 net = 3; 1249 for (int i = 0; i < WifiLastResortWatchdog.FAILURE_THRESHOLD + 1; i++) { 1250 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1251 mSsids[net], mBssids[net], WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 1252 assertEquals(false, watchdogTriggered); 1253 } 1254 } 1255 1256 private void incrementFailuresUntilTrigger(String[] ssids, String[] bssids) { 1257 // Bring 3 of the 4 networks over failure Threshold without triggering watchdog 1258 boolean watchdogTriggered = false; 1259 for (int i = 0; i < WifiLastResortWatchdog.FAILURE_THRESHOLD; i++) { 1260 for (int j = 0; j < ssids.length - 1; j++) { 1261 watchdogTriggered = mLastResortWatchdog 1262 .noteConnectionFailureAndTriggerIfNeeded(ssids[j], bssids[j], 1263 WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 1264 assertEquals(false, watchdogTriggered); 1265 } 1266 } 1267 for (int i = 0; i < WifiLastResortWatchdog.FAILURE_THRESHOLD - 1; i++) { 1268 watchdogTriggered = mLastResortWatchdog 1269 .noteConnectionFailureAndTriggerIfNeeded(ssids[ssids.length - 1], 1270 bssids[ssids.length - 1], WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 1271 assertEquals(false, watchdogTriggered); 1272 } 1273 1274 // Increment failure count once more, check that watchdog triggered this time 1275 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1276 ssids[ssids.length - 1], bssids[ssids.length - 1], 1277 WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 1278 assertEquals(true, watchdogTriggered); 1279 } 1280 1281 /** 1282 * Case 22: Test enabling/disabling of Watchdog Trigger, disabled after triggering 1283 * In this test, we have 4 networks. Increment failures until Watchdog triggers. Increment some 1284 * more failures. 1285 * Expected behavior: Watchdog trigger gets deactivated after triggering, and stops triggering 1286 */ 1287 @Test 1288 public void testTriggerEnabling_disabledAfterTriggering() throws Exception { 1289 int associationRejections = WifiLastResortWatchdog.FAILURE_THRESHOLD; 1290 int authenticationFailures = WifiLastResortWatchdog.FAILURE_THRESHOLD + 2; 1291 int dhcpFailures = WifiLastResortWatchdog.FAILURE_THRESHOLD + 3; 1292 boolean[] hasEverConnected = {false, true, false, false}; 1293 1294 // Buffer potential candidates 1,2,3 & 4 1295 List<Pair<ScanDetail, WifiConfiguration>> candidates = createFilteredQnsCandidates(mSsids, 1296 mBssids, mFrequencies, mCaps, mLevels, mIsEphemeral, hasEverConnected); 1297 mLastResortWatchdog.updateAvailableNetworks(candidates); 1298 1299 incrementFailuresUntilTrigger(mSsids, mBssids); 1300 1301 // Increment failure count 5 more times, watchdog should not trigger 1302 for (int i = 0; i < 5; i++) { 1303 boolean watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1304 mSsids[3], mBssids[3], WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 1305 assertEquals(false, watchdogTriggered); 1306 } 1307 } 1308 1309 /** 1310 * Case 23: Test enabling/disabling of Watchdog Trigger, trigger re-enabled after connecting 1311 * In this test, we have 4 networks. Increment failures until Watchdog triggers and deactivates, 1312 * transition wifi to connected state, then increment failures until all networks over threshold 1313 * Expected behavior: Watchdog able to trigger again after transitioning to and from connected 1314 * state 1315 */ 1316 @Test 1317 public void testTriggerEnabling_enabledAfterConnecting() throws Exception { 1318 int associationRejections = WifiLastResortWatchdog.FAILURE_THRESHOLD; 1319 int authenticationFailures = WifiLastResortWatchdog.FAILURE_THRESHOLD + 2; 1320 int dhcpFailures = WifiLastResortWatchdog.FAILURE_THRESHOLD + 3; 1321 boolean[] hasEverConnected = {false, true, false, false}; 1322 boolean watchdogTriggered; 1323 // Buffer potential candidates 1,2,3 & 4 1324 List<Pair<ScanDetail, WifiConfiguration>> candidates = createFilteredQnsCandidates(mSsids, 1325 mBssids, mFrequencies, mCaps, mLevels, mIsEphemeral, hasEverConnected); 1326 mLastResortWatchdog.updateAvailableNetworks(candidates); 1327 1328 incrementFailuresUntilTrigger(mSsids, mBssids); 1329 1330 // Increment failure count 5 more times, ensure trigger is deactivated 1331 for (int i = 0; i < 5; i++) { 1332 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1333 mSsids[3], mBssids[3], WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 1334 mLastResortWatchdog.updateAvailableNetworks(candidates); 1335 assertEquals(false, watchdogTriggered); 1336 } 1337 1338 // transition Watchdog wifi state tracking to 'connected' then back to 'disconnected' 1339 mLastResortWatchdog.connectedStateTransition(true); 1340 mLastResortWatchdog.connectedStateTransition(false); 1341 1342 // Fail 3/4 networks until they're over threshold 1343 for (int i = 0; i < WifiLastResortWatchdog.FAILURE_THRESHOLD + 1; i++) { 1344 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1345 mSsids[0], mBssids[0], WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 1346 assertEquals(false, watchdogTriggered); 1347 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1348 mSsids[1], mBssids[1], WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION); 1349 assertEquals(false, watchdogTriggered); 1350 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1351 mSsids[2], mBssids[2], WifiLastResortWatchdog.FAILURE_CODE_DHCP); 1352 assertEquals(false, watchdogTriggered); 1353 } 1354 1355 // Bring the remaining unfailed network upto 1 less than the failure threshold 1356 for (int i = 0; i < WifiLastResortWatchdog.FAILURE_THRESHOLD - 1; i++) { 1357 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1358 mSsids[3], mBssids[3], WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 1359 assertEquals(false, watchdogTriggered); 1360 } 1361 // Increment failure count once more, check that watchdog triggered this time 1362 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1363 mSsids[3], mBssids[3], WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 1364 assertEquals(true, watchdogTriggered); 1365 } 1366 1367 /** 1368 * Case 24: Test enabling/disabling of Watchdog Trigger, trigger re-enabled after new network 1369 * In this test, we have 3 networks. Increment failures until Watchdog triggers and deactivates, 1370 * we then buffer a new network (network 4), then increment failures until all networks over 1371 * threshold Expected behavior: Watchdog able to trigger again after discovering a new network 1372 */ 1373 @Test 1374 public void testTriggerEnabling_enabledAfterNewNetwork() { 1375 int associationRejections = WifiLastResortWatchdog.FAILURE_THRESHOLD; 1376 int authenticationFailures = WifiLastResortWatchdog.FAILURE_THRESHOLD + 2; 1377 int dhcpFailures = WifiLastResortWatchdog.FAILURE_THRESHOLD + 3; 1378 boolean[] hasEverConnected = {false, true, false, false}; 1379 boolean watchdogTriggered; 1380 1381 // Buffer potential candidates 1,2,3 1382 List<Pair<ScanDetail, WifiConfiguration>> candidates = createFilteredQnsCandidates( 1383 Arrays.copyOfRange(mSsids, 0, 3), 1384 Arrays.copyOfRange(mBssids, 0, 3), 1385 Arrays.copyOfRange(mFrequencies, 0, 3), 1386 Arrays.copyOfRange(mCaps, 0, 3), 1387 Arrays.copyOfRange(mLevels, 0, 3), 1388 Arrays.copyOfRange(mIsEphemeral, 0, 3), 1389 Arrays.copyOfRange(hasEverConnected, 0, 3)); 1390 mLastResortWatchdog.updateAvailableNetworks(candidates); 1391 1392 incrementFailuresUntilTrigger(Arrays.copyOfRange(mSsids, 0, 3), 1393 Arrays.copyOfRange(mBssids, 0, 3)); 1394 1395 // Increment failure count 5 more times, ensure trigger is deactivated 1396 for (int i = 0; i < 5; i++) { 1397 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1398 mSsids[2], mBssids[2], WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 1399 mLastResortWatchdog.updateAvailableNetworks(candidates); 1400 assertEquals(false, watchdogTriggered); 1401 } 1402 1403 candidates = createFilteredQnsCandidates(mSsids, mBssids, mFrequencies, mCaps, mLevels, 1404 mIsEphemeral, hasEverConnected); 1405 mLastResortWatchdog.updateAvailableNetworks(candidates); 1406 1407 incrementFailuresUntilTrigger(mSsids, mBssids); 1408 1409 } 1410 1411 /** 1412 * Case 26: Test Metrics collection 1413 * Setup 5 networks (unique SSIDs). Fail them until watchdog triggers, with 1 network failing 1414 * association, 1 failing authentication, 2 failing dhcp and one failing both authentication and 1415 * dhcp, (over threshold for all these failures) 1416 * Expected behavior: Metrics are updated as follows 1417 * Triggers++ 1418 * # of Networks += 5 1419 * Triggers with Bad association++ 1420 * Triggers with Bad authentication++ 1421 * Triggers with Bad dhcp++ 1422 * Number of networks with bad association += 1 1423 * Number of networks with bad authentication += 2 1424 * Number of networks with bad dhcp += 3 1425 */ 1426 @Test 1427 public void testMetricsCollection() { 1428 String[] ssids = {"\"test1\"", "\"test2\"", "\"test3\"", "\"test4\"", "\"test5\""}; 1429 String[] bssids = {"6c:f3:7f:ae:8c:f3", "6c:f3:7f:ae:8c:f4", "de:ad:ba:b1:e5:55", 1430 "c0:ff:ee:ee:e3:ee", "6c:f3:7f:ae:3c:f3"}; 1431 int[] frequencies = {2437, 5180, 5180, 2437, 2437}; 1432 String[] caps = {"[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]", 1433 "[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]", "[WPA2-EAP-CCMP][ESS]"}; 1434 int[] levels = {-60, -86, -50, -62, -60}; 1435 boolean[] isEphemeral = {false, false, false, false, false}; 1436 boolean[] hasEverConnected = {true, false, false, false, false}; 1437 // Buffer potential candidates 1,2,3 & 4 1438 List<Pair<ScanDetail, WifiConfiguration>> candidates = createFilteredQnsCandidates(ssids, 1439 bssids, frequencies, caps, levels, isEphemeral, hasEverConnected); 1440 mLastResortWatchdog.updateAvailableNetworks(candidates); 1441 1442 // Ensure new networks have zero'ed failure counts 1443 for (int i = 0; i < ssids.length; i++) { 1444 assertFailureCountEquals(bssids[i], 0, 0, 0); 1445 } 1446 1447 //Increment failure count for the first test network ssid & bssid 1448 for (int i = 0; i < WifiLastResortWatchdog.FAILURE_THRESHOLD; i++) { 1449 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1450 ssids[1], bssids[1], WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION); 1451 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1452 ssids[2], bssids[2], WifiLastResortWatchdog.FAILURE_CODE_DHCP); 1453 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1454 ssids[3], bssids[3], WifiLastResortWatchdog.FAILURE_CODE_DHCP); 1455 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1456 ssids[4], bssids[4], WifiLastResortWatchdog.FAILURE_CODE_DHCP); 1457 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1458 ssids[4], bssids[4], WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION); 1459 mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1460 ssids[0], bssids[0], WifiLastResortWatchdog.FAILURE_CODE_ASSOCIATION); 1461 } 1462 1463 // Verify relevant WifiMetrics calls were made once with appropriate arguments 1464 verify(mWifiMetrics, times(1)).incrementNumLastResortWatchdogTriggers(); 1465 verify(mWifiMetrics, times(1)).addCountToNumLastResortWatchdogAvailableNetworksTotal(5); 1466 verify(mWifiMetrics, times(1)) 1467 .addCountToNumLastResortWatchdogBadAuthenticationNetworksTotal(2); 1468 verify(mWifiMetrics, times(1)) 1469 .incrementNumLastResortWatchdogTriggersWithBadAuthentication(); 1470 verify(mWifiMetrics, times(1)) 1471 .addCountToNumLastResortWatchdogBadAssociationNetworksTotal(1); 1472 verify(mWifiMetrics, times(1)).incrementNumLastResortWatchdogTriggersWithBadAssociation(); 1473 verify(mWifiMetrics, times(1)).addCountToNumLastResortWatchdogBadDhcpNetworksTotal(3); 1474 verify(mWifiMetrics, times(1)).incrementNumLastResortWatchdogTriggersWithBadDhcp(); 1475 } 1476 1477 /** 1478 * Case 21: Test config updates where new config is null. 1479 * Create a scan result with an associated config and update the available networks list. 1480 * Repeat this with a second scan result where the config is null. 1481 * Expected behavior: The stored config should not be lost overwritten. 1482 */ 1483 @Test 1484 public void testUpdateNetworkWithNullConfig() { 1485 List<Pair<ScanDetail, WifiConfiguration>> candidates = 1486 new ArrayList<Pair<ScanDetail, WifiConfiguration>>(); 1487 String ssid = mSsids[0].replaceAll("^\"+", "").replaceAll("\"+$", ""); 1488 ScanDetail scanDetail = new ScanDetail(WifiSsid.createFromAsciiEncoded(ssid), 1489 mBssids[0], mCaps[0], mLevels[0], mFrequencies[0], System.currentTimeMillis(), 0); 1490 WifiConfiguration config = mock(WifiConfiguration.class); 1491 WifiConfiguration.NetworkSelectionStatus networkSelectionStatus = 1492 mock(WifiConfiguration.NetworkSelectionStatus.class); 1493 when(config.getNetworkSelectionStatus()).thenReturn(networkSelectionStatus); 1494 when(networkSelectionStatus.getHasEverConnected()) 1495 .thenReturn(true); 1496 candidates.add(Pair.create(scanDetail, config)); 1497 mLastResortWatchdog.updateAvailableNetworks(candidates); 1498 1499 candidates.clear(); 1500 1501 candidates.add(Pair.create(scanDetail, null)); 1502 mLastResortWatchdog.updateAvailableNetworks(candidates); 1503 1504 boolean watchdogTriggered = false; 1505 for (int i = 0; i < WifiLastResortWatchdog.FAILURE_THRESHOLD; i++) { 1506 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1507 mSsids[0], mBssids[0], WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION); 1508 } 1509 assertEquals(true, watchdogTriggered); 1510 } 1511 1512 /** 1513 * Case 22: Test config updates where hasEverConnected goes from false to true. 1514 * Create a scan result with an associated config and update the available networks list. 1515 * Repeat this with a second scan result where the config value for hasEverConnected 1516 * is true. 1517 * Expected behavior: The stored config should not be lost overwritten. 1518 */ 1519 @Test 1520 public void testUpdateNetworkWithHasEverConnectedTrue() { 1521 List<Pair<ScanDetail, WifiConfiguration>> candidates = 1522 new ArrayList<Pair<ScanDetail, WifiConfiguration>>(); 1523 String ssid = mSsids[0].replaceAll("^\"+", "").replaceAll("\"+$", ""); 1524 ScanDetail scanDetail = new ScanDetail(WifiSsid.createFromAsciiEncoded(ssid), 1525 mBssids[0], mCaps[0], mLevels[0], mFrequencies[0], System.currentTimeMillis(), 0); 1526 WifiConfiguration configHasEverConnectedFalse = mock(WifiConfiguration.class); 1527 WifiConfiguration.NetworkSelectionStatus networkSelectionStatusFalse = 1528 mock(WifiConfiguration.NetworkSelectionStatus.class); 1529 when(configHasEverConnectedFalse.getNetworkSelectionStatus()) 1530 .thenReturn(networkSelectionStatusFalse); 1531 when(networkSelectionStatusFalse.getHasEverConnected()) 1532 .thenReturn(false); 1533 candidates.add(Pair.create(scanDetail, configHasEverConnectedFalse)); 1534 mLastResortWatchdog.updateAvailableNetworks(candidates); 1535 1536 boolean watchdogTriggered = false; 1537 for (int i = 0; i < WifiLastResortWatchdog.FAILURE_THRESHOLD; i++) { 1538 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1539 mSsids[0], mBssids[0], WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION); 1540 } 1541 assertEquals(false, watchdogTriggered); 1542 1543 candidates.clear(); 1544 1545 WifiConfiguration configHasEverConnectedTrue = mock(WifiConfiguration.class); 1546 WifiConfiguration.NetworkSelectionStatus networkSelectionStatusTrue = 1547 mock(WifiConfiguration.NetworkSelectionStatus.class); 1548 when(configHasEverConnectedTrue.getNetworkSelectionStatus()) 1549 .thenReturn(networkSelectionStatusTrue); 1550 when(networkSelectionStatusTrue.getHasEverConnected()) 1551 .thenReturn(true); 1552 candidates.add(Pair.create(scanDetail, configHasEverConnectedTrue)); 1553 mLastResortWatchdog.updateAvailableNetworks(candidates); 1554 1555 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1556 mSsids[0], mBssids[0], WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION); 1557 assertEquals(true, watchdogTriggered); 1558 } 1559 1560 /** 1561 * Case 23: Test config updates where hasEverConnected goes from true to false. 1562 * Create a scan result with an associated config and update the available networks list. 1563 * Repeat this with a second scan result where hasEverConnected is false. 1564 * Expected behavior: The stored config should not be lost overwritten. 1565 */ 1566 @Test 1567 public void testUpdateNetworkWithHasEverConnectedFalse() { 1568 List<Pair<ScanDetail, WifiConfiguration>> candidates = 1569 new ArrayList<Pair<ScanDetail, WifiConfiguration>>(); 1570 String ssid = mSsids[0].replaceAll("^\"+", "").replaceAll("\"+$", ""); 1571 ScanDetail scanDetail = new ScanDetail(WifiSsid.createFromAsciiEncoded(ssid), 1572 mBssids[0], mCaps[0], mLevels[0], mFrequencies[0], System.currentTimeMillis(), 0); 1573 1574 WifiConfiguration configHasEverConnectedTrue = mock(WifiConfiguration.class); 1575 WifiConfiguration.NetworkSelectionStatus networkSelectionStatusTrue = 1576 mock(WifiConfiguration.NetworkSelectionStatus.class); 1577 when(configHasEverConnectedTrue.getNetworkSelectionStatus()) 1578 .thenReturn(networkSelectionStatusTrue); 1579 when(networkSelectionStatusTrue.getHasEverConnected()) 1580 .thenReturn(true); 1581 candidates.add(Pair.create(scanDetail, configHasEverConnectedTrue)); 1582 mLastResortWatchdog.updateAvailableNetworks(candidates); 1583 1584 boolean watchdogTriggered = false; 1585 for (int i = 0; i < WifiLastResortWatchdog.FAILURE_THRESHOLD; i++) { 1586 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1587 mSsids[0], mBssids[0], WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION); 1588 } 1589 assertEquals(true, watchdogTriggered); 1590 1591 candidates.clear(); 1592 1593 WifiConfiguration configHasEverConnectedFalse = mock(WifiConfiguration.class); 1594 WifiConfiguration.NetworkSelectionStatus networkSelectionStatusFalse = 1595 mock(WifiConfiguration.NetworkSelectionStatus.class); 1596 when(configHasEverConnectedFalse.getNetworkSelectionStatus()) 1597 .thenReturn(networkSelectionStatusFalse); 1598 when(networkSelectionStatusFalse.getHasEverConnected()) 1599 .thenReturn(false); 1600 candidates.add(Pair.create(scanDetail, configHasEverConnectedFalse)); 1601 mLastResortWatchdog.updateAvailableNetworks(candidates); 1602 1603 for (int i = 0; i < WifiLastResortWatchdog.FAILURE_THRESHOLD; i++) { 1604 watchdogTriggered = mLastResortWatchdog.noteConnectionFailureAndTriggerIfNeeded( 1605 mSsids[0], mBssids[0], WifiLastResortWatchdog.FAILURE_CODE_AUTHENTICATION); 1606 } 1607 assertEquals(false, watchdogTriggered); 1608 } 1609 1610 /** 1611 * Case 24: Check toString method for accurate hasEverConnected value in 1612 * AvailableNetworkFailureCount objects. 1613 * Create an AvailableNetworkFailureCount instance and check output of toString method. 1614 * Expected behavior: String contains HasEverConnected setting or null_config if there is not 1615 * an associated config. 1616 */ 1617 @Test 1618 public void testHasEverConnectedValueInAvailableNetworkFailureCountToString() { 1619 // Check with HasEverConnected true 1620 WifiConfiguration configHasEverConnectedTrue = mock(WifiConfiguration.class); 1621 WifiConfiguration.NetworkSelectionStatus networkSelectionStatusTrue = 1622 mock(WifiConfiguration.NetworkSelectionStatus.class); 1623 when(configHasEverConnectedTrue.getNetworkSelectionStatus()) 1624 .thenReturn(networkSelectionStatusTrue); 1625 when(networkSelectionStatusTrue.getHasEverConnected()).thenReturn(true); 1626 WifiLastResortWatchdog.AvailableNetworkFailureCount withConfigHECTrue = 1627 new WifiLastResortWatchdog.AvailableNetworkFailureCount(configHasEverConnectedTrue); 1628 String output = withConfigHECTrue.toString(); 1629 assertTrue(output.contains("HasEverConnected: true")); 1630 1631 // check with HasEverConnected false 1632 WifiConfiguration configHasEverConnectedFalse = mock(WifiConfiguration.class); 1633 WifiConfiguration.NetworkSelectionStatus networkSelectionStatusFalse = 1634 mock(WifiConfiguration.NetworkSelectionStatus.class); 1635 when(configHasEverConnectedFalse.getNetworkSelectionStatus()) 1636 .thenReturn(networkSelectionStatusFalse); 1637 when(networkSelectionStatusFalse.getHasEverConnected()).thenReturn(false); 1638 WifiLastResortWatchdog.AvailableNetworkFailureCount withConfigHECFalse = 1639 new WifiLastResortWatchdog.AvailableNetworkFailureCount( 1640 configHasEverConnectedFalse); 1641 output = withConfigHECFalse.toString(); 1642 assertTrue(output.contains("HasEverConnected: false")); 1643 1644 // Check with a null config 1645 WifiLastResortWatchdog.AvailableNetworkFailureCount withNullConfig = 1646 new WifiLastResortWatchdog.AvailableNetworkFailureCount(null); 1647 output = withNullConfig.toString(); 1648 assertTrue(output.contains("HasEverConnected: null_config")); 1649 } 1650} 1651