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 17 package android.settings.functional; 18 19 import android.content.Context; 20 import android.net.wifi.WifiManager; 21 import android.os.RemoteException; 22 import android.provider.Settings; 23 import android.platform.test.helpers.SettingsHelperImpl; 24 import android.support.test.uiautomator.By; 25 import android.support.test.uiautomator.BySelector; 26 import android.support.test.uiautomator.Direction; 27 import android.support.test.uiautomator.StaleObjectException; 28 import android.support.test.uiautomator.UiDevice; 29 import android.support.test.uiautomator.UiObject2; 30 import android.support.test.uiautomator.Until; 31 import android.test.InstrumentationTestCase; 32 import android.test.suitebuilder.annotation.MediumTest; 33 34 public class WirelessNetworkSettingsTests extends InstrumentationTestCase { 35 // These back button presses are performed in tearDown() to exit Wifi 36 // Settings sub-menus that a test might finish in. This number should be 37 // high enough to account for the deepest sub-menu a test might enter. 38 private static final int NUM_BACK_BUTTON_PRESSES = 5; 39 private static final int TIMEOUT = 2000; 40 private static final int SLEEP_TIME = 500; 41 42 // Note: The values of these variables might affect flakiness in tests that involve 43 // scrolling. Adjust where necessary. 44 private static final float SCROLL_UP_PERCENT = 10.0f; 45 private static final float SCROLL_DOWN_PERCENT = 0.5f; 46 private static final int MAX_SCROLL_ATTEMPTS = 10; 47 private static final int MAX_ADD_NETWORK_BUTTON_ATTEMPTS = 3; 48 private static final int SCROLL_SPEED = 2000; 49 50 private static final String TEST_SSID = "testSsid"; 51 private static final String TEST_PW_GE_8_CHAR = "testPasswordGreaterThan8Char"; 52 private static final String TEST_PW_LT_8_CHAR = "lt8Char"; 53 private static final String TEST_DOMAIN = "testDomain.com"; 54 55 private static final String SETTINGS_PACKAGE = "com.android.settings"; 56 57 private static final String CHECKBOX_CLASS = "android.widget.CheckBox"; 58 private static final String SPINNER_CLASS = "android.widget.Spinner"; 59 private static final String EDIT_TEXT_CLASS = "android.widget.EditText"; 60 private static final String SCROLLVIEW_CLASS = "android.widget.ScrollView"; 61 private static final String LISTVIEW_CLASS = "android.widget.ListView"; 62 63 private static final String ADD_NETWORK_MENU_CANCEL_BUTTON_TEXT = "CANCEL"; 64 private static final String ADD_NETWORK_MENU_SAVE_BUTTON_TEXT = "SAVE"; 65 private static final String ADD_NETWORK_PREFERENCE_TEXT = "Add network"; 66 private static final String CACERT_MENU_PLEASE_SELECT_TEXT = "Please select"; 67 private static final String CACERT_MENU_USE_SYSTEM_CERTS_TEXT = "Use system certificates"; 68 private static final String CACERT_MENU_DO_NOT_VALIDATE_TEXT = "Do not validate"; 69 private static final String USERCERT_MENU_PLEASE_SELECT_TEXT = "Please select"; 70 private static final String USERCERT_MENU_DO_NOT_PROVIDE_TEXT = "Do not provide"; 71 private static final String SECURITY_OPTION_NONE_TEXT = "None"; 72 private static final String SECURITY_OPTION_WEP_TEXT = "WEP"; 73 private static final String SECURITY_OPTION_PSK_TEXT = "WPA/WPA2 PSK"; 74 private static final String SECURITY_OPTION_EAP_TEXT = "802.1x EAP"; 75 private static final String EAP_METHOD_PEAP_TEXT = "PEAP"; 76 private static final String EAP_METHOD_TLS_TEXT = "TLS"; 77 private static final String EAP_METHOD_TTLS_TEXT = "TTLS"; 78 private static final String EAP_METHOD_PWD_TEXT = "PWD"; 79 private static final String EAP_METHOD_SIM_TEXT = "SIM"; 80 private static final String EAP_METHOD_AKA_TEXT = "AKA"; 81 private static final String EAP_METHOD_AKA_PRIME_TEXT = "AKA'"; 82 private static final String PHASE2_MENU_NONE_TEXT = "None"; 83 private static final String PHASE2_MENU_MSCHAPV2_TEXT = "MSCHAPV2"; 84 private static final String PHASE2_MENU_GTC_TEXT = "GTC"; 85 86 private static final String ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID = "wifi_advanced_togglebox"; 87 private static final String ADD_NETWORK_MENU_IP_SETTINGS_RES_ID = "ip_settings"; 88 private static final String ADD_NETWORK_MENU_PROXY_SETTINGS_RES_ID = "proxy_settings"; 89 private static final String ADD_NETWORK_MENU_SECURITY_OPTION_RES_ID = "security"; 90 private static final String ADD_NETWORK_MENU_EAP_METHOD_RES_ID = "method"; 91 private static final String ADD_NETWORK_MENU_SSID_RES_ID = "ssid"; 92 private static final String ADD_NETWORK_MENU_PHASE2_RES_ID = "phase2"; 93 private static final String ADD_NETWORK_MENU_CACERT_RES_ID = "ca_cert"; 94 private static final String ADD_NETWORK_MENU_USERCERT_RES_ID = "user_cert"; 95 private static final String ADD_NETWORK_MENU_NO_DOMAIN_WARNING_RES_ID = "no_domain_warning"; 96 private static final String ADD_NETWORK_MENU_NO_CACERT_WARNING_RES_ID = "no_ca_cert_warning"; 97 private static final String ADD_NETWORK_MENU_DOMAIN_LAYOUT_RES_ID = "l_domain"; 98 private static final String ADD_NETWORK_MENU_DOMAIN_RES_ID = "domain"; 99 private static final String ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID = "l_identity"; 100 private static final String ADD_NETWORK_MENU_ANONYMOUS_LAYOUT_RES_ID = "l_anonymous"; 101 private static final String ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID = "password_layout"; 102 private static final String ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID = 103 "show_password_layout"; 104 private static final String ADD_NETWORK_MENU_PASSWORD_RES_ID = "password"; 105 106 private static final BySelector ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR = 107 By.scrollable(true).clazz(SCROLLVIEW_CLASS); 108 private static final BySelector SPINNER_OPTIONS_SCROLLABLE_BY_SELECTOR = 109 By.scrollable(true).clazz(LISTVIEW_CLASS); 110 111 private UiDevice mDevice; 112 113 @Override setUp()114 public void setUp() throws Exception { 115 super.setUp(); 116 mDevice = UiDevice.getInstance(getInstrumentation()); 117 try { 118 mDevice.setOrientationNatural(); 119 } catch (RemoteException e) { 120 throw new RuntimeException("failed to freeze device orientation", e); 121 } 122 } 123 124 @Override tearDown()125 protected void tearDown() throws Exception { 126 // Exit all settings sub-menus. 127 for (int i = 0; i < NUM_BACK_BUTTON_PRESSES; ++i) { 128 mDevice.pressBack(); 129 } 130 mDevice.pressHome(); 131 super.tearDown(); 132 } 133 134 @MediumTest testWiFiEnabled()135 public void testWiFiEnabled() throws Exception { 136 verifyWiFiOnOrOff(true); 137 } 138 139 @MediumTest testWiFiDisabled()140 public void testWiFiDisabled() throws Exception { 141 verifyWiFiOnOrOff(false); 142 } 143 144 @MediumTest testWifiMenuLoadConfigure()145 public void testWifiMenuLoadConfigure() throws Exception { 146 loadWiFiConfigureMenu(); 147 Thread.sleep(SLEEP_TIME); 148 UiObject2 configureWiFiHeading = mDevice.wait(Until.findObject(By.text("Configure Wi‑Fi")), 149 TIMEOUT); 150 assertNotNull("Configure WiFi menu has not loaded correctly", configureWiFiHeading); 151 } 152 153 @MediumTest testNetworkNotificationsOn()154 public void testNetworkNotificationsOn() throws Exception { 155 verifyNetworkNotificationsOnOrOff(true); 156 } 157 158 @MediumTest testNetworkNotificationsOff()159 public void testNetworkNotificationsOff() throws Exception { 160 verifyNetworkNotificationsOnOrOff(false); 161 } 162 163 @MediumTest testKeepWiFiDuringSleepAlways()164 public void testKeepWiFiDuringSleepAlways() throws Exception { 165 // Change the default and then change it back 166 Settings.Global.putInt(getInstrumentation().getContext().getContentResolver(), 167 Settings.Global.WIFI_SLEEP_POLICY, Settings.Global.WIFI_SLEEP_POLICY_DEFAULT); 168 verifyKeepWiFiOnDuringSleep("Always", Settings.Global.WIFI_SLEEP_POLICY_NEVER); 169 } 170 171 @MediumTest testKeepWiFiDuringSleepOnlyWhenPluggedIn()172 public void testKeepWiFiDuringSleepOnlyWhenPluggedIn() throws Exception { 173 verifyKeepWiFiOnDuringSleep("Only when plugged in", 174 Settings.Global.WIFI_SLEEP_POLICY_NEVER_WHILE_PLUGGED); 175 } 176 177 @MediumTest testKeepWiFiDuringSleepNever()178 public void testKeepWiFiDuringSleepNever() throws Exception { 179 verifyKeepWiFiOnDuringSleep("Never", Settings.Global.WIFI_SLEEP_POLICY_DEFAULT); 180 } 181 182 @MediumTest testAddNetworkMenu_Default()183 public void testAddNetworkMenu_Default() throws Exception { 184 loadAddNetworkMenu(); 185 186 // Submit button should be disabled by default, while cancel button should be enabled. 187 assertFalse(mDevice.wait(Until.findObject( 188 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 189 assertTrue(mDevice.wait(Until.findObject( 190 By.text(ADD_NETWORK_MENU_CANCEL_BUTTON_TEXT)), TIMEOUT).isEnabled()); 191 192 // Check that the SSID field is defaults to the hint. 193 assertEquals("Enter the SSID", mDevice.wait(Until.findObject(By 194 .res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SSID_RES_ID) 195 .clazz(EDIT_TEXT_CLASS)), TIMEOUT) 196 .getText()); 197 198 // Check Security defaults to None. 199 assertEquals("None", mDevice.wait(Until.findObject(By 200 .res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SECURITY_OPTION_RES_ID) 201 .clazz(SPINNER_CLASS)), TIMEOUT) 202 .getChildren().get(0).getText()); 203 204 // Check advanced options are collapsed by default. 205 assertFalse(mDevice.wait(Until.findObject(By 206 .res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID) 207 .clazz(CHECKBOX_CLASS)), TIMEOUT).isChecked()); 208 209 } 210 211 @MediumTest testAddNetworkMenu_Proxy()212 public void testAddNetworkMenu_Proxy() throws Exception { 213 loadAddNetworkMenu(); 214 215 // Toggle advanced options. 216 mDevice.wait(Until.findObject(By 217 .res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID) 218 .clazz(CHECKBOX_CLASS)), TIMEOUT).click(); 219 220 // Verify Proxy defaults to None. 221 BySelector proxySettingsBySelector = 222 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PROXY_SETTINGS_RES_ID) 223 .clazz(SPINNER_CLASS); 224 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, proxySettingsBySelector); 225 assertEquals("None", mDevice.wait(Until.findObject(proxySettingsBySelector), TIMEOUT) 226 .getChildren().get(0).getText()); 227 228 // Verify that Proxy Manual fields appear. 229 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, proxySettingsBySelector); 230 mDevice.wait(Until.findObject(proxySettingsBySelector), TIMEOUT).click(); 231 mDevice.wait(Until.findObject(By.text("Manual")), TIMEOUT).click(); 232 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 233 By.res(SETTINGS_PACKAGE, "proxy_warning_limited_support")); 234 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 235 By.res(SETTINGS_PACKAGE, "proxy_hostname")); 236 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 237 By.res(SETTINGS_PACKAGE, "proxy_exclusionlist")); 238 239 // Verify that Proxy Auto-Config options appear. 240 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, proxySettingsBySelector); 241 mDevice.wait(Until.findObject(proxySettingsBySelector), TIMEOUT).click(); 242 mDevice.wait(Until.findObject(By.text("Proxy Auto-Config")), TIMEOUT).click(); 243 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 244 By.res(SETTINGS_PACKAGE, "proxy_pac")); 245 } 246 247 @MediumTest testAddNetworkMenu_IpSettings()248 public void testAddNetworkMenu_IpSettings() throws Exception { 249 loadAddNetworkMenu(); 250 251 // Toggle advanced options. 252 mDevice.wait(Until.findObject(By 253 .res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ADV_TOGGLE_RES_ID) 254 .clazz(CHECKBOX_CLASS)), TIMEOUT).click(); 255 256 // Verify IP settings defaults to DHCP. 257 BySelector ipSettingsBySelector = 258 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IP_SETTINGS_RES_ID).clazz(SPINNER_CLASS); 259 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, ipSettingsBySelector); 260 assertEquals("DHCP", mDevice.wait(Until.findObject(ipSettingsBySelector), TIMEOUT) 261 .getChildren().get(0).getText()); 262 263 // Verify that Static IP settings options appear. 264 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, ipSettingsBySelector).click(); 265 mDevice.wait(Until.findObject(By.text("Static")), TIMEOUT).click(); 266 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 267 By.res(SETTINGS_PACKAGE, "ipaddress")); 268 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 269 By.res(SETTINGS_PACKAGE, "gateway")); 270 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 271 By.res(SETTINGS_PACKAGE, "network_prefix_length")); 272 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 273 By.res(SETTINGS_PACKAGE, "dns1")); 274 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 275 By.res(SETTINGS_PACKAGE, "dns2")); 276 } 277 278 @MediumTest testPhase2Settings()279 public void testPhase2Settings() throws Exception { 280 loadAddNetworkMenu(); 281 selectSecurityOption(SECURITY_OPTION_EAP_TEXT); 282 283 BySelector phase2SettingsBySelector = 284 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PHASE2_RES_ID).clazz(SPINNER_CLASS); 285 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, phase2SettingsBySelector); 286 assertEquals(PHASE2_MENU_NONE_TEXT, mDevice.wait(Until 287 .findObject(phase2SettingsBySelector), TIMEOUT).getChildren().get(0).getText()); 288 mDevice.wait(Until.findObject(phase2SettingsBySelector), TIMEOUT).click(); 289 Thread.sleep(SLEEP_TIME); 290 291 // Verify Phase 2 authentication spinner options. 292 assertNotNull(mDevice.wait(Until.findObject(By.text(PHASE2_MENU_NONE_TEXT)), TIMEOUT)); 293 assertNotNull(mDevice.wait(Until.findObject(By.text(PHASE2_MENU_MSCHAPV2_TEXT)), TIMEOUT)); 294 assertNotNull(mDevice.wait(Until.findObject(By.text(PHASE2_MENU_GTC_TEXT)), TIMEOUT)); 295 } 296 297 @MediumTest testCaCertSettings()298 public void testCaCertSettings() throws Exception { 299 loadAddNetworkMenu(); 300 selectSecurityOption(SECURITY_OPTION_EAP_TEXT); 301 302 BySelector caCertSettingsBySelector = 303 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID).clazz(SPINNER_CLASS); 304 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, caCertSettingsBySelector); 305 assertEquals(CACERT_MENU_PLEASE_SELECT_TEXT, mDevice.wait(Until 306 .findObject(caCertSettingsBySelector), TIMEOUT).getChildren().get(0).getText()); 307 mDevice.wait(Until.findObject(caCertSettingsBySelector), TIMEOUT).click(); 308 Thread.sleep(SLEEP_TIME); 309 310 // Verify CA certificate spinner options. 311 assertNotNull(mDevice.wait(Until.findObject( 312 By.text(CACERT_MENU_PLEASE_SELECT_TEXT)), TIMEOUT)); 313 assertNotNull(mDevice.wait(Until.findObject( 314 By.text(CACERT_MENU_USE_SYSTEM_CERTS_TEXT)), TIMEOUT)); 315 assertNotNull(mDevice.wait(Until.findObject( 316 By.text(CACERT_MENU_DO_NOT_VALIDATE_TEXT)), TIMEOUT)); 317 318 // Verify that a domain field and warning appear when the user selects the 319 // "Use system certificates" option. 320 mDevice.wait(Until.findObject(By.text(CACERT_MENU_USE_SYSTEM_CERTS_TEXT)), TIMEOUT).click(); 321 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 322 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_DOMAIN_LAYOUT_RES_ID)); 323 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 324 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_NO_DOMAIN_WARNING_RES_ID)); 325 326 // Verify that a warning appears when the user chooses the "Do Not Validate" option. 327 mDevice.wait(Until.findObject(caCertSettingsBySelector), TIMEOUT).click(); 328 mDevice.wait(Until.findObject(By.text(CACERT_MENU_DO_NOT_VALIDATE_TEXT)), TIMEOUT).click(); 329 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 330 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_NO_CACERT_WARNING_RES_ID)); 331 } 332 333 @MediumTest testAddNetwork_NoSecurity()334 public void testAddNetwork_NoSecurity() throws Exception { 335 loadAddNetworkMenu(); 336 selectSecurityOption(SECURITY_OPTION_NONE_TEXT); 337 338 // Entering an SSID is enough to enable the submit button. // TODO THIS GUY 339 enterSSID(TEST_SSID); 340 assertTrue(mDevice.wait(Until 341 .findObject(By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 342 } 343 344 @MediumTest testAddNetwork_WEP()345 public void testAddNetwork_WEP() throws Exception { 346 loadAddNetworkMenu(); 347 selectSecurityOption(SECURITY_OPTION_WEP_TEXT); 348 assertFalse(mDevice.wait(Until.findObject( 349 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 350 351 // Verify that WEP fields appear. 352 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 353 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID)); 354 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 355 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID)); 356 357 // Entering an SSID alone does not enable the submit button. 358 enterSSID(TEST_SSID); 359 assertFalse(mDevice.wait(Until.findObject( 360 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 361 362 // Submit button is only enabled after a password is entered. 363 enterPassword(TEST_PW_GE_8_CHAR); 364 assertTrue(mDevice.wait(Until 365 .findObject(By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 366 } 367 368 @MediumTest testAddNetwork_PSK()369 public void testAddNetwork_PSK() throws Exception { 370 loadAddNetworkMenu(); 371 selectSecurityOption(SECURITY_OPTION_PSK_TEXT); 372 assertFalse(mDevice.wait(Until.findObject( 373 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 374 375 // Verify that PSK fields appear. 376 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 377 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID)); 378 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 379 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID)); 380 381 // Entering an SSID alone does not enable the submit button. 382 enterSSID(TEST_SSID); 383 assertFalse(mDevice.wait(Until.findObject( 384 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 385 386 // Entering an password that is too short does not enable submit button. 387 enterPassword(TEST_PW_LT_8_CHAR); 388 assertFalse(mDevice.wait(Until.findObject( 389 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 390 391 // Submit button is only enabled after a password of valid length is entered. 392 enterPassword(TEST_PW_GE_8_CHAR); 393 assertTrue(mDevice.wait(Until.findObject( 394 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 395 } 396 397 @MediumTest testAddNetwork_EAP_PEAP()398 public void testAddNetwork_EAP_PEAP() throws Exception { 399 loadAddNetworkMenu(); 400 selectSecurityOption(SECURITY_OPTION_EAP_TEXT); 401 assertFalse(mDevice.wait(Until.findObject( 402 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 403 404 selectEAPMethod(EAP_METHOD_PEAP_TEXT); 405 406 // Verify that EAP-PEAP fields appear. 407 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 408 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PHASE2_RES_ID)); 409 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 410 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID)); 411 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 412 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID)); 413 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 414 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ANONYMOUS_LAYOUT_RES_ID)); 415 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 416 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID)); 417 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 418 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SHOW_PASSWORD_LAYOUT_RES_ID)); 419 420 // Entering an SSID alone does not enable the submit button. 421 enterSSID(TEST_SSID); 422 assertFalse(mDevice.wait(Until.findObject( 423 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 424 425 verifyCaCertificateSubmitConditions(); 426 } 427 428 @MediumTest testAddNetwork_EAP_TLS()429 public void testAddNetwork_EAP_TLS() throws Exception { 430 loadAddNetworkMenu(); 431 selectSecurityOption(SECURITY_OPTION_EAP_TEXT); 432 assertFalse(mDevice.wait(Until.findObject( 433 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 434 435 selectEAPMethod(EAP_METHOD_TLS_TEXT); 436 437 // Verify that EAP-TLS fields appear. 438 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 439 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID)); 440 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 441 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_USERCERT_RES_ID)); 442 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 443 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID)); 444 445 // Entering an SSID alone does not enable the submit button. 446 enterSSID(TEST_SSID); 447 assertFalse(mDevice.wait(Until.findObject( 448 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 449 450 // Selecting the User certificate "Do not provide" option alone does not enable the submit 451 // button. 452 selectUserCertificateOption(USERCERT_MENU_DO_NOT_PROVIDE_TEXT); 453 assertFalse(mDevice.wait(Until.findObject( 454 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 455 456 verifyCaCertificateSubmitConditions(); 457 } 458 459 @MediumTest testAddNetwork_EAP_TTLS()460 public void testAddNetwork_EAP_TTLS() throws Exception { 461 loadAddNetworkMenu(); 462 selectSecurityOption(SECURITY_OPTION_EAP_TEXT); 463 assertFalse(mDevice.wait(Until.findObject( 464 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 465 466 selectEAPMethod(EAP_METHOD_TTLS_TEXT); 467 468 // Verify that EAP-TLS fields appear. 469 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 470 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PHASE2_RES_ID)); 471 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 472 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID)); 473 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 474 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID)); 475 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 476 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_ANONYMOUS_LAYOUT_RES_ID)); 477 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 478 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID)); 479 480 // Entering an SSID alone does not enable the submit button. 481 enterSSID(TEST_SSID); 482 assertFalse(mDevice.wait(Until.findObject( 483 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 484 485 verifyCaCertificateSubmitConditions(); 486 } 487 488 @MediumTest testAddNetwork_EAP_PWD()489 public void testAddNetwork_EAP_PWD() throws Exception { 490 loadAddNetworkMenu(); 491 selectSecurityOption(SECURITY_OPTION_EAP_TEXT); 492 assertFalse(mDevice.wait(Until.findObject( 493 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 494 495 selectEAPMethod(EAP_METHOD_PWD_TEXT); 496 497 // Verify that EAP-TLS fields appear. 498 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 499 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_IDENTITY_LAYOUT_RES_ID)); 500 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 501 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_LAYOUT_RES_ID)); 502 503 // Entering an SSID alone enables the submit button. 504 enterSSID(TEST_SSID); 505 assertTrue(mDevice.wait(Until.findObject( 506 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 507 } 508 509 @MediumTest testAddNetwork_EAP_SIM()510 public void testAddNetwork_EAP_SIM() throws Exception { 511 loadAddNetworkMenu(); 512 selectSecurityOption(SECURITY_OPTION_EAP_TEXT); 513 assertFalse(mDevice.wait(Until.findObject( 514 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 515 516 selectEAPMethod(EAP_METHOD_SIM_TEXT); 517 518 // Entering an SSID alone enables the submit button. 519 enterSSID(TEST_SSID); 520 assertTrue(mDevice.wait(Until.findObject( 521 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 522 } 523 524 @MediumTest testAddNetwork_EAP_AKA()525 public void testAddNetwork_EAP_AKA() throws Exception { 526 loadAddNetworkMenu(); 527 selectSecurityOption(SECURITY_OPTION_EAP_TEXT); 528 assertFalse(mDevice.wait(Until.findObject( 529 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 530 531 selectEAPMethod(EAP_METHOD_AKA_TEXT); 532 533 // Entering an SSID alone enables the submit button. 534 enterSSID(TEST_SSID); 535 assertTrue(mDevice.wait(Until.findObject( 536 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 537 } 538 539 @MediumTest testAddNetwork_EAP_AKA_PRIME()540 public void testAddNetwork_EAP_AKA_PRIME() throws Exception { 541 loadAddNetworkMenu(); 542 selectSecurityOption(SECURITY_OPTION_EAP_TEXT); 543 assertFalse(mDevice.wait(Until.findObject( 544 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 545 546 selectEAPMethod(EAP_METHOD_AKA_PRIME_TEXT); 547 548 // Entering an SSID alone enables the submit button. 549 enterSSID(TEST_SSID); 550 assertTrue(mDevice.wait(Until.findObject( 551 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 552 } 553 verifyKeepWiFiOnDuringSleep(String settingToBeVerified, int settingValue)554 private void verifyKeepWiFiOnDuringSleep(String settingToBeVerified, int settingValue) 555 throws Exception { 556 loadWiFiConfigureMenu(); 557 mDevice.wait(Until.findObject(By.text("Keep Wi‑Fi on during sleep")), TIMEOUT) 558 .click(); 559 mDevice.wait(Until.findObject(By.clazz("android.widget.CheckedTextView") 560 .text(settingToBeVerified)), TIMEOUT).click(); 561 Thread.sleep(SLEEP_TIME); 562 int keepWiFiOnSetting = 563 Settings.Global.getInt(getInstrumentation().getContext().getContentResolver(), 564 Settings.Global.WIFI_SLEEP_POLICY); 565 assertEquals(settingValue, keepWiFiOnSetting); 566 } 567 verifyNetworkNotificationsOnOrOff(boolean verifyOn)568 private void verifyNetworkNotificationsOnOrOff(boolean verifyOn) 569 throws Exception { 570 String switchText = "ON"; 571 if (verifyOn) { 572 switchText = "OFF"; 573 Settings.Global.putString(getInstrumentation().getContext().getContentResolver(), 574 Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, "0"); 575 } 576 else { 577 Settings.Global.putString(getInstrumentation().getContext().getContentResolver(), 578 Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, "1"); 579 } 580 loadWiFiConfigureMenu(); 581 mDevice.wait(Until.findObject(By.res("android:id/switch_widget").text(switchText)), TIMEOUT) 582 .click(); 583 Thread.sleep(SLEEP_TIME); 584 String wifiNotificationValue = 585 Settings.Global.getString(getInstrumentation().getContext().getContentResolver(), 586 Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON); 587 if (verifyOn) { 588 assertEquals("1", wifiNotificationValue); 589 } 590 else { 591 assertEquals("0", wifiNotificationValue); 592 } 593 } 594 verifyWiFiOnOrOff(boolean verifyOn)595 private void verifyWiFiOnOrOff(boolean verifyOn) throws Exception { 596 String switchText = "On"; 597 if (verifyOn) { 598 switchText = "Off"; 599 } 600 loadWiFiSettingsPage(!verifyOn); 601 mDevice.wait(Until 602 .findObject(By.res(SETTINGS_PACKAGE, "switch_bar").text(switchText)), TIMEOUT) 603 .click(); 604 Thread.sleep(SLEEP_TIME); 605 String wifiValue = 606 Settings.Global.getString(getInstrumentation().getContext().getContentResolver(), 607 Settings.Global.WIFI_ON); 608 if (verifyOn) { 609 assertEquals("1", wifiValue); 610 } 611 else { 612 assertEquals("0", wifiValue); 613 } 614 } 615 verifyCaCertificateSubmitConditions()616 private void verifyCaCertificateSubmitConditions() throws Exception { 617 // Selecting the CA certificate "Do not validate" option enables the submit button. 618 selectCaCertificateOption(CACERT_MENU_DO_NOT_VALIDATE_TEXT); 619 assertTrue(mDevice.wait(Until.findObject( 620 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 621 622 // However, selecting the CA certificate "Use system certificates option" is not enough to 623 // enable the submit button. 624 selectCaCertificateOption(CACERT_MENU_USE_SYSTEM_CERTS_TEXT); 625 assertFalse(mDevice.wait(Until.findObject( 626 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 627 628 // Submit button is only enabled after a domain is entered as well. 629 enterDomain(TEST_DOMAIN); 630 assertTrue(mDevice.wait(Until.findObject( 631 By.text(ADD_NETWORK_MENU_SAVE_BUTTON_TEXT)), TIMEOUT).isEnabled()); 632 } 633 loadWiFiSettingsPage(boolean wifiEnabled)634 private void loadWiFiSettingsPage(boolean wifiEnabled) throws Exception { 635 WifiManager wifiManager = (WifiManager)getInstrumentation().getContext() 636 .getSystemService(Context.WIFI_SERVICE); 637 wifiManager.setWifiEnabled(wifiEnabled); 638 SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), 639 Settings.ACTION_WIFI_SETTINGS); 640 } 641 loadWiFiConfigureMenu()642 private void loadWiFiConfigureMenu() throws Exception { 643 loadWiFiSettingsPage(true); 644 mDevice.wait(Until.findObject(By.desc("Configure")), TIMEOUT).click(); 645 } 646 loadAddNetworkMenu()647 private void loadAddNetworkMenu() throws Exception { 648 loadWiFiSettingsPage(true); 649 for (int attempts = 0; attempts < MAX_ADD_NETWORK_BUTTON_ATTEMPTS; ++attempts) { 650 UiObject2 found = null; 651 try { 652 findOrScrollToObject(By.scrollable(true), By.text(ADD_NETWORK_PREFERENCE_TEXT)) 653 .click(); 654 } catch (StaleObjectException e) { 655 // The network list might have been updated between when the Add network button was 656 // found, and when it UI automator attempted to click on it. Retry. 657 continue; 658 } 659 // If we get here, we successfully clicked on the Add network button, so we are done. 660 // Adding a sleep and a back press to dismiss the IME, as a workaround for 661 // b/28862652 662 Thread.sleep(SLEEP_TIME*5); 663 mDevice.pressBack(); 664 return; 665 } 666 667 fail("Failed to load Add Network Menu after " + MAX_ADD_NETWORK_BUTTON_ATTEMPTS 668 + " retries"); 669 } 670 selectSecurityOption(String securityOption)671 private void selectSecurityOption(String securityOption) throws Exception { 672 // We might not need to scroll to the security options if not enough add network menu 673 // options are visible. 674 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 675 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SECURITY_OPTION_RES_ID) 676 .clazz(SPINNER_CLASS)).click(); 677 Thread.sleep(SLEEP_TIME); 678 mDevice.wait(Until.findObject(By.text(securityOption)), TIMEOUT).click(); 679 } 680 selectEAPMethod(String eapMethod)681 private void selectEAPMethod(String eapMethod) throws Exception { 682 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 683 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_EAP_METHOD_RES_ID).clazz(SPINNER_CLASS)) 684 .click(); 685 Thread.sleep(SLEEP_TIME); 686 findOrScrollToObject(SPINNER_OPTIONS_SCROLLABLE_BY_SELECTOR, By.text(eapMethod)).click(); 687 } 688 selectUserCertificateOption(String userCertificateOption)689 private void selectUserCertificateOption(String userCertificateOption) throws Exception { 690 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 691 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_USERCERT_RES_ID).clazz(SPINNER_CLASS)) 692 .click(); 693 mDevice.wait(Until.findObject(By.text(userCertificateOption)), TIMEOUT).click(); 694 } 695 selectCaCertificateOption(String caCertificateOption)696 private void selectCaCertificateOption(String caCertificateOption) throws Exception { 697 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 698 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_CACERT_RES_ID).clazz(SPINNER_CLASS)) 699 .click(); 700 mDevice.wait(Until.findObject(By.text(caCertificateOption)), TIMEOUT).click(); 701 } 702 enterSSID(String ssid)703 private void enterSSID(String ssid) throws Exception { 704 // We might not need to scroll to the SSID option if not enough add network menu options 705 // are visible. 706 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 707 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_SSID_RES_ID).clazz(EDIT_TEXT_CLASS)) 708 .setText(ssid); 709 } 710 enterPassword(String password)711 private void enterPassword(String password) throws Exception { 712 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 713 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_PASSWORD_RES_ID).clazz(EDIT_TEXT_CLASS)) 714 .setText(password); 715 } 716 enterDomain(String domain)717 private void enterDomain(String domain) throws Exception { 718 findOrScrollToObject(ADD_NETWORK_MENU_SCROLLABLE_BY_SELECTOR, 719 By.res(SETTINGS_PACKAGE, ADD_NETWORK_MENU_DOMAIN_RES_ID)).setText(domain); 720 } 721 722 // Use this if the UI object might or might not need to be scrolled to. findOrScrollToObject(BySelector scrollableSelector, BySelector objectSelector)723 private UiObject2 findOrScrollToObject(BySelector scrollableSelector, BySelector objectSelector) 724 throws Exception { 725 UiObject2 object = mDevice.wait(Until.findObject(objectSelector), TIMEOUT); 726 if (object == null) { 727 object = scrollToObject(scrollableSelector, objectSelector); 728 } 729 return object; 730 } 731 scrollToObject(BySelector scrollableSelector, BySelector objectSelector)732 private UiObject2 scrollToObject(BySelector scrollableSelector, BySelector objectSelector) 733 throws Exception { 734 UiObject2 scrollable = mDevice.wait(Until.findObject(scrollableSelector), TIMEOUT); 735 if (scrollable == null) { 736 fail("Could not find scrollable UI object identified by " + scrollableSelector); 737 } 738 UiObject2 found = null; 739 // Scroll all the way up first, then all the way down. 740 while (true) { 741 // Optimization: terminate if we find the object while scrolling up to reset, so 742 // we save the time spent scrolling down again. 743 boolean canScrollAgain = scrollable.scroll(Direction.UP, SCROLL_UP_PERCENT, 744 SCROLL_SPEED); 745 found = mDevice.findObject(objectSelector); 746 if (found != null) return found; 747 if (!canScrollAgain) break; 748 } 749 for (int attempts = 0; found == null && attempts < MAX_SCROLL_ATTEMPTS; ++attempts) { 750 // Return value of UiObject2.scroll() is not reliable, so do not use it in loop 751 // condition, in case it causes this loop to terminate prematurely. 752 scrollable.scroll(Direction.DOWN, SCROLL_DOWN_PERCENT, SCROLL_SPEED); 753 found = mDevice.findObject(objectSelector); 754 } 755 if (found == null) { 756 fail("Could not scroll to UI object identified by " + objectSelector); 757 } 758 return found; 759 } 760 } 761