diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 6912bb45f86..3c272fc094b 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -235,6 +235,22 @@
- @string/wifi_security_psk_generic
+
+
+
+ - @string/wifi_security_wpa2
+
+ - @string/wifi_security_none
+
+
+
+
+
+ - 4
+
+ - 0
+
+
diff --git a/res/xml/wifi_tether_settings.xml b/res/xml/wifi_tether_settings.xml
index f9d9596ea24..f07944eebd3 100644
--- a/res/xml/wifi_tether_settings.xml
+++ b/res/xml/wifi_tether_settings.xml
@@ -19,13 +19,20 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:title="@string/wifi_hotspot_checkbox_text"
- settings:initialExpandedChildrenCount="2">
+ settings:initialExpandedChildrenCount="3">
+
+
@@ -33,7 +40,7 @@
+ android:summary="@string/wifi_hotspot_auto_off_summary" />
+ android:positiveButtonText="@string/apply" />
\ No newline at end of file
diff --git a/src/com/android/settings/wifi/WifiUtils.java b/src/com/android/settings/wifi/WifiUtils.java
index 3e797d77b47..99b77d9e36b 100644
--- a/src/com/android/settings/wifi/WifiUtils.java
+++ b/src/com/android/settings/wifi/WifiUtils.java
@@ -52,7 +52,7 @@ public class WifiUtils {
public static boolean isHotspotPasswordValid(String password) {
if (TextUtils.isEmpty(password)) {
- return true;
+ return false;
}
final int length = password.length();
diff --git a/src/com/android/settings/wifi/tether/WifiTetherPasswordPreferenceController.java b/src/com/android/settings/wifi/tether/WifiTetherPasswordPreferenceController.java
index 5ba0583b6ab..055e9781aea 100644
--- a/src/com/android/settings/wifi/tether/WifiTetherPasswordPreferenceController.java
+++ b/src/com/android/settings/wifi/tether/WifiTetherPasswordPreferenceController.java
@@ -31,7 +31,6 @@ import java.util.UUID;
public class WifiTetherPasswordPreferenceController extends WifiTetherBasePreferenceController
implements ValidatedEditTextPreference.Validator {
- private static final String TAG = "WifiTetherPswdPref";
private static final String PREF_KEY = "wifi_tether_network_password";
private String mPassword;
@@ -49,10 +48,11 @@ public class WifiTetherPasswordPreferenceController extends WifiTetherBasePrefer
@Override
public void updateDisplay() {
final WifiConfiguration config = mWifiManager.getWifiApConfiguration();
- if (config != null) {
- mPassword = config.preSharedKey;
- } else {
+ if (config == null || (config.getAuthType() == WifiConfiguration.KeyMgmt.WPA2_PSK
+ && TextUtils.isEmpty(config.preSharedKey))) {
mPassword = generateRandomPassword();
+ } else {
+ mPassword = config.preSharedKey;
}
((ValidatedEditTextPreference) mPreference).setValidator(this);
((ValidatedEditTextPreference) mPreference).setIsPassword(true);
@@ -68,17 +68,27 @@ public class WifiTetherPasswordPreferenceController extends WifiTetherBasePrefer
return true;
}
- public String getPassword() {
+ /**
+ * This method returns the current password if it is valid for the indicated security type. If
+ * the password currently set is invalid it will forcefully set a random password that is valid.
+ *
+ * @param securityType The security type for the password.
+ * @return The current password if it is valid for the indicated security type. A new randomly
+ * generated password if it is not.
+ */
+ public String getPasswordValidated(int securityType) {
+ // don't actually overwrite unless we get a new config in case it was accidentally toggled.
+ if (securityType == WifiConfiguration.KeyMgmt.NONE) {
+ return "";
+ } else if (!isTextValid(mPassword)) {
+ mPassword = generateRandomPassword();
+ updatePasswordDisplay((EditTextPreference) mPreference);
+ }
return mPassword;
}
- public int getSecuritySettingForPassword() {
- // We should return NONE when no password is set
- if (TextUtils.isEmpty(mPassword)) {
- return WifiConfiguration.KeyMgmt.NONE;
- }
- // Only other currently supported type is WPA2 so we'll try that
- return WifiConfiguration.KeyMgmt.WPA2_PSK;
+ public void updateVisibility(int securityType) {
+ mPreference.setVisible(securityType != WifiConfiguration.KeyMgmt.NONE);
}
@Override
@@ -98,9 +108,11 @@ public class WifiTetherPasswordPreferenceController extends WifiTetherBasePrefer
if (!TextUtils.isEmpty(mPassword)) {
pref.setIsSummaryPassword(true);
pref.setSummary(mPassword);
+ pref.setVisible(true);
} else {
pref.setIsSummaryPassword(false);
pref.setSummary(R.string.wifi_hotspot_no_password_subtext);
+ pref.setVisible(false);
}
}
}
diff --git a/src/com/android/settings/wifi/tether/WifiTetherSecurityPreferenceController.java b/src/com/android/settings/wifi/tether/WifiTetherSecurityPreferenceController.java
new file mode 100644
index 00000000000..08a956bb07d
--- /dev/null
+++ b/src/com/android/settings/wifi/tether/WifiTetherSecurityPreferenceController.java
@@ -0,0 +1,63 @@
+package com.android.settings.wifi.tether;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.net.wifi.WifiConfiguration;
+import android.support.v7.preference.ListPreference;
+import android.support.v7.preference.Preference;
+
+import com.android.settings.R;
+
+public class WifiTetherSecurityPreferenceController extends WifiTetherBasePreferenceController {
+
+ private static final String PREF_KEY = "wifi_tether_security";
+
+ private final String[] mSecurityEntries;
+ private int mSecurityValue;
+
+ public WifiTetherSecurityPreferenceController(Context context,
+ OnTetherConfigUpdateListener listener) {
+ super(context, listener);
+ mSecurityEntries = mContext.getResources().getStringArray(R.array.wifi_tether_security);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return PREF_KEY;
+ }
+
+ @Override
+ public void updateDisplay() {
+ final WifiConfiguration config = mWifiManager.getWifiApConfiguration();
+ if (config != null && config.getAuthType() == WifiConfiguration.KeyMgmt.NONE) {
+ mSecurityValue = WifiConfiguration.KeyMgmt.NONE;
+
+ } else {
+ mSecurityValue = WifiConfiguration.KeyMgmt.WPA2_PSK;
+ }
+
+ final ListPreference preference = (ListPreference) mPreference;
+ preference.setSummary(getSummaryForSecurityType(mSecurityValue));
+ preference.setValue(String.valueOf(mSecurityValue));
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ mSecurityValue = Integer.parseInt((String) newValue);
+ preference.setSummary(getSummaryForSecurityType(mSecurityValue));
+ mListener.onTetherConfigUpdated();
+ return true;
+ }
+
+ public int getSecurityType() {
+ return mSecurityValue;
+ }
+
+ private String getSummaryForSecurityType(int securityType) {
+ if (securityType == WifiConfiguration.KeyMgmt.NONE) {
+ return mSecurityEntries[1];
+ }
+ // WPA2 PSK
+ return mSecurityEntries[0];
+ }
+}
diff --git a/src/com/android/settings/wifi/tether/WifiTetherSettings.java b/src/com/android/settings/wifi/tether/WifiTetherSettings.java
index de6243c2f31..b2b60e044f7 100644
--- a/src/com/android/settings/wifi/tether/WifiTetherSettings.java
+++ b/src/com/android/settings/wifi/tether/WifiTetherSettings.java
@@ -28,7 +28,6 @@ import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.UserManager;
import android.support.annotation.VisibleForTesting;
-import android.text.TextUtils;
import android.util.Log;
import com.android.internal.logging.nano.MetricsProto;
@@ -41,7 +40,6 @@ import com.android.settingslib.core.AbstractPreferenceController;
import java.util.ArrayList;
import java.util.List;
-import java.util.UUID;
public class WifiTetherSettings extends RestrictedDashboardFragment
implements WifiTetherBasePreferenceController.OnTetherConfigUpdateListener {
@@ -54,6 +52,7 @@ public class WifiTetherSettings extends RestrictedDashboardFragment
private WifiTetherSSIDPreferenceController mSSIDPreferenceController;
private WifiTetherPasswordPreferenceController mPasswordPreferenceController;
private WifiTetherApBandPreferenceController mApBandPreferenceController;
+ private WifiTetherSecurityPreferenceController mSecurityPreferenceController;
private WifiManager mWifiManager;
private boolean mRestartWifiApAfterConfigChange;
@@ -128,10 +127,12 @@ public class WifiTetherSettings extends RestrictedDashboardFragment
protected List createPreferenceControllers(Context context) {
final List controllers = new ArrayList<>();
mSSIDPreferenceController = new WifiTetherSSIDPreferenceController(context, this);
+ mSecurityPreferenceController = new WifiTetherSecurityPreferenceController(context, this);
mPasswordPreferenceController = new WifiTetherPasswordPreferenceController(context, this);
mApBandPreferenceController = new WifiTetherApBandPreferenceController(context, this);
controllers.add(mSSIDPreferenceController);
+ controllers.add(mSecurityPreferenceController);
controllers.add(mPasswordPreferenceController);
controllers.add(mApBandPreferenceController);
controllers.add(
@@ -142,6 +143,8 @@ public class WifiTetherSettings extends RestrictedDashboardFragment
@Override
public void onTetherConfigUpdated() {
final WifiConfiguration config = buildNewConfig();
+ mPasswordPreferenceController.updateVisibility(config.getAuthType());
+
/**
* if soft AP is stopped, bring up
* else restart with new config
@@ -158,11 +161,11 @@ public class WifiTetherSettings extends RestrictedDashboardFragment
private WifiConfiguration buildNewConfig() {
final WifiConfiguration config = new WifiConfiguration();
+ final int securityType = mSecurityPreferenceController.getSecurityType();
config.SSID = mSSIDPreferenceController.getSSID();
- config.preSharedKey = mPasswordPreferenceController.getPassword();
- config.allowedKeyManagement.set(
- mPasswordPreferenceController.getSecuritySettingForPassword());
+ config.allowedKeyManagement.set(securityType);
+ config.preSharedKey = mPasswordPreferenceController.getPasswordValidated(securityType);
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
config.apBand = mApBandPreferenceController.getBandIndex();
return config;
@@ -176,6 +179,8 @@ public class WifiTetherSettings extends RestrictedDashboardFragment
private void updateDisplayWithNewConfig() {
use(WifiTetherSSIDPreferenceController.class)
.updateDisplay();
+ use(WifiTetherSecurityPreferenceController.class)
+ .updateDisplay();
use(WifiTetherPasswordPreferenceController.class)
.updateDisplay();
use(WifiTetherApBandPreferenceController.class)
diff --git a/tests/robotests/src/com/android/settings/wifi/WifiUtilsTest.java b/tests/robotests/src/com/android/settings/wifi/WifiUtilsTest.java
index 198517a297f..1f49654c402 100644
--- a/tests/robotests/src/com/android/settings/wifi/WifiUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/WifiUtilsTest.java
@@ -43,6 +43,6 @@ public class WifiUtilsTest {
assertThat(WifiUtils.isHotspotPasswordValid("12345678")).isTrue();
assertThat(WifiUtils.isHotspotPasswordValid("1234567890")).isTrue();
assertThat(WifiUtils.isHotspotPasswordValid(longPassword)).isFalse();
- assertThat(WifiUtils.isHotspotPasswordValid("")).isTrue();
+ assertThat(WifiUtils.isHotspotPasswordValid("")).isFalse();
}
}
diff --git a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPasswordPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPasswordPreferenceControllerTest.java
index 7e757ad5f84..2de98d96e7a 100644
--- a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPasswordPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherPasswordPreferenceControllerTest.java
@@ -42,6 +42,8 @@ import org.robolectric.RuntimeEnvironment;
@RunWith(SettingsRobolectricTestRunner.class)
public class WifiTetherPasswordPreferenceControllerTest {
+ private static final String VALID_PASS = "12345678";
+ private static final String VALID_PASS2 = "23456789";
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Context mContext;
@Mock
@@ -87,11 +89,13 @@ public class WifiTetherPasswordPreferenceControllerTest {
@Test
public void changePreference_shouldUpdateValue() {
mController.displayPreference(mScreen);
- mController.onPreferenceChange(mPreference, "1");
- assertThat(mController.getPassword()).isEqualTo("1");
+ mController.onPreferenceChange(mPreference, VALID_PASS);
+ assertThat(mController.getPasswordValidated(WifiConfiguration.KeyMgmt.WPA2_PSK))
+ .isEqualTo(VALID_PASS);
- mController.onPreferenceChange(mPreference, "0");
- assertThat(mController.getPassword()).isEqualTo("0");
+ mController.onPreferenceChange(mPreference, VALID_PASS2);
+ assertThat(mController.getPasswordValidated(WifiConfiguration.KeyMgmt.WPA2_PSK))
+ .isEqualTo(VALID_PASS2);
verify(mListener, times(2)).onTetherConfigUpdated();
}
@@ -100,62 +104,33 @@ public class WifiTetherPasswordPreferenceControllerTest {
public void updateDisplay_shouldUpdateValue() {
// Set controller password to anything and verify is set.
mController.displayPreference(mScreen);
- mController.onPreferenceChange(mPreference, "1");
- assertThat(mController.getPassword()).isEqualTo("1");
+ mController.onPreferenceChange(mPreference, VALID_PASS);
+ assertThat(mController.getPasswordValidated(WifiConfiguration.KeyMgmt.WPA2_PSK))
+ .isEqualTo(VALID_PASS);
// Create a new config using different password
final WifiConfiguration config = new WifiConfiguration();
- config.preSharedKey = "test_1234";
+ config.preSharedKey = VALID_PASS2;
when(mWifiManager.getWifiApConfiguration()).thenReturn(config);
// Call updateDisplay and verify it's changed.
mController.updateDisplay();
- assertThat(mController.getPassword()).isEqualTo(config.preSharedKey);
+ assertThat(mController.getPasswordValidated(WifiConfiguration.KeyMgmt.WPA2_PSK))
+ .isEqualTo(config.preSharedKey);
assertThat(mPreference.getSummary()).isEqualTo(config.preSharedKey);
}
- @Test
- public void getSecuritySettingForPassword_returnCorrectType() {
- // valid wpa2 password
- mController.displayPreference(mScreen);
- assertThat(mController.getSecuritySettingForPassword())
- .isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK);
-
- // password which is empty returns NONE
- mConfig = new WifiConfiguration();
- mConfig.SSID = "test_1234";
- mConfig.preSharedKey = "";
- when(mContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifiManager);
- when(mWifiManager.getWifiApConfiguration()).thenReturn(mConfig);
- mController = new WifiTetherPasswordPreferenceController(mContext, mListener);
-
- mController.displayPreference(mScreen);
- assertThat(mController.getSecuritySettingForPassword())
- .isEqualTo(WifiConfiguration.KeyMgmt.NONE);
-
- // default for unsupported types is wpa2
- mConfig = new WifiConfiguration();
- mConfig.SSID = "test_1234";
- mConfig.preSharedKey = "short";
- when(mContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifiManager);
- when(mWifiManager.getWifiApConfiguration()).thenReturn(mConfig);
- mController = new WifiTetherPasswordPreferenceController(mContext, mListener);
-
- mController.displayPreference(mScreen);
- assertThat(mController.getSecuritySettingForPassword())
- .isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK);
- }
-
@Test
public void updateDisplay_shouldSetInputType() {
// Set controller password to anything and verify is set.
mController.displayPreference(mScreen);
- mController.onPreferenceChange(mPreference, "1");
- assertThat(mController.getPassword()).isEqualTo("1");
+ mController.onPreferenceChange(mPreference, VALID_PASS);
+ assertThat(mController.getPasswordValidated(WifiConfiguration.KeyMgmt.WPA2_PSK))
+ .isEqualTo(VALID_PASS);
// Create a new config using different password
final WifiConfiguration config = new WifiConfiguration();
- config.preSharedKey = "test_1234";
+ config.preSharedKey = VALID_PASS2;
when(mWifiManager.getWifiApConfiguration()).thenReturn(config);
// Call updateDisplay and verify it's changed.
diff --git a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSecurityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSecurityPreferenceControllerTest.java
new file mode 100644
index 00000000000..4108df448de
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherSecurityPreferenceControllerTest.java
@@ -0,0 +1,99 @@
+package com.android.settings.wifi.tether;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiManager;
+import android.support.v7.preference.ListPreference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class WifiTetherSecurityPreferenceControllerTest {
+
+ private static final String WPA2_PSK = String.valueOf(WifiConfiguration.KeyMgmt.WPA2_PSK);
+ private static final String NONE = String.valueOf(WifiConfiguration.KeyMgmt.NONE);
+ @Mock
+ private WifiTetherBasePreferenceController.OnTetherConfigUpdateListener mListener;
+ private Context mContext;
+ @Mock
+ private ConnectivityManager mConnectivityManager;
+ @Mock
+ private WifiManager mWifiManager;
+ @Mock
+ private PreferenceScreen mScreen;
+ private WifiTetherSecurityPreferenceController mController;
+ private ListPreference mPreference;
+ private WifiConfiguration mConfig;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mConfig = new WifiConfiguration();
+ mConfig.SSID = "test_1234";
+ mConfig.preSharedKey = "test_password";
+ mConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA2_PSK);
+ mContext = spy(RuntimeEnvironment.application);
+
+ when(mContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifiManager);
+ when(mWifiManager.getWifiApConfiguration()).thenReturn(mConfig);
+ when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE))
+ .thenReturn(mConnectivityManager);
+ when(mConnectivityManager.getTetherableWifiRegexs()).thenReturn(new String[]{"1", "2"});
+ when(mScreen.findPreference(anyString())).thenReturn(mPreference);
+
+ mController = new WifiTetherSecurityPreferenceController(mContext, mListener);
+ mPreference = new ListPreference(RuntimeEnvironment.application);
+ mController.mPreference = mPreference;
+ }
+
+ @Test
+ public void onPreferenceChange_securityValueUpdated() {
+ mController.onPreferenceChange(mPreference, WPA2_PSK);
+ assertThat(mController.getSecurityType()).isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK);
+ assertThat(mPreference.getSummary()).isEqualTo("WPA2 PSK");
+
+ mController.onPreferenceChange(mPreference, NONE);
+ assertThat(mController.getSecurityType()).isEqualTo(WifiConfiguration.KeyMgmt.NONE);
+ assertThat(mPreference.getSummary()).isEqualTo("None");
+ }
+
+ @Test
+ public void updateDisplay_preferenceUpdated() {
+ // test defaulting to WPA2 PSK on new config
+ when(mWifiManager.getWifiApConfiguration()).thenReturn(null);
+ mController.updateDisplay();
+ assertThat(mController.getSecurityType()).isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK);
+ assertThat(mPreference.getSummary()).isEqualTo("WPA2 PSK");
+
+ // test open tether network
+ when(mWifiManager.getWifiApConfiguration()).thenReturn(mConfig);
+ mConfig.allowedKeyManagement.clear();
+ mConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
+ mController.updateDisplay();
+ assertThat(mController.getSecurityType()).isEqualTo(WifiConfiguration.KeyMgmt.NONE);
+ assertThat(mPreference.getSummary()).isEqualTo("None");
+
+ // test WPA2 PSK tether network
+ mConfig.allowedKeyManagement.clear();
+ mConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA2_PSK);
+ mController.updateDisplay();
+ assertThat(mController.getSecurityType()).isEqualTo(WifiConfiguration.KeyMgmt.WPA2_PSK);
+ assertThat(mPreference.getSummary()).isEqualTo("WPA2 PSK");
+ }
+}