1 /* 2 * Copyright (C) 2017 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 com.android.settings.wifi; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.mockito.Mockito.any; 22 import static org.mockito.Mockito.anyBoolean; 23 import static org.mockito.Mockito.anyInt; 24 import static org.mockito.Mockito.anyString; 25 import static org.mockito.Mockito.mock; 26 import static org.mockito.Mockito.verify; 27 import static org.mockito.Mockito.when; 28 29 import android.content.Context; 30 import android.net.wifi.WifiConfiguration; 31 import android.net.wifi.WifiManager; 32 import android.os.ServiceSpecificException; 33 import android.security.KeyStore; 34 import android.view.LayoutInflater; 35 import android.view.View; 36 import android.view.ViewGroup; 37 import android.widget.ArrayAdapter; 38 import android.widget.Spinner; 39 import android.widget.TextView; 40 41 import com.android.settings.R; 42 import com.android.settings.testutils.shadow.ShadowConnectivityManager; 43 import com.android.settings.wifi.details.WifiPrivacyPreferenceController; 44 import com.android.settingslib.wifi.AccessPoint; 45 46 import org.junit.Before; 47 import org.junit.Test; 48 import org.junit.runner.RunWith; 49 import org.mockito.Mock; 50 import org.mockito.MockitoAnnotations; 51 import org.robolectric.RobolectricTestRunner; 52 import org.robolectric.RuntimeEnvironment; 53 import org.robolectric.annotation.Config; 54 55 @RunWith(RobolectricTestRunner.class) 56 @Config(shadows = ShadowConnectivityManager.class) 57 public class WifiConfigControllerTest { 58 59 @Mock 60 private WifiConfigUiBase mConfigUiBase; 61 @Mock 62 private Context mContext; 63 @Mock 64 private AccessPoint mAccessPoint; 65 @Mock 66 private KeyStore mKeyStore; 67 private View mView; 68 private Spinner mHiddenSettingsSpinner; 69 70 public WifiConfigController mController; 71 private static final String HEX_PSK = "01234567012345670123456701234567012345670123456701234567" 72 + "01abcdef"; 73 // An invalid ASCII PSK pass phrase. It is 64 characters long, must not be greater than 63 74 private static final String LONG_PSK = 75 "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl"; 76 // An invalid PSK pass phrase. It is 7 characters long, must be at least 8 77 private static final String SHORT_PSK = "abcdefg"; 78 // Valid PSK pass phrase 79 private static final String GOOD_PSK = "abcdefghijklmnopqrstuvwxyz"; 80 private static final String GOOD_SSID = "abc"; 81 private static final int DHCP = 0; 82 83 @Before setUp()84 public void setUp() { 85 MockitoAnnotations.initMocks(this); 86 mContext = RuntimeEnvironment.application; 87 when(mConfigUiBase.getContext()).thenReturn(mContext); 88 when(mAccessPoint.getSecurity()).thenReturn(AccessPoint.SECURITY_PSK); 89 mView = LayoutInflater.from(mContext).inflate(R.layout.wifi_dialog, null); 90 final Spinner ipSettingsSpinner = mView.findViewById(R.id.ip_settings); 91 mHiddenSettingsSpinner = mView.findViewById(R.id.hidden_settings); 92 ipSettingsSpinner.setSelection(DHCP); 93 94 mController = new TestWifiConfigController(mConfigUiBase, mView, mAccessPoint, 95 WifiConfigUiBase.MODE_CONNECT); 96 } 97 98 @Test ssidExceeds32Bytes_shouldShowSsidTooLongWarning()99 public void ssidExceeds32Bytes_shouldShowSsidTooLongWarning() { 100 mController = new TestWifiConfigController(mConfigUiBase, mView, null /* accessPoint */, 101 WifiConfigUiBase.MODE_CONNECT); 102 final TextView ssid = mView.findViewById(R.id.ssid); 103 assertThat(ssid).isNotNull(); 104 ssid.setText("☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎"); 105 mController.showWarningMessagesIfAppropriate(); 106 107 assertThat(mView.findViewById(R.id.ssid_too_long_warning).getVisibility()) 108 .isEqualTo(View.VISIBLE); 109 } 110 111 @Test ssidShorterThan32Bytes_shouldNotShowSsidTooLongWarning()112 public void ssidShorterThan32Bytes_shouldNotShowSsidTooLongWarning() { 113 mController = new TestWifiConfigController(mConfigUiBase, mView, null /* accessPoint */, 114 WifiConfigUiBase.MODE_CONNECT); 115 116 final TextView ssid = mView.findViewById(R.id.ssid); 117 assertThat(ssid).isNotNull(); 118 ssid.setText("123456789012345678901234567890"); 119 mController.showWarningMessagesIfAppropriate(); 120 121 assertThat(mView.findViewById(R.id.ssid_too_long_warning).getVisibility()) 122 .isEqualTo(View.GONE); 123 124 ssid.setText("123"); 125 mController.showWarningMessagesIfAppropriate(); 126 127 assertThat(mView.findViewById(R.id.ssid_too_long_warning).getVisibility()) 128 .isEqualTo(View.GONE); 129 } 130 131 @Test isSubmittable_noSSID_shouldReturnFalse()132 public void isSubmittable_noSSID_shouldReturnFalse() { 133 final TextView ssid = mView.findViewById(R.id.ssid); 134 assertThat(ssid).isNotNull(); 135 ssid.setText(""); 136 assertThat(mController.isSubmittable()).isFalse(); 137 } 138 139 @Test isSubmittable_longPsk_shouldReturnFalse()140 public void isSubmittable_longPsk_shouldReturnFalse() { 141 final TextView password = mView.findViewById(R.id.password); 142 assertThat(password).isNotNull(); 143 password.setText(LONG_PSK); 144 assertThat(mController.isSubmittable()).isFalse(); 145 } 146 147 @Test isSubmittable_shortPsk_shouldReturnFalse()148 public void isSubmittable_shortPsk_shouldReturnFalse() { 149 final TextView password = mView.findViewById(R.id.password); 150 assertThat(password).isNotNull(); 151 password.setText(SHORT_PSK); 152 assertThat(mController.isSubmittable()).isFalse(); 153 } 154 155 @Test isSubmittable_goodPsk_shouldReturnTrue()156 public void isSubmittable_goodPsk_shouldReturnTrue() { 157 final TextView password = mView.findViewById(R.id.password); 158 assertThat(password).isNotNull(); 159 password.setText(GOOD_PSK); 160 assertThat(mController.isSubmittable()).isTrue(); 161 } 162 163 @Test isSubmittable_hexPsk_shouldReturnTrue()164 public void isSubmittable_hexPsk_shouldReturnTrue() { 165 final TextView password = mView.findViewById(R.id.password); 166 assertThat(password).isNotNull(); 167 password.setText(HEX_PSK); 168 assertThat(mController.isSubmittable()).isTrue(); 169 } 170 171 @Test isSubmittable_savedConfigZeroLengthPassword_shouldReturnTrue()172 public void isSubmittable_savedConfigZeroLengthPassword_shouldReturnTrue() { 173 final TextView password = mView.findViewById(R.id.password); 174 assertThat(password).isNotNull(); 175 password.setText(""); 176 when(mAccessPoint.isSaved()).thenReturn(true); 177 assertThat(mController.isSubmittable()).isTrue(); 178 } 179 180 @Test isSubmittable_nullAccessPoint_noException()181 public void isSubmittable_nullAccessPoint_noException() { 182 mController = 183 new TestWifiConfigController(mConfigUiBase, mView, null, WifiConfigUiBase.MODE_CONNECT); 184 mController.isSubmittable(); 185 } 186 187 @Test isSubmittable_EapToPskWithValidPassword_shouldReturnTrue()188 public void isSubmittable_EapToPskWithValidPassword_shouldReturnTrue() { 189 mController = new TestWifiConfigController(mConfigUiBase, mView, null, 190 WifiConfigUiBase.MODE_CONNECT); 191 final TextView ssid = mView.findViewById(R.id.ssid); 192 final TextView password = mView.findViewById(R.id.password); 193 final Spinner securitySpinner = mView.findViewById(R.id.security); 194 assertThat(password).isNotNull(); 195 assertThat(securitySpinner).isNotNull(); 196 when(mAccessPoint.isSaved()).thenReturn(true); 197 198 // Change it from EAP to PSK 199 mController.onItemSelected(securitySpinner, null, AccessPoint.SECURITY_EAP, 0); 200 mController.onItemSelected(securitySpinner, null, AccessPoint.SECURITY_PSK, 0); 201 password.setText(GOOD_PSK); 202 ssid.setText(GOOD_SSID); 203 204 assertThat(mController.isSubmittable()).isTrue(); 205 } 206 207 @Test isSubmittable_EapWithAkaMethod_shouldReturnTrue()208 public void isSubmittable_EapWithAkaMethod_shouldReturnTrue() { 209 when(mAccessPoint.isSaved()).thenReturn(true); 210 mController.mAccessPointSecurity = AccessPoint.SECURITY_EAP; 211 mView.findViewById(R.id.l_ca_cert).setVisibility(View.GONE); 212 213 assertThat(mController.isSubmittable()).isTrue(); 214 } 215 216 @Test getSignalString_notReachable_shouldHaveNoSignalString()217 public void getSignalString_notReachable_shouldHaveNoSignalString() { 218 when(mAccessPoint.isReachable()).thenReturn(false); 219 220 assertThat(mController.getSignalString()).isNull(); 221 } 222 223 @Test showForCarrierAp()224 public void showForCarrierAp() { 225 // Setup the mock view for wifi dialog. 226 View view = mock(View.class); 227 TextView nameText = mock(TextView.class); 228 TextView valueText = mock(TextView.class); 229 when(view.findViewById(R.id.name)).thenReturn(nameText); 230 when(view.findViewById(R.id.value)).thenReturn(valueText); 231 LayoutInflater inflater = mock(LayoutInflater.class); 232 when(inflater.inflate(anyInt(), any(ViewGroup.class), anyBoolean())).thenReturn(view); 233 when(mConfigUiBase.getLayoutInflater()).thenReturn(inflater); 234 235 String carrierName = "Test Carrier"; 236 when(mAccessPoint.isCarrierAp()).thenReturn(true); 237 when(mAccessPoint.getCarrierName()).thenReturn(carrierName); 238 mController = new TestWifiConfigController(mConfigUiBase, mView, mAccessPoint, 239 WifiConfigUiBase.MODE_CONNECT); 240 // Verify the content of the text fields. 241 verify(nameText).setText(R.string.wifi_carrier_connect); 242 verify(valueText).setText( 243 String.format(mContext.getString(R.string.wifi_carrier_content), carrierName)); 244 // Verify that the advance toggle is not visible. 245 assertThat(mView.findViewById(R.id.wifi_advanced_toggle).getVisibility()) 246 .isEqualTo(View.GONE); 247 // Verify that the EAP method menu is not visible. 248 assertThat(mView.findViewById(R.id.eap).getVisibility()).isEqualTo(View.GONE); 249 } 250 251 @Test loadCertificates_keyStoreListFail_shouldNotCrash()252 public void loadCertificates_keyStoreListFail_shouldNotCrash() { 253 // Set up 254 when(mAccessPoint.getSecurity()).thenReturn(AccessPoint.SECURITY_EAP); 255 when(mKeyStore.list(anyString())) 256 .thenThrow(new ServiceSpecificException(-1, "permission error")); 257 258 mController = new TestWifiConfigController(mConfigUiBase, mView, mAccessPoint, 259 WifiConfigUiBase.MODE_CONNECT); 260 261 // Verify that the EAP method menu is visible. 262 assertThat(mView.findViewById(R.id.eap).getVisibility()).isEqualTo(View.VISIBLE); 263 // No Crash 264 } 265 266 @Test ssidGetFocus_addNewNetwork_shouldReturnTrue()267 public void ssidGetFocus_addNewNetwork_shouldReturnTrue() { 268 mController = new TestWifiConfigController(mConfigUiBase, mView, null /* accessPoint */, 269 WifiConfigUiBase.MODE_CONNECT); 270 final TextView ssid = mView.findViewById(R.id.ssid); 271 // Verify ssid text get focus when add new network (accesspoint is null) 272 assertThat(ssid.isFocused()).isTrue(); 273 } 274 275 @Test passwordGetFocus_connectSecureWifi_shouldReturnTrue()276 public void passwordGetFocus_connectSecureWifi_shouldReturnTrue() { 277 final TextView password = mView.findViewById(R.id.password); 278 // Verify password get focus when connect to secure wifi without eap type 279 assertThat(password.isFocused()).isTrue(); 280 } 281 282 @Test hiddenWarning_warningVisibilityProperlyUpdated()283 public void hiddenWarning_warningVisibilityProperlyUpdated() { 284 View warningView = mView.findViewById(R.id.hidden_settings_warning); 285 mController.onItemSelected(mHiddenSettingsSpinner, null, mController.HIDDEN_NETWORK, 0); 286 assertThat(warningView.getVisibility()).isEqualTo(View.VISIBLE); 287 288 mController.onItemSelected(mHiddenSettingsSpinner, null, mController.NOT_HIDDEN_NETWORK, 0); 289 assertThat(warningView.getVisibility()).isEqualTo(View.GONE); 290 } 291 292 @Test hiddenField_visibilityUpdatesCorrectly()293 public void hiddenField_visibilityUpdatesCorrectly() { 294 View hiddenField = mView.findViewById(R.id.hidden_settings_field); 295 assertThat(hiddenField.getVisibility()).isEqualTo(View.GONE); 296 297 mController = new TestWifiConfigController(mConfigUiBase, mView, null /* accessPoint */, 298 WifiConfigUiBase.MODE_CONNECT); 299 assertThat(hiddenField.getVisibility()).isEqualTo(View.VISIBLE); 300 } 301 302 @Test securitySpinner_saeSuitebAndOweNotVisible()303 public void securitySpinner_saeSuitebAndOweNotVisible() { 304 securitySpinnerTestHelper(false, false, false); 305 } 306 307 @Test securitySpinner_saeSuitebAndOweVisible()308 public void securitySpinner_saeSuitebAndOweVisible() { 309 securitySpinnerTestHelper(true, true, true); 310 } 311 312 @Test securitySpinner_saeVisible_suitebAndOweNotVisible()313 public void securitySpinner_saeVisible_suitebAndOweNotVisible() { 314 securitySpinnerTestHelper(true, false, false); 315 } 316 317 @Test securitySpinner_oweVisible_suitebAndSaeNotVisible()318 public void securitySpinner_oweVisible_suitebAndSaeNotVisible() { 319 securitySpinnerTestHelper(false, false, true); 320 } 321 securitySpinnerTestHelper(boolean saeVisible, boolean suitebVisible, boolean oweVisible)322 private void securitySpinnerTestHelper(boolean saeVisible, boolean suitebVisible, 323 boolean oweVisible) { 324 WifiManager wifiManager = mock(WifiManager.class); 325 when(wifiManager.isWpa3SaeSupported()).thenReturn(saeVisible); 326 when(wifiManager.isWpa3SuiteBSupported()).thenReturn(suitebVisible); 327 when(wifiManager.isEnhancedOpenSupported()).thenReturn(oweVisible); 328 329 mController = new TestWifiConfigController(mConfigUiBase, mView, null /* accessPoint */, 330 WifiConfigUiBase.MODE_MODIFY, wifiManager); 331 332 final Spinner securitySpinner = mView.findViewById(R.id.security); 333 final ArrayAdapter<String> adapter = (ArrayAdapter) securitySpinner.getAdapter(); 334 boolean saeFound = false; 335 boolean suitebFound = false; 336 boolean oweFound = false; 337 for (int i = 0; i < adapter.getCount(); i++) { 338 String val = adapter.getItem(i); 339 340 if (val.compareTo(mContext.getString(R.string.wifi_security_sae)) == 0) { 341 saeFound = true; 342 } 343 344 if (val.compareTo(mContext.getString(R.string.wifi_security_eap_suiteb)) == 0) { 345 suitebFound = true; 346 } 347 348 if (val.compareTo(mContext.getString(R.string.wifi_security_owe)) == 0) { 349 oweFound = true; 350 } 351 } 352 353 if (saeVisible) { 354 assertThat(saeFound).isTrue(); 355 } else { 356 assertThat(saeFound).isFalse(); 357 } 358 if (suitebVisible) { 359 assertThat(suitebFound).isTrue(); 360 } else { 361 assertThat(suitebFound).isFalse(); 362 } 363 if (oweVisible) { 364 assertThat(oweFound).isTrue(); 365 } else { 366 assertThat(oweFound).isFalse(); 367 } 368 } 369 370 public class TestWifiConfigController extends WifiConfigController { 371 TestWifiConfigController( WifiConfigUiBase parent, View view, AccessPoint accessPoint, int mode)372 private TestWifiConfigController( 373 WifiConfigUiBase parent, View view, AccessPoint accessPoint, int mode) { 374 super(parent, view, accessPoint, mode); 375 } 376 TestWifiConfigController( WifiConfigUiBase parent, View view, AccessPoint accessPoint, int mode, WifiManager wifiManager)377 private TestWifiConfigController( 378 WifiConfigUiBase parent, View view, AccessPoint accessPoint, int mode, 379 WifiManager wifiManager) { 380 super(parent, view, accessPoint, mode, wifiManager); 381 } 382 383 @Override isSplitSystemUser()384 boolean isSplitSystemUser() { 385 return false; 386 } 387 388 @Override getKeyStore()389 KeyStore getKeyStore() { return mKeyStore; } 390 } 391 392 @Test loadMacRandomizedValue_shouldPersistentAsDefault()393 public void loadMacRandomizedValue_shouldPersistentAsDefault() { 394 final Spinner privacySetting = mView.findViewById(R.id.privacy_settings); 395 final int prefPersist = 396 WifiPrivacyPreferenceController.translateMacRandomizedValueToPrefValue( 397 WifiConfiguration.RANDOMIZATION_PERSISTENT); 398 399 assertThat(privacySetting.getVisibility()).isEqualTo(View.VISIBLE); 400 assertThat(privacySetting.getSelectedItemPosition()).isEqualTo(prefPersist); 401 } 402 403 @Test loadSavedMacRandomizedPersistentValue_shouldCorrectMacValue()404 public void loadSavedMacRandomizedPersistentValue_shouldCorrectMacValue() { 405 checkSavedMacRandomizedValue(WifiConfiguration.RANDOMIZATION_PERSISTENT); 406 } 407 408 @Test loadSavedMacRandomizedNoneValue_shouldCorrectMacValue()409 public void loadSavedMacRandomizedNoneValue_shouldCorrectMacValue() { 410 checkSavedMacRandomizedValue(WifiConfiguration.RANDOMIZATION_NONE); 411 } 412 checkSavedMacRandomizedValue(int macRandomizedValue)413 private void checkSavedMacRandomizedValue(int macRandomizedValue) { 414 when(mAccessPoint.isSaved()).thenReturn(true); 415 final WifiConfiguration mockWifiConfig = mock(WifiConfiguration.class); 416 when(mAccessPoint.getConfig()).thenReturn(mockWifiConfig); 417 mockWifiConfig.macRandomizationSetting = macRandomizedValue; 418 mController = new TestWifiConfigController(mConfigUiBase, mView, mAccessPoint, 419 WifiConfigUiBase.MODE_CONNECT); 420 421 final Spinner privacySetting = mView.findViewById(R.id.privacy_settings); 422 final int expectedPrefValue = 423 WifiPrivacyPreferenceController.translateMacRandomizedValueToPrefValue( 424 macRandomizedValue); 425 426 assertThat(privacySetting.getVisibility()).isEqualTo(View.VISIBLE); 427 assertThat(privacySetting.getSelectedItemPosition()).isEqualTo(expectedPrefValue); 428 } 429 430 @Test saveMacRandomizedValue_noChanged_shouldPersistentAsDefault()431 public void saveMacRandomizedValue_noChanged_shouldPersistentAsDefault() { 432 WifiConfiguration config = mController.getConfig(); 433 assertThat(config.macRandomizationSetting).isEqualTo( 434 WifiConfiguration.RANDOMIZATION_PERSISTENT); 435 } 436 437 @Test saveMacRandomizedValue_ChangedToNone_shouldGetNone()438 public void saveMacRandomizedValue_ChangedToNone_shouldGetNone() { 439 final Spinner privacySetting = mView.findViewById(R.id.privacy_settings); 440 final int prefMacNone = 441 WifiPrivacyPreferenceController.translateMacRandomizedValueToPrefValue( 442 WifiConfiguration.RANDOMIZATION_NONE); 443 privacySetting.setSelection(prefMacNone); 444 445 WifiConfiguration config = mController.getConfig(); 446 assertThat(config.macRandomizationSetting).isEqualTo(WifiConfiguration.RANDOMIZATION_NONE); 447 } 448 } 449