Loading res/layout/wifi_network_config.xml +22 −16 Original line number Diff line number Diff line Loading @@ -16,11 +16,13 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/l_wifidialog" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:paddingBottom="8dip"> android:paddingBottom="8dip" android:theme="@style/Theme.AppCompat.DayNight"> <LinearLayout android:id="@+id/wep_warning_layout" android:layout_width="match_parent" Loading Loading @@ -50,30 +52,34 @@ android:layout_width="match_parent" android:layout_height="wrap_content" style="@style/wifi_item"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" style="@style/wifi_item_label" android:text="@string/wifi_ssid" android:textDirection="locale"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <EditText android:id="@+id/ssid" <com.google.android.material.textfield.TextInputLayout android:id="@+id/ssid_layout" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" style="@style/wifi_item_edit_content" android:hint="@string/wifi_ssid_hint" android:singleLine="true" android:inputType="textNoSuggestions"/> android:hint="@string/wifi_ssid" android:theme="@style/Theme.Settings" android:textDirection="locale" app:endIconMode="clear_text" app:errorEnabled="true"> <com.google.android.material.textfield.TextInputEditText android:id="@+id/ssid" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textNoSuggestions" android:singleLine="true"/> </com.google.android.material.textfield.TextInputLayout> <ImageButton android:id="@+id/ssid_scanner_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:minWidth="@dimen/min_tap_target_size" android:minHeight="@dimen/min_tap_target_size" android:background="?android:attr/selectableItemBackground" Loading src/com/android/settings/wifi/AddNetworkFragment.java +3 −0 Original line number Diff line number Diff line Loading @@ -234,6 +234,9 @@ public class AddNetworkFragment extends InstrumentedFragment implements WifiConf activity.getSystemService(WifiManager.class).save(config, saveListener); } else { if (!mUIController.canFinish()) { return; } Intent intent = new Intent(); intent.putExtra(WIFI_CONFIG_KEY, config); activity.setResult(Activity.RESULT_OK, intent); Loading src/com/android/settings/wifi/WifiConfigController2.java +22 −16 Original line number Diff line number Diff line Loading @@ -77,6 +77,7 @@ import com.android.settings.utils.AndroidKeystoreAliasLoader; 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.SsidInputGroup; import com.android.settingslib.Utils; import com.android.settingslib.utils.ThreadUtils; import com.android.wifi.flags.Flags; Loading Loading @@ -228,7 +229,7 @@ public class WifiConfigController2 implements TextWatcher, private final boolean mHideMeteredAndPrivacy; private final WifiManager mWifiManager; private final AndroidKeystoreAliasLoader mAndroidKeystoreAliasLoader; private TextView mSsidView; private SsidInputGroup mSsidInputGroup; private final Context mContext; Loading Loading @@ -298,6 +299,7 @@ public class WifiConfigController2 implements TextWatcher, wepWarningLayout.setVisibility(View.VISIBLE); } mSsidInputGroup = new SsidInputGroup(mContext, mView, R.id.ssid_layout, R.id.ssid); mSsidScanButton = (ImageButton) mView.findViewById(R.id.ssid_scanner_button); mIpSettingsSpinner = (Spinner) mView.findViewById(R.id.ip_settings); mIpSettingsSpinner.setOnItemSelectedListener(this); Loading Loading @@ -544,13 +546,13 @@ public class WifiConfigController2 implements TextWatcher, && !isValidSaePassword(mPasswordView.getText().toString())))) { passwordInvalid = true; } if ((mSsidView != null && mSsidView.length() == 0) if ((mWifiEntry == null || !mWifiEntry.isSaved()) && passwordInvalid) { // If WifiEntry is not saved, apply passwordInvalid check || ((mWifiEntry == null || !mWifiEntry.isSaved()) && passwordInvalid 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 || mWifiEntry != null && mWifiEntry.isSaved() && passwordInvalid && mPasswordView.length() > 0)) { enabled = false; } else { enabled = ipAndProxyFieldsAreValid(); Loading Loading @@ -586,17 +588,22 @@ 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); mView.findViewById(R.id.ssid_too_long_warning).setVisibility(View.GONE); if (mSsidView != null) { final String ssid = mSsidView.getText().toString(); if (WifiUtils.isSSIDTooLong(ssid)) { if (WifiUtils.isSSIDTooLong(mSsidInputGroup.getText())) { mView.findViewById(R.id.ssid_too_long_warning).setVisibility(View.VISIBLE); } } if (mEapCaCertSpinner != null && mView.findViewById(R.id.l_ca_cert).getVisibility() != View.GONE) { if (mEapDomainView != null Loading Loading @@ -628,7 +635,7 @@ public class WifiConfigController2 implements TextWatcher, WifiConfiguration config; if (mWifiEntry == null) { config = new WifiConfiguration(); config.SSID = "\"" + mSsidView.getText().toString() + "\""; config.SSID = "\"" + mSsidInputGroup.getText() + "\""; // If the user adds a network manually, assume that it is hidden. config.hiddenSSID = mHiddenSettingsSpinner.getSelectedItemPosition() == HIDDEN_NETWORK; } else if (mWifiEntry.isSaved()) { Loading Loading @@ -1823,8 +1830,7 @@ public class WifiConfigController2 implements TextWatcher, private void configureSecuritySpinner() { mConfigUi.setTitle(R.string.wifi_add_network); mSsidView = (TextView) mView.findViewById(R.id.ssid); mSsidView.addTextChangedListener(this); mSsidInputGroup.addTextChangedListener(this); mSecuritySpinner = ((Spinner) mView.findViewById(R.id.security)); mSecuritySpinner.setOnItemSelectedListener(this); Loading src/com/android/settings/wifi/utils/SsidInputGroup.kt 0 → 100644 +34 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settings.wifi.utils import android.content.Context import android.view.View import com.android.settings.R /** TextInputGroup for Wi-Fi SSID. */ class SsidInputGroup(private val context: Context, view: View, layoutId: Int, editTextId: Int) : TextInputGroup(view, layoutId, editTextId) { fun validate(): Boolean { if (getText().isEmpty()) { setError(context.getString(R.string.wifi_ssid_hint)) return false } return true } } src/com/android/settings/wifi/utils/TextInputGroup.kt 0 → 100644 +68 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settings.wifi.utils import android.text.Editable import android.text.TextWatcher import android.view.View import android.widget.EditText import com.google.android.material.textfield.TextInputLayout /** A widget that wraps the relationship work between a TextInputLayout and an EditText. */ open class TextInputGroup( private val view: View, private val layoutId: Int, private val editTextId: Int, ) { private val View.layout: TextInputLayout? get() = findViewById(layoutId) private val View.editText: EditText? get() = findViewById(editTextId) private val textWatcher = object : TextWatcher { override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {} override fun afterTextChanged(s: Editable?) { view.layout?.isErrorEnabled = false } } init { addTextChangedListener(textWatcher) } fun addTextChangedListener(watcher: TextWatcher) { view.editText?.addTextChangedListener(watcher) } fun getText(): String { return view.editText?.text?.toString() ?: "" } fun setText(text: String) { view.editText?.setText(text) } fun setError(errorMessage: String?) { view.layout?.apply { error = errorMessage } } } Loading
res/layout/wifi_network_config.xml +22 −16 Original line number Diff line number Diff line Loading @@ -16,11 +16,13 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/l_wifidialog" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:paddingBottom="8dip"> android:paddingBottom="8dip" android:theme="@style/Theme.AppCompat.DayNight"> <LinearLayout android:id="@+id/wep_warning_layout" android:layout_width="match_parent" Loading Loading @@ -50,30 +52,34 @@ android:layout_width="match_parent" android:layout_height="wrap_content" style="@style/wifi_item"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" style="@style/wifi_item_label" android:text="@string/wifi_ssid" android:textDirection="locale"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <EditText android:id="@+id/ssid" <com.google.android.material.textfield.TextInputLayout android:id="@+id/ssid_layout" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" style="@style/wifi_item_edit_content" android:hint="@string/wifi_ssid_hint" android:singleLine="true" android:inputType="textNoSuggestions"/> android:hint="@string/wifi_ssid" android:theme="@style/Theme.Settings" android:textDirection="locale" app:endIconMode="clear_text" app:errorEnabled="true"> <com.google.android.material.textfield.TextInputEditText android:id="@+id/ssid" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textNoSuggestions" android:singleLine="true"/> </com.google.android.material.textfield.TextInputLayout> <ImageButton android:id="@+id/ssid_scanner_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:minWidth="@dimen/min_tap_target_size" android:minHeight="@dimen/min_tap_target_size" android:background="?android:attr/selectableItemBackground" Loading
src/com/android/settings/wifi/AddNetworkFragment.java +3 −0 Original line number Diff line number Diff line Loading @@ -234,6 +234,9 @@ public class AddNetworkFragment extends InstrumentedFragment implements WifiConf activity.getSystemService(WifiManager.class).save(config, saveListener); } else { if (!mUIController.canFinish()) { return; } Intent intent = new Intent(); intent.putExtra(WIFI_CONFIG_KEY, config); activity.setResult(Activity.RESULT_OK, intent); Loading
src/com/android/settings/wifi/WifiConfigController2.java +22 −16 Original line number Diff line number Diff line Loading @@ -77,6 +77,7 @@ import com.android.settings.utils.AndroidKeystoreAliasLoader; 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.SsidInputGroup; import com.android.settingslib.Utils; import com.android.settingslib.utils.ThreadUtils; import com.android.wifi.flags.Flags; Loading Loading @@ -228,7 +229,7 @@ public class WifiConfigController2 implements TextWatcher, private final boolean mHideMeteredAndPrivacy; private final WifiManager mWifiManager; private final AndroidKeystoreAliasLoader mAndroidKeystoreAliasLoader; private TextView mSsidView; private SsidInputGroup mSsidInputGroup; private final Context mContext; Loading Loading @@ -298,6 +299,7 @@ public class WifiConfigController2 implements TextWatcher, wepWarningLayout.setVisibility(View.VISIBLE); } mSsidInputGroup = new SsidInputGroup(mContext, mView, R.id.ssid_layout, R.id.ssid); mSsidScanButton = (ImageButton) mView.findViewById(R.id.ssid_scanner_button); mIpSettingsSpinner = (Spinner) mView.findViewById(R.id.ip_settings); mIpSettingsSpinner.setOnItemSelectedListener(this); Loading Loading @@ -544,13 +546,13 @@ public class WifiConfigController2 implements TextWatcher, && !isValidSaePassword(mPasswordView.getText().toString())))) { passwordInvalid = true; } if ((mSsidView != null && mSsidView.length() == 0) if ((mWifiEntry == null || !mWifiEntry.isSaved()) && passwordInvalid) { // If WifiEntry is not saved, apply passwordInvalid check || ((mWifiEntry == null || !mWifiEntry.isSaved()) && passwordInvalid 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 || mWifiEntry != null && mWifiEntry.isSaved() && passwordInvalid && mPasswordView.length() > 0)) { enabled = false; } else { enabled = ipAndProxyFieldsAreValid(); Loading Loading @@ -586,17 +588,22 @@ 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); mView.findViewById(R.id.ssid_too_long_warning).setVisibility(View.GONE); if (mSsidView != null) { final String ssid = mSsidView.getText().toString(); if (WifiUtils.isSSIDTooLong(ssid)) { if (WifiUtils.isSSIDTooLong(mSsidInputGroup.getText())) { mView.findViewById(R.id.ssid_too_long_warning).setVisibility(View.VISIBLE); } } if (mEapCaCertSpinner != null && mView.findViewById(R.id.l_ca_cert).getVisibility() != View.GONE) { if (mEapDomainView != null Loading Loading @@ -628,7 +635,7 @@ public class WifiConfigController2 implements TextWatcher, WifiConfiguration config; if (mWifiEntry == null) { config = new WifiConfiguration(); config.SSID = "\"" + mSsidView.getText().toString() + "\""; config.SSID = "\"" + mSsidInputGroup.getText() + "\""; // If the user adds a network manually, assume that it is hidden. config.hiddenSSID = mHiddenSettingsSpinner.getSelectedItemPosition() == HIDDEN_NETWORK; } else if (mWifiEntry.isSaved()) { Loading Loading @@ -1823,8 +1830,7 @@ public class WifiConfigController2 implements TextWatcher, private void configureSecuritySpinner() { mConfigUi.setTitle(R.string.wifi_add_network); mSsidView = (TextView) mView.findViewById(R.id.ssid); mSsidView.addTextChangedListener(this); mSsidInputGroup.addTextChangedListener(this); mSecuritySpinner = ((Spinner) mView.findViewById(R.id.security)); mSecuritySpinner.setOnItemSelectedListener(this); Loading
src/com/android/settings/wifi/utils/SsidInputGroup.kt 0 → 100644 +34 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settings.wifi.utils import android.content.Context import android.view.View import com.android.settings.R /** TextInputGroup for Wi-Fi SSID. */ class SsidInputGroup(private val context: Context, view: View, layoutId: Int, editTextId: Int) : TextInputGroup(view, layoutId, editTextId) { fun validate(): Boolean { if (getText().isEmpty()) { setError(context.getString(R.string.wifi_ssid_hint)) return false } return true } }
src/com/android/settings/wifi/utils/TextInputGroup.kt 0 → 100644 +68 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settings.wifi.utils import android.text.Editable import android.text.TextWatcher import android.view.View import android.widget.EditText import com.google.android.material.textfield.TextInputLayout /** A widget that wraps the relationship work between a TextInputLayout and an EditText. */ open class TextInputGroup( private val view: View, private val layoutId: Int, private val editTextId: Int, ) { private val View.layout: TextInputLayout? get() = findViewById(layoutId) private val View.editText: EditText? get() = findViewById(editTextId) private val textWatcher = object : TextWatcher { override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {} override fun afterTextChanged(s: Editable?) { view.layout?.isErrorEnabled = false } } init { addTextChangedListener(textWatcher) } fun addTextChangedListener(watcher: TextWatcher) { view.editText?.addTextChangedListener(watcher) } fun getText(): String { return view.editText?.text?.toString() ?: "" } fun setText(text: String) { view.editText?.setText(text) } fun setError(errorMessage: String?) { view.layout?.apply { error = errorMessage } } }