diff --git a/res/values/strings.xml b/res/values/strings.xml
index 7a5108f2b0e..28e3ba64bc6 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -2448,6 +2448,8 @@
Anonymous identity
Password*
+
+ Password (optional)
The password is invalid
diff --git a/src/com/android/settings/wifi/AddNetworkFragment.java b/src/com/android/settings/wifi/AddNetworkFragment.java
index aa8e840e38d..af12c5803bb 100644
--- a/src/com/android/settings/wifi/AddNetworkFragment.java
+++ b/src/com/android/settings/wifi/AddNetworkFragment.java
@@ -206,7 +206,7 @@ public class AddNetworkFragment extends InstrumentedFragment implements WifiConf
@VisibleForTesting
void handleSubmitAction() {
- if (!mUIController.canFinish()) {
+ if (!mUIController.getValidator().validate()) {
return;
}
successfullyFinish(mUIController.getConfig());
diff --git a/src/com/android/settings/wifi/ConfigureWifiEntryFragment.java b/src/com/android/settings/wifi/ConfigureWifiEntryFragment.java
index 652d318b4f9..77254302819 100644
--- a/src/com/android/settings/wifi/ConfigureWifiEntryFragment.java
+++ b/src/com/android/settings/wifi/ConfigureWifiEntryFragment.java
@@ -203,6 +203,9 @@ public class ConfigureWifiEntryFragment extends InstrumentedFragment implements
@VisibleForTesting
void handleSubmitAction() {
+ if (!mUiController.getValidator().validate()) {
+ return;
+ }
final Intent intent = new Intent();
final Activity activity = getActivity();
intent.putExtra(NETWORK_CONFIG_KEY, mUiController.getConfig());
diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java
index 003c2afed49..192cc5b0370 100644
--- a/src/com/android/settings/wifi/WifiConfigController.java
+++ b/src/com/android/settings/wifi/WifiConfigController.java
@@ -296,7 +296,7 @@ public class WifiConfigController implements TextWatcher,
mSsidInput = new TextInputGroup(mView, R.id.ssid_layout, R.id.ssid,
R.string.wifi_ssid_hint);
- mPasswordInput = new WifiPasswordInput(mView);
+ mPasswordInput = new WifiPasswordInput(mView, mAccessPointSecurity);
mValidator.addTextInput(mSsidInput);
mValidator.addTextInput(mPasswordInput);
diff --git a/src/com/android/settings/wifi/WifiConfigController2.java b/src/com/android/settings/wifi/WifiConfigController2.java
index a080fc8c5bc..7ba91ada316 100644
--- a/src/com/android/settings/wifi/WifiConfigController2.java
+++ b/src/com/android/settings/wifi/WifiConfigController2.java
@@ -78,6 +78,8 @@ import com.android.settings.wifi.details2.WifiPrivacyPreferenceController;
import com.android.settings.wifi.details2.WifiPrivacyPreferenceController2;
import com.android.settings.wifi.dpp.WifiDppUtils;
import com.android.settings.wifi.utils.TextInputGroup;
+import com.android.settings.wifi.utils.TextInputValidator;
+import com.android.settings.wifi.utils.WifiPasswordInput;
import com.android.settingslib.Utils;
import com.android.settingslib.utils.ThreadUtils;
import com.android.wifi.flags.Flags;
@@ -229,7 +231,10 @@ public class WifiConfigController2 implements TextWatcher,
private final boolean mHideMeteredAndPrivacy;
private final WifiManager mWifiManager;
private final AndroidKeystoreAliasLoader mAndroidKeystoreAliasLoader;
+
+ private TextInputValidator mValidator = new TextInputValidator();
private TextInputGroup mSsidInputGroup;
+ private WifiPasswordInput mPasswordInput;
private final Context mContext;
@@ -301,6 +306,10 @@ public class WifiConfigController2 implements TextWatcher,
mSsidInputGroup = new TextInputGroup(mView, R.id.ssid_layout, R.id.ssid,
R.string.wifi_ssid_hint);
+ mPasswordInput = new WifiPasswordInput(mView, mWifiEntrySecurity);
+ mValidator.addTextInput(mSsidInputGroup);
+ mValidator.addTextInput(mPasswordInput);
+
mSsidScanButton = (ImageButton) mView.findViewById(R.id.ssid_scanner_button);
mIpSettingsSpinner = (Spinner) mView.findViewById(R.id.ip_settings);
mIpSettingsSpinner.setOnItemSelectedListener(this);
@@ -519,45 +528,8 @@ public class WifiConfigController2 implements TextWatcher,
submit.setEnabled(isSubmittable());
}
- boolean isValidPsk(String password) {
- if (password.length() == 64 && password.matches("[0-9A-Fa-f]{64}")) {
- return true;
- } else if (password.length() >= 8 && password.length() <= 63) {
- return true;
- }
- return false;
- }
-
- boolean isValidSaePassword(String password) {
- if (password.length() >= 1 && password.length() <= 128) {
- return true;
- }
- return false;
- }
-
boolean isSubmittable() {
- boolean enabled = false;
- boolean passwordInvalid = false;
- if (mPasswordView != null
- && ((mWifiEntrySecurity == WifiEntry.SECURITY_WEP
- && mPasswordView.length() == 0)
- || (mWifiEntrySecurity == WifiEntry.SECURITY_PSK
- && !isValidPsk(mPasswordView.getText().toString()))
- || (mWifiEntrySecurity == WifiEntry.SECURITY_SAE
- && !isValidSaePassword(mPasswordView.getText().toString())))) {
- passwordInvalid = true;
- }
- if ((mWifiEntry == null || !mWifiEntry.isSaved()) && passwordInvalid) {
- // If WifiEntry is not saved, apply passwordInvalid check
- enabled = false;
- } else if (mWifiEntry != null && mWifiEntry.isSaved() && passwordInvalid
- && mPasswordView.length() > 0) {
- // If WifiEntry is saved (modifying network) and password is changed, apply
- // Invalid password check
- enabled = false;
- } else {
- enabled = ipAndProxyFieldsAreValid();
- }
+ boolean enabled = ipAndProxyFieldsAreValid();
if ((mWifiEntrySecurity == WifiEntry.SECURITY_EAP
|| mWifiEntrySecurity == WifiEntry.SECURITY_EAP_WPA3_ENTERPRISE
|| mWifiEntrySecurity == WifiEntry.SECURITY_EAP_SUITE_B)
@@ -589,14 +561,6 @@ public class WifiConfigController2 implements TextWatcher,
return enabled;
}
- boolean canFinish() {
- if (!mSsidInputGroup.validate()) {
- Log.w(TAG, "Can't finish because SSID is invalid!");
- return false;
- }
- return true;
- }
-
void showWarningMessagesIfAppropriate() {
mView.findViewById(R.id.no_user_cert_warning).setVisibility(View.GONE);
mView.findViewById(R.id.no_domain_warning).setVisibility(View.GONE);
@@ -1050,7 +1014,9 @@ public class WifiConfigController2 implements TextWatcher,
.setOnCheckedChangeListener(this);
if (mWifiEntry != null && mWifiEntry.isSaved()) {
- mPasswordView.setHint(R.string.wifi_unchanged);
+ mPasswordInput.setCanBeEmpty(true);
+ mPasswordInput.getLayout().setHint(R.string.wifi_password_optional);
+ mPasswordInput.setHelperText(mContext.getString(R.string.wifi_unchanged));
}
}
@@ -1763,6 +1729,7 @@ public class WifiConfigController2 implements TextWatcher,
// Convert menu position to actual Wi-Fi security type
mWifiEntrySecurity = mSecurityInPosition[position];
showSecurityFields(/* refreshEapMethods */ true, /* refreshCertificates */ true);
+ mPasswordInput.setSecurity(mWifiEntrySecurity);
if (WifiDppUtils.isSupportEnrolleeQrCodeScanner(mContext, mWifiEntrySecurity)) {
mSsidScanButton.setVisibility(View.VISIBLE);
@@ -2013,4 +1980,11 @@ public class WifiConfigController2 implements TextWatcher,
spinner.setAdapter(getSpinnerAdapter(stringArray));
return spinner;
}
+
+ /**
+ * Provides a validator to verify that the Wi-Fi configuration is ready.
+ */
+ public TextInputValidator getValidator() {
+ return mValidator;
+ }
}
diff --git a/src/com/android/settings/wifi/WifiDialog.java b/src/com/android/settings/wifi/WifiDialog.java
index 2fd3ce1ea93..6d0fca20175 100644
--- a/src/com/android/settings/wifi/WifiDialog.java
+++ b/src/com/android/settings/wifi/WifiDialog.java
@@ -118,7 +118,7 @@ public class WifiDialog extends AlertDialog implements WifiConfigUiBase,
mController.hideForgetButton();
}
- mDialogHelper = new WifiDialogHelper(this, mController.getValidator());
+ mDialogHelper = new WifiDialogHelper(this, this, mController.getValidator());
}
@SuppressWarnings("MissingSuperCall") // TODO: Fix me
@@ -159,6 +159,9 @@ public class WifiDialog extends AlertDialog implements WifiConfigUiBase,
public void onClick(DialogInterface dialogInterface, int id) {
if (mListener != null) {
switch (id) {
+ case BUTTON_SUBMIT:
+ mListener.onSubmit(this);
+ break;
case BUTTON_FORGET:
if (WifiUtils.isNetworkLockedDown(getContext(), mAccessPoint.getConfig())) {
RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getContext(),
@@ -171,11 +174,6 @@ public class WifiDialog extends AlertDialog implements WifiConfigUiBase,
}
}
- /** Return true to tell the parent activity to call onSubmit before onDismiss. */
- public boolean shouldSubmitBeforeFinish() {
- return mDialogHelper.isPositive();
- }
-
@Override
public int getMode() {
return mMode;
diff --git a/src/com/android/settings/wifi/WifiDialog2.kt b/src/com/android/settings/wifi/WifiDialog2.kt
index 2b89e4bb41a..c9476e4d9e7 100644
--- a/src/com/android/settings/wifi/WifiDialog2.kt
+++ b/src/com/android/settings/wifi/WifiDialog2.kt
@@ -28,6 +28,7 @@ import android.widget.TextView
import androidx.annotation.OpenForTesting
import androidx.appcompat.app.AlertDialog
import com.android.settings.R
+import com.android.settings.wifi.utils.WifiDialogHelper
import com.android.settingslib.RestrictedLockUtils
import com.android.settingslib.RestrictedLockUtilsInternal
import com.android.wifitrackerlib.WifiEntry
@@ -68,6 +69,7 @@ open class WifiDialog2 @JvmOverloads constructor(
private lateinit var view: View
private lateinit var controller: WifiConfigController2
+ private lateinit var dialogHelper: WifiDialogHelper
override fun getController(): WifiConfigController2 = controller
@@ -89,6 +91,7 @@ open class WifiDialog2 @JvmOverloads constructor(
if (wifiEntry == null) {
controller.hideForgetButton()
}
+ dialogHelper = WifiDialogHelper(this, this, controller.validator)
}
private fun setWindowsOverlay() {
diff --git a/src/com/android/settings/wifi/WifiDialogActivity.java b/src/com/android/settings/wifi/WifiDialogActivity.java
index 1d431753f32..951277aa9cf 100644
--- a/src/com/android/settings/wifi/WifiDialogActivity.java
+++ b/src/com/android/settings/wifi/WifiDialogActivity.java
@@ -346,9 +346,6 @@ public class WifiDialogActivity extends ObservableActivity implements WifiDialog
@Override
public void onDismiss(DialogInterface dialogInterface) {
mDialog2 = null;
- if (mDialog != null && mDialog.shouldSubmitBeforeFinish()) {
- onSubmit(mDialog);
- }
mDialog = null;
finish();
}
diff --git a/src/com/android/settings/wifi/utils/AlertDialogHelper.kt b/src/com/android/settings/wifi/utils/AlertDialogHelper.kt
index c50323220b7..e2307fbfdc7 100644
--- a/src/com/android/settings/wifi/utils/AlertDialogHelper.kt
+++ b/src/com/android/settings/wifi/utils/AlertDialogHelper.kt
@@ -17,16 +17,18 @@
package com.android.settings.wifi.utils
import android.content.DialogInterface
+import android.content.DialogInterface.BUTTON_POSITIVE
import android.util.Log
import androidx.appcompat.app.AlertDialog
-open class AlertDialogHelper(val alertDialog: AlertDialog) {
-
- var isPositive = false
+open class AlertDialogHelper(
+ val alertDialog: AlertDialog,
+ val onClickListener: DialogInterface.OnClickListener? = null,
+) {
init {
alertDialog.setOnShowListener {
- alertDialog.getButton(DialogInterface.BUTTON_POSITIVE)?.setOnClickListener {
+ alertDialog.getButton(BUTTON_POSITIVE)?.setOnClickListener {
onPositiveButtonClicked()
} ?: Log.e(TAG, "Can't get the positive button!")
}
@@ -37,7 +39,7 @@ open class AlertDialogHelper(val alertDialog: AlertDialog) {
Log.w(TAG, "Can't dismiss dialog!")
return
}
- isPositive = true
+ onClickListener?.onClick(alertDialog, BUTTON_POSITIVE)
alertDialog.dismiss()
}
diff --git a/src/com/android/settings/wifi/utils/TextInputGroup.kt b/src/com/android/settings/wifi/utils/TextInputGroup.kt
index 3fe2d9d08a4..37d7356d3d7 100644
--- a/src/com/android/settings/wifi/utils/TextInputGroup.kt
+++ b/src/com/android/settings/wifi/utils/TextInputGroup.kt
@@ -75,6 +75,7 @@ open class TextInputGroup(
get() = layout.helperText?.toString() ?: ""
set(value) {
layout.setHelperText(value)
+ if (value.isEmpty()) layout.isHelperTextEnabled = false
}
var error: String
@@ -85,6 +86,8 @@ open class TextInputGroup(
}
open fun validate(): Boolean {
+ if (!editText.isShown) return true
+
val isValid = text.isNotEmpty()
if (!isValid) {
Log.w(TAG, "validate failed in ${layout.hint ?: "unknown"}")
diff --git a/src/com/android/settings/wifi/utils/WifiDialogHelper.kt b/src/com/android/settings/wifi/utils/WifiDialogHelper.kt
index f4c3327e3bf..5607fdf1598 100644
--- a/src/com/android/settings/wifi/utils/WifiDialogHelper.kt
+++ b/src/com/android/settings/wifi/utils/WifiDialogHelper.kt
@@ -16,13 +16,14 @@
package com.android.settings.wifi.utils
-import android.util.Log
+import android.content.DialogInterface
import androidx.appcompat.app.AlertDialog
class WifiDialogHelper(
alertDialog: AlertDialog,
+ onClickListener: DialogInterface.OnClickListener?,
private val validator: TextInputValidator,
-) : AlertDialogHelper(alertDialog) {
+) : AlertDialogHelper(alertDialog, onClickListener) {
override fun canDismiss(): Boolean = validator.validate()
diff --git a/src/com/android/settings/wifi/utils/WifiPasswordInput.kt b/src/com/android/settings/wifi/utils/WifiPasswordInput.kt
index 19ebdd9658b..084e8bf7131 100644
--- a/src/com/android/settings/wifi/utils/WifiPasswordInput.kt
+++ b/src/com/android/settings/wifi/utils/WifiPasswordInput.kt
@@ -27,13 +27,16 @@ import com.android.wifitrackerlib.WifiEntry.SECURITY_WEP
/**
* The Wi-Fi password {@code TextInputGroup} that supports input validation.
*/
-class WifiPasswordInput(view: View) :
- TextInputGroup(view, R.id.password_input_layout, R.id.password, R.string.wifi_field_required) {
+class WifiPasswordInput(
+ view: View,
+ var security: Int = SECURITY_NONE,
+) : TextInputGroup(view, R.id.password_input_layout, R.id.password, R.string.wifi_field_required) {
- var security: Int = SECURITY_NONE
+ var canBeEmpty: Boolean = false
override fun validate(): Boolean {
if (!editText.isShown) return true
+ if (canBeEmpty && text.isEmpty()) return true
return when (security) {
SECURITY_WEP -> super.validate()
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiConfigController2Test.java b/tests/robotests/src/com/android/settings/wifi/WifiConfigController2Test.java
index 99b3acc0db2..3112a4d0f36 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiConfigController2Test.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiConfigController2Test.java
@@ -193,52 +193,6 @@ public class WifiConfigController2Test {
.isEqualTo(View.GONE);
}
- @Test
- public void isSubmittable_longPsk_shouldReturnFalse() {
- createController(mWifiEntry, WifiConfigUiBase2.MODE_CONNECT, false);
- final TextView password = mView.findViewById(R.id.password);
- assertThat(password).isNotNull();
- password.setText(LONG_PSK);
- assertThat(mController.isSubmittable()).isFalse();
- }
-
- @Test
- public void isSubmittable_shortPsk_shouldReturnFalse() {
- createController(mWifiEntry, WifiConfigUiBase2.MODE_CONNECT, false);
- final TextView password = mView.findViewById(R.id.password);
- assertThat(password).isNotNull();
- password.setText(SHORT_PSK);
- assertThat(mController.isSubmittable()).isFalse();
- }
-
- @Test
- public void isSubmittable_goodPsk_shouldReturnTrue() {
- createController(mWifiEntry, WifiConfigUiBase2.MODE_CONNECT, false);
- final TextView password = mView.findViewById(R.id.password);
- assertThat(password).isNotNull();
- password.setText(GOOD_PSK);
- assertThat(mController.isSubmittable()).isTrue();
- }
-
- @Test
- public void isSubmittable_hexPsk_shouldReturnTrue() {
- createController(mWifiEntry, WifiConfigUiBase2.MODE_CONNECT, false);
- final TextView password = mView.findViewById(R.id.password);
- assertThat(password).isNotNull();
- password.setText(HEX_PSK);
- assertThat(mController.isSubmittable()).isTrue();
- }
-
- @Test
- public void isSubmittable_savedConfigZeroLengthPassword_shouldReturnTrue() {
- createController(mWifiEntry, WifiConfigUiBase2.MODE_CONNECT, false);
- final TextView password = mView.findViewById(R.id.password);
- assertThat(password).isNotNull();
- password.setText("");
- when(mWifiEntry.isSaved()).thenReturn(true);
- assertThat(mController.isSubmittable()).isTrue();
- }
-
@Test
public void isSubmittable_nullWifiEntry_noException() {
createController(null, WifiConfigUiBase2.MODE_CONNECT, false);
@@ -1039,24 +993,6 @@ public class WifiConfigController2Test {
verify(mController.mEapAnonymousView, never()).setText(any(String.class));
}
- @Test
- public void canFinish_ssidIsEmpty_returnFalse() {
- createController(null, WifiConfigUiBase2.MODE_CONNECT, false);
- TextView ssid = mView.findViewById(R.id.ssid);
- ssid.setText("");
-
- assertThat(mController.canFinish()).isFalse();
- }
-
- @Test
- public void canFinish_ssidIsGood_returnTrue() {
- createController(null, WifiConfigUiBase2.MODE_CONNECT, false);
- TextView ssid = mView.findViewById(R.id.ssid);
- ssid.setText(GOOD_SSID);
-
- assertThat(mController.canFinish()).isTrue();
- }
-
private void setUpModifyingSavedCertificateConfigController(String savedCaCertificate,
String savedUserCertificate) {
final WifiConfiguration mockWifiConfig = spy(new WifiConfiguration());
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiDialogActivityTest.java b/tests/robotests/src/com/android/settings/wifi/WifiDialogActivityTest.java
index 159d97acd15..d1cbd0ee1b7 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiDialogActivityTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiDialogActivityTest.java
@@ -349,14 +349,4 @@ public class WifiDialogActivityTest {
verify(mActivity).dismissDialog();
}
-
- @Test
- public void onDismiss_shouldSubmitBeforeFinish_callOnSubmit() {
- mActivity.mDialog = mWifiDialog;
- when(mWifiDialog.shouldSubmitBeforeFinish()).thenReturn(true);
-
- mActivity.onDismiss(mWifiDialog);
-
- verify(mActivity).onSubmit(mWifiDialog);
- }
}