Refactor hotspot into a full page
- Deprecated WifiAPEnabler, and copied most of its logic into various controllers and WifiTetherSettings. - Added tests Fix: 37253404 Fix: 36181835 Test: make RunSettingsRoboTests Change-Id: Iad994d61b694ad7f1113d045a3e7500eeaec178b
This commit is contained in:
@@ -17,10 +17,16 @@
|
|||||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:settings="http://schemas.android.com/apk/res-auto">
|
xmlns:settings="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
android:key="wifi_tether"
|
||||||
|
android:title="@string/wifi_tether_checkbox_text"
|
||||||
|
android:summary="@string/summary_placeholder"
|
||||||
|
android:fragment="com.android.settings.wifi.tether.WifiTetherSettings" />
|
||||||
|
|
||||||
<SwitchPreference
|
<SwitchPreference
|
||||||
android:key="usb_tether_settings"
|
android:key="usb_tether_settings"
|
||||||
android:title="@string/usb_tethering_button_text"
|
android:title="@string/usb_tethering_button_text"
|
||||||
android:summary="@string/usb_tethering_subtext"/>
|
android:summary="@string/usb_tethering_subtext" />
|
||||||
|
|
||||||
<SwitchPreference
|
<SwitchPreference
|
||||||
android:key="enable_wifi_ap"
|
android:key="enable_wifi_ap"
|
||||||
@@ -35,7 +41,7 @@
|
|||||||
<SwitchPreference
|
<SwitchPreference
|
||||||
android:key="enable_bluetooth_tethering"
|
android:key="enable_bluetooth_tethering"
|
||||||
android:title="@string/bluetooth_tether_checkbox_text"
|
android:title="@string/bluetooth_tether_checkbox_text"
|
||||||
android:summary="@string/bluetooth_tethering_subtext"/>
|
android:summary="@string/bluetooth_tethering_subtext" />
|
||||||
|
|
||||||
<Preference
|
<Preference
|
||||||
android:key="disabled_on_data_saver"
|
android:key="disabled_on_data_saver"
|
||||||
|
33
res/xml/wifi_tether_settings.xml
Normal file
33
res/xml/wifi_tether_settings.xml
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2017 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<com.android.settings.widget.ValidatedEditTextPreference
|
||||||
|
android:key="wifi_tether_network_name"
|
||||||
|
android:title="@string/wifi_ssid"
|
||||||
|
android:summary="@string/summary_placeholder" />
|
||||||
|
|
||||||
|
<com.android.settings.widget.ValidatedEditTextPreference
|
||||||
|
android:key="wifi_tether_network_password"
|
||||||
|
android:title="@string/wifi_password" />
|
||||||
|
|
||||||
|
<ListPreference
|
||||||
|
android:key="wifi_tether_network_ap_band"
|
||||||
|
android:title="@string/wifi_ap_band_config"
|
||||||
|
android:summary="@string/summary_placeholder" />
|
||||||
|
</PreferenceScreen>
|
@@ -43,6 +43,8 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
|||||||
import com.android.settings.datausage.DataSaverBackend;
|
import com.android.settings.datausage.DataSaverBackend;
|
||||||
import com.android.settings.wifi.WifiApDialog;
|
import com.android.settings.wifi.WifiApDialog;
|
||||||
import com.android.settings.wifi.WifiApEnabler;
|
import com.android.settings.wifi.WifiApEnabler;
|
||||||
|
import com.android.settings.wifi.tether.WifiTetherPreferenceController;
|
||||||
|
import com.android.settings.wifi.tether.WifiTetherSettings;
|
||||||
import com.android.settingslib.TetherUtil;
|
import com.android.settingslib.TetherUtil;
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
@@ -63,7 +65,6 @@ public class TetherSettings extends RestrictedSettingsFragment
|
|||||||
private static final String USB_TETHER_SETTINGS = "usb_tether_settings";
|
private static final String USB_TETHER_SETTINGS = "usb_tether_settings";
|
||||||
private static final String ENABLE_WIFI_AP = "enable_wifi_ap";
|
private static final String ENABLE_WIFI_AP = "enable_wifi_ap";
|
||||||
private static final String ENABLE_BLUETOOTH_TETHERING = "enable_bluetooth_tethering";
|
private static final String ENABLE_BLUETOOTH_TETHERING = "enable_bluetooth_tethering";
|
||||||
private static final String TETHER_CHOICE = "TETHER_TYPE";
|
|
||||||
private static final String DATA_SAVER_FOOTER = "disabled_on_data_saver";
|
private static final String DATA_SAVER_FOOTER = "disabled_on_data_saver";
|
||||||
|
|
||||||
private static final int DIALOG_AP_SETTINGS = 1;
|
private static final int DIALOG_AP_SETTINGS = 1;
|
||||||
@@ -100,17 +101,14 @@ public class TetherSettings extends RestrictedSettingsFragment
|
|||||||
private WifiConfiguration mWifiConfig = null;
|
private WifiConfiguration mWifiConfig = null;
|
||||||
private ConnectivityManager mCm;
|
private ConnectivityManager mCm;
|
||||||
|
|
||||||
|
private WifiTetherPreferenceController mWifiTetherPreferenceController;
|
||||||
|
|
||||||
private boolean mRestartWifiApAfterConfigChange;
|
private boolean mRestartWifiApAfterConfigChange;
|
||||||
|
|
||||||
private boolean mUsbConnected;
|
private boolean mUsbConnected;
|
||||||
private boolean mMassStorageActive;
|
private boolean mMassStorageActive;
|
||||||
|
|
||||||
private boolean mBluetoothEnableForTether;
|
private boolean mBluetoothEnableForTether;
|
||||||
|
|
||||||
/* Stores the package name and the class name of the provisioning app */
|
|
||||||
private String[] mProvisionApp;
|
|
||||||
private static final int PROVISION_REQUEST = 0;
|
|
||||||
|
|
||||||
private boolean mUnavailable;
|
private boolean mUnavailable;
|
||||||
|
|
||||||
private DataSaverBackend mDataSaverBackend;
|
private DataSaverBackend mDataSaverBackend;
|
||||||
@@ -126,6 +124,13 @@ public class TetherSettings extends RestrictedSettingsFragment
|
|||||||
super(UserManager.DISALLOW_CONFIG_TETHERING);
|
super(UserManager.DISALLOW_CONFIG_TETHERING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(Context context) {
|
||||||
|
super.onAttach(context);
|
||||||
|
mWifiTetherPreferenceController =
|
||||||
|
new WifiTetherPreferenceController(context, getLifecycle());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle icicle) {
|
public void onCreate(Bundle icicle) {
|
||||||
super.onCreate(icicle);
|
super.onCreate(icicle);
|
||||||
@@ -154,6 +159,7 @@ public class TetherSettings extends RestrictedSettingsFragment
|
|||||||
|
|
||||||
mEnableWifiAp =
|
mEnableWifiAp =
|
||||||
(SwitchPreference) findPreference(ENABLE_WIFI_AP);
|
(SwitchPreference) findPreference(ENABLE_WIFI_AP);
|
||||||
|
|
||||||
Preference wifiApSettings = findPreference(WIFI_AP_SSID_AND_SECURITY);
|
Preference wifiApSettings = findPreference(WIFI_AP_SSID_AND_SECURITY);
|
||||||
mUsbTether = (SwitchPreference) findPreference(USB_TETHER_SETTINGS);
|
mUsbTether = (SwitchPreference) findPreference(USB_TETHER_SETTINGS);
|
||||||
mBluetoothTether = (SwitchPreference) findPreference(ENABLE_BLUETOOTH_TETHERING);
|
mBluetoothTether = (SwitchPreference) findPreference(ENABLE_BLUETOOTH_TETHERING);
|
||||||
@@ -175,6 +181,11 @@ public class TetherSettings extends RestrictedSettingsFragment
|
|||||||
getPreferenceScreen().removePreference(mUsbTether);
|
getPreferenceScreen().removePreference(mUsbTether);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mWifiTetherPreferenceController.displayPreference(getPreferenceScreen());
|
||||||
|
if (WifiTetherSettings.isTetherSettingPageEnabled()) {
|
||||||
|
removePreference(ENABLE_WIFI_AP);
|
||||||
|
removePreference(WIFI_AP_SSID_AND_SECURITY);
|
||||||
|
} else {
|
||||||
if (wifiAvailable && !Utils.isMonkeyRunning()) {
|
if (wifiAvailable && !Utils.isMonkeyRunning()) {
|
||||||
mWifiApEnabler = new WifiApEnabler(activity, mDataSaverBackend, mEnableWifiAp);
|
mWifiApEnabler = new WifiApEnabler(activity, mDataSaverBackend, mEnableWifiAp);
|
||||||
initWifiTethering();
|
initWifiTethering();
|
||||||
@@ -182,6 +193,7 @@ public class TetherSettings extends RestrictedSettingsFragment
|
|||||||
getPreferenceScreen().removePreference(mEnableWifiAp);
|
getPreferenceScreen().removePreference(mEnableWifiAp);
|
||||||
getPreferenceScreen().removePreference(wifiApSettings);
|
getPreferenceScreen().removePreference(wifiApSettings);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!bluetoothAvailable) {
|
if (!bluetoothAvailable) {
|
||||||
getPreferenceScreen().removePreference(mBluetoothTether);
|
getPreferenceScreen().removePreference(mBluetoothTether);
|
||||||
|
111
src/com/android/settings/widget/ValidatedEditTextPreference.java
Normal file
111
src/com/android/settings/widget/ValidatedEditTextPreference.java
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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.widget;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.support.annotation.VisibleForTesting;
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.text.InputType;
|
||||||
|
import android.text.TextWatcher;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.EditText;
|
||||||
|
|
||||||
|
import com.android.settings.CustomEditTextPreference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code EditTextPreference} that supports input validation.
|
||||||
|
*/
|
||||||
|
public class ValidatedEditTextPreference extends CustomEditTextPreference {
|
||||||
|
|
||||||
|
public interface Validator {
|
||||||
|
boolean isTextValid(String value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final EditTextWatcher mTextWatcher = new EditTextWatcher();
|
||||||
|
private Validator mValidator;
|
||||||
|
private boolean mIsPassword;
|
||||||
|
|
||||||
|
public ValidatedEditTextPreference(Context context, AttributeSet attrs,
|
||||||
|
int defStyleAttr, int defStyleRes) {
|
||||||
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValidatedEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValidatedEditTextPreference(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValidatedEditTextPreference(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onBindDialogView(View view) {
|
||||||
|
super.onBindDialogView(view);
|
||||||
|
if (mValidator != null) {
|
||||||
|
final EditText editText = view.findViewById(android.R.id.edit);
|
||||||
|
if (editText != null) {
|
||||||
|
editText.removeTextChangedListener(mTextWatcher);
|
||||||
|
if (mIsPassword) {
|
||||||
|
editText.setInputType(
|
||||||
|
InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
|
||||||
|
editText.setMaxLines(1);
|
||||||
|
}
|
||||||
|
editText.addTextChangedListener(mTextWatcher);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsPassword(boolean isPassword) {
|
||||||
|
mIsPassword = isPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
|
||||||
|
public boolean isPassword() {
|
||||||
|
return mIsPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValidator(Validator validator) {
|
||||||
|
mValidator = validator;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class EditTextWatcher implements TextWatcher {
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) {
|
||||||
|
final EditText editText = getEditText();
|
||||||
|
if (mValidator != null && editText != null) {
|
||||||
|
final AlertDialog dialog = (AlertDialog) getDialog();
|
||||||
|
final boolean valid = mValidator.isTextValid(editText.getText().toString());
|
||||||
|
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(valid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -32,6 +32,10 @@ import com.android.settings.datausage.DataSaverBackend;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated in favor of WifiTetherPreferenceController and WifiTetherSettings
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public class WifiApEnabler {
|
public class WifiApEnabler {
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final SwitchPreference mSwitch;
|
private final SwitchPreference mSwitch;
|
||||||
|
@@ -110,7 +110,6 @@ public class WifiConfigController implements TextWatcher,
|
|||||||
public static final int WIFI_PEAP_PHASE2_AKA = 4;
|
public static final int WIFI_PEAP_PHASE2_AKA = 4;
|
||||||
public static final int WIFI_PEAP_PHASE2_AKA_PRIME = 5;
|
public static final int WIFI_PEAP_PHASE2_AKA_PRIME = 5;
|
||||||
|
|
||||||
private static final int SSID_ASCII_MAX_LENGTH = 32;
|
|
||||||
|
|
||||||
/* Phase2 methods supported by PEAP are limited */
|
/* Phase2 methods supported by PEAP are limited */
|
||||||
private final ArrayAdapter<String> mPhase2PeapAdapter;
|
private final ArrayAdapter<String> mPhase2PeapAdapter;
|
||||||
@@ -463,7 +462,7 @@ public class WifiConfigController implements TextWatcher,
|
|||||||
|
|
||||||
if (mSsidView != null) {
|
if (mSsidView != null) {
|
||||||
final String ssid = mSsidView.getText().toString();
|
final String ssid = mSsidView.getText().toString();
|
||||||
if (ssid.length() > SSID_ASCII_MAX_LENGTH) {
|
if (WifiUtils.isSSIDTooLong(ssid)) {
|
||||||
mView.findViewById(R.id.ssid_too_long_warning).setVisibility(View.VISIBLE);
|
mView.findViewById(R.id.ssid_too_long_warning).setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
50
src/com/android/settings/wifi/WifiUtils.java
Normal file
50
src/com/android/settings/wifi/WifiUtils.java
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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;
|
||||||
|
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
public class WifiUtils {
|
||||||
|
|
||||||
|
private static final int SSID_ASCII_MIN_LENGTH = 1;
|
||||||
|
private static final int SSID_ASCII_MAX_LENGTH = 32;
|
||||||
|
private static final int PASSWORD_MIN_LENGTH = 8;
|
||||||
|
private static final int PASSWORD_MAX_LENGTH = 63;
|
||||||
|
|
||||||
|
|
||||||
|
public static boolean isSSIDTooLong(String ssid) {
|
||||||
|
if (TextUtils.isEmpty(ssid)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return ssid.length() > SSID_ASCII_MAX_LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isSSIDTooShort(String ssid) {
|
||||||
|
if (TextUtils.isEmpty(ssid)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return ssid.length() < SSID_ASCII_MIN_LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isPasswordValid(String password) {
|
||||||
|
if (TextUtils.isEmpty(password)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
final int length = password.length();
|
||||||
|
return length >= PASSWORD_MIN_LENGTH && length <= PASSWORD_MAX_LENGTH;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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.tether;
|
||||||
|
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
|
|
||||||
|
class NoOpOnStartTetheringCallback extends ConnectivityManager.OnStartTetheringCallback {
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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.tether;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.wifi.WifiConfiguration;
|
||||||
|
import android.support.v7.preference.ListPreference;
|
||||||
|
import android.support.v7.preference.Preference;
|
||||||
|
import android.support.v7.preference.PreferenceScreen;
|
||||||
|
|
||||||
|
import com.android.settings.R;
|
||||||
|
|
||||||
|
import static android.net.wifi.WifiConfiguration.AP_BAND_2GHZ;
|
||||||
|
import static android.net.wifi.WifiConfiguration.AP_BAND_5GHZ;
|
||||||
|
|
||||||
|
public class WifiTetherApBandPreferenceController extends WifiTetherBasePreferenceController {
|
||||||
|
|
||||||
|
private static final String PREF_KEY = "wifi_tether_network_ap_band";
|
||||||
|
private static final String[] BAND_VALUES =
|
||||||
|
{String.valueOf(AP_BAND_2GHZ), String.valueOf(AP_BAND_5GHZ)};
|
||||||
|
|
||||||
|
private final String[] mBandEntries;
|
||||||
|
private int mBandIndex;
|
||||||
|
|
||||||
|
public WifiTetherApBandPreferenceController(Context context,
|
||||||
|
OnTetherConfigUpdateListener listener) {
|
||||||
|
super(context, listener);
|
||||||
|
mBandEntries = mContext.getResources().getStringArray(R.array.wifi_ap_band_config_full);
|
||||||
|
final WifiConfiguration config = mWifiManager.getWifiApConfiguration();
|
||||||
|
if (config != null) {
|
||||||
|
mBandIndex = config.apBand;
|
||||||
|
} else {
|
||||||
|
mBandIndex = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void displayPreference(PreferenceScreen screen) {
|
||||||
|
super.displayPreference(screen);
|
||||||
|
ListPreference preference = (ListPreference) mPreference;
|
||||||
|
if (!is5GhzBandSupported()) {
|
||||||
|
preference.setEnabled(false);
|
||||||
|
preference.setSummary(R.string.wifi_ap_choose_2G);
|
||||||
|
} else {
|
||||||
|
preference.setEntries(mBandEntries);
|
||||||
|
preference.setEntryValues(BAND_VALUES);
|
||||||
|
preference.setSummary(mBandEntries[mBandIndex]);
|
||||||
|
preference.setValue(String.valueOf(mBandIndex));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPreferenceKey() {
|
||||||
|
return PREF_KEY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
|
mBandIndex = Integer.parseInt((String) newValue);
|
||||||
|
preference.setSummary(mBandEntries[mBandIndex]);
|
||||||
|
mListener.onTetherConfigUpdated();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean is5GhzBandSupported() {
|
||||||
|
if (mBandIndex > 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return mWifiManager.is5GHzBandSupported();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBandIndex() {
|
||||||
|
return mBandIndex;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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.tether;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.wifi.WifiManager;
|
||||||
|
import android.support.v7.preference.Preference;
|
||||||
|
import android.support.v7.preference.PreferenceScreen;
|
||||||
|
|
||||||
|
import com.android.settings.core.PreferenceController;
|
||||||
|
|
||||||
|
public abstract class WifiTetherBasePreferenceController extends PreferenceController
|
||||||
|
implements Preference.OnPreferenceChangeListener {
|
||||||
|
|
||||||
|
public interface OnTetherConfigUpdateListener {
|
||||||
|
void onTetherConfigUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final WifiManager mWifiManager;
|
||||||
|
protected final String[] mWifiRegexs;
|
||||||
|
protected final ConnectivityManager mCm;
|
||||||
|
protected final OnTetherConfigUpdateListener mListener;
|
||||||
|
|
||||||
|
protected Preference mPreference;
|
||||||
|
|
||||||
|
public WifiTetherBasePreferenceController(Context context,
|
||||||
|
OnTetherConfigUpdateListener listener) {
|
||||||
|
super(context);
|
||||||
|
mListener = listener;
|
||||||
|
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
|
||||||
|
mCm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
|
mWifiRegexs = mCm.getTetherableWifiRegexs();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAvailable() {
|
||||||
|
return mWifiManager != null && mWifiRegexs != null && mWifiRegexs.length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void displayPreference(PreferenceScreen screen) {
|
||||||
|
super.displayPreference(screen);
|
||||||
|
mPreference = screen.findPreference(getPreferenceKey());
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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.tether;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.wifi.WifiConfiguration;
|
||||||
|
import android.support.v7.preference.Preference;
|
||||||
|
import android.support.v7.preference.PreferenceScreen;
|
||||||
|
|
||||||
|
import com.android.settings.widget.ValidatedEditTextPreference;
|
||||||
|
import com.android.settings.wifi.WifiUtils;
|
||||||
|
|
||||||
|
public class WifiTetherPasswordPreferenceController extends WifiTetherBasePreferenceController
|
||||||
|
implements ValidatedEditTextPreference.Validator {
|
||||||
|
|
||||||
|
private static final String PREF_KEY = "wifi_tether_network_password";
|
||||||
|
|
||||||
|
private String mPassword;
|
||||||
|
|
||||||
|
public WifiTetherPasswordPreferenceController(Context context,
|
||||||
|
OnTetherConfigUpdateListener listener) {
|
||||||
|
super(context, listener);
|
||||||
|
final WifiConfiguration config = mWifiManager.getWifiApConfiguration();
|
||||||
|
if (config != null) {
|
||||||
|
mPassword = config.preSharedKey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPreferenceKey() {
|
||||||
|
return PREF_KEY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void displayPreference(PreferenceScreen screen) {
|
||||||
|
super.displayPreference(screen);
|
||||||
|
((ValidatedEditTextPreference) mPreference).setText(mPassword);
|
||||||
|
((ValidatedEditTextPreference) mPreference).setIsPassword(true);
|
||||||
|
((ValidatedEditTextPreference) mPreference).setValidator(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
|
mPassword = (String) newValue;
|
||||||
|
((ValidatedEditTextPreference) mPreference).setText(mPassword);
|
||||||
|
mListener.onTetherConfigUpdated();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return mPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isTextValid(String value) {
|
||||||
|
return WifiUtils.isPasswordValid(value);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,200 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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.tether;
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.wifi.WifiConfiguration;
|
||||||
|
import android.net.wifi.WifiManager;
|
||||||
|
import android.provider.Settings;
|
||||||
|
import android.support.v7.preference.Preference;
|
||||||
|
import android.support.v7.preference.PreferenceScreen;
|
||||||
|
import android.text.BidiFormatter;
|
||||||
|
|
||||||
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.Utils;
|
||||||
|
import com.android.settings.core.PreferenceController;
|
||||||
|
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||||
|
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||||
|
import com.android.settingslib.core.lifecycle.events.OnPause;
|
||||||
|
import com.android.settingslib.core.lifecycle.events.OnResume;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class WifiTetherPreferenceController extends PreferenceController
|
||||||
|
implements LifecycleObserver, OnResume, OnPause {
|
||||||
|
|
||||||
|
public static final IntentFilter WIFI_TETHER_INTENT_FILTER;
|
||||||
|
private static final String WIFI_TETHER_SETTINGS = "wifi_tether";
|
||||||
|
|
||||||
|
private final ConnectivityManager mConnectivityManager;
|
||||||
|
private final String[] mWifiRegexs;
|
||||||
|
private final WifiManager mWifiManager;
|
||||||
|
private Preference mPreference;
|
||||||
|
|
||||||
|
static {
|
||||||
|
WIFI_TETHER_INTENT_FILTER = new IntentFilter(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
|
||||||
|
WIFI_TETHER_INTENT_FILTER.addAction(ConnectivityManager.ACTION_TETHER_STATE_CHANGED);
|
||||||
|
WIFI_TETHER_INTENT_FILTER.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WifiTetherPreferenceController(Context context, Lifecycle lifecycle) {
|
||||||
|
super(context);
|
||||||
|
mConnectivityManager =
|
||||||
|
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
|
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
|
||||||
|
|
||||||
|
mWifiRegexs = mConnectivityManager.getTetherableWifiRegexs();
|
||||||
|
|
||||||
|
if (lifecycle != null) {
|
||||||
|
lifecycle.addObserver(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAvailable() {
|
||||||
|
return mWifiRegexs != null
|
||||||
|
&& mWifiRegexs.length != 0
|
||||||
|
&& WifiTetherSettings.isTetherSettingPageEnabled()
|
||||||
|
&& !Utils.isMonkeyRunning();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void displayPreference(PreferenceScreen screen) {
|
||||||
|
super.displayPreference(screen);
|
||||||
|
mPreference = screen.findPreference(WIFI_TETHER_SETTINGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPreferenceKey() {
|
||||||
|
return WIFI_TETHER_SETTINGS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
if (mPreference != null) {
|
||||||
|
mContext.registerReceiver(mReceiver, WIFI_TETHER_INTENT_FILTER);
|
||||||
|
clearSummaryForAirplaneMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
if (mPreference != null) {
|
||||||
|
mContext.unregisterReceiver(mReceiver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Everything below is copied from WifiApEnabler
|
||||||
|
//
|
||||||
|
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
String action = intent.getAction();
|
||||||
|
if (WifiManager.WIFI_AP_STATE_CHANGED_ACTION.equals(action)) {
|
||||||
|
int state = intent.getIntExtra(
|
||||||
|
WifiManager.EXTRA_WIFI_AP_STATE, WifiManager.WIFI_AP_STATE_FAILED);
|
||||||
|
int reason = intent.getIntExtra(WifiManager.EXTRA_WIFI_AP_FAILURE_REASON,
|
||||||
|
WifiManager.SAP_START_FAILURE_GENERAL);
|
||||||
|
handleWifiApStateChanged(state, reason);
|
||||||
|
} else if (ConnectivityManager.ACTION_TETHER_STATE_CHANGED.equals(action)) {
|
||||||
|
List<String> active = intent.getStringArrayListExtra(
|
||||||
|
ConnectivityManager.EXTRA_ACTIVE_TETHER);
|
||||||
|
List<String> errored = intent.getStringArrayListExtra(
|
||||||
|
ConnectivityManager.EXTRA_ERRORED_TETHER);
|
||||||
|
updateTetherState(active.toArray(), errored.toArray());
|
||||||
|
} else if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)) {
|
||||||
|
clearSummaryForAirplaneMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private void handleWifiApStateChanged(int state, int reason) {
|
||||||
|
switch (state) {
|
||||||
|
case WifiManager.WIFI_AP_STATE_ENABLED:
|
||||||
|
/**
|
||||||
|
* Summary on enable is handled by tether
|
||||||
|
* broadcast notice
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
case WifiManager.WIFI_AP_STATE_DISABLING:
|
||||||
|
mPreference.setSummary(R.string.wifi_tether_stopping);
|
||||||
|
break;
|
||||||
|
case WifiManager.WIFI_AP_STATE_DISABLED:
|
||||||
|
mPreference.setSummary(R.string.wifi_hotspot_off_subtext);
|
||||||
|
clearSummaryForAirplaneMode();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (reason == WifiManager.SAP_START_FAILURE_NO_CHANNEL) {
|
||||||
|
mPreference.setSummary(R.string.wifi_sap_no_channel_error);
|
||||||
|
} else {
|
||||||
|
mPreference.setSummary(R.string.wifi_error);
|
||||||
|
}
|
||||||
|
clearSummaryForAirplaneMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateTetherState(Object[] tethered, Object[] errored) {
|
||||||
|
boolean wifiTethered = matchRegex(tethered);
|
||||||
|
boolean wifiErrored = matchRegex(errored);
|
||||||
|
|
||||||
|
if (wifiTethered) {
|
||||||
|
WifiConfiguration wifiConfig = mWifiManager.getWifiApConfiguration();
|
||||||
|
updateConfigSummary(wifiConfig);
|
||||||
|
} else if (wifiErrored) {
|
||||||
|
mPreference.setSummary(R.string.wifi_error);
|
||||||
|
} else {
|
||||||
|
mPreference.setSummary(R.string.wifi_hotspot_off_subtext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean matchRegex(Object[] tethers) {
|
||||||
|
for (Object o : tethers) {
|
||||||
|
String s = (String) o;
|
||||||
|
for (String regex : mWifiRegexs) {
|
||||||
|
if (s.matches(regex)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateConfigSummary(WifiConfiguration wifiConfig) {
|
||||||
|
final String s = mContext.getString(
|
||||||
|
com.android.internal.R.string.wifi_tether_configure_ssid_default);
|
||||||
|
|
||||||
|
mPreference.setSummary(mContext.getString(R.string.wifi_tether_enabled_subtext,
|
||||||
|
BidiFormatter.getInstance().unicodeWrap(
|
||||||
|
(wifiConfig == null) ? s : wifiConfig.SSID)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearSummaryForAirplaneMode() {
|
||||||
|
boolean isAirplaneMode = Settings.Global.getInt(mContext.getContentResolver(),
|
||||||
|
Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
|
||||||
|
if (isAirplaneMode) {
|
||||||
|
mPreference.setSummary(R.string.summary_placeholder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Everything above is copied from WifiApEnabler
|
||||||
|
//
|
||||||
|
}
|
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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.tether;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.wifi.WifiConfiguration;
|
||||||
|
import android.support.annotation.VisibleForTesting;
|
||||||
|
import android.support.v7.preference.EditTextPreference;
|
||||||
|
import android.support.v7.preference.Preference;
|
||||||
|
import android.support.v7.preference.PreferenceScreen;
|
||||||
|
|
||||||
|
import com.android.settings.widget.ValidatedEditTextPreference;
|
||||||
|
import com.android.settings.wifi.WifiUtils;
|
||||||
|
|
||||||
|
public class WifiTetherSSIDPreferenceController extends WifiTetherBasePreferenceController
|
||||||
|
implements ValidatedEditTextPreference.Validator {
|
||||||
|
|
||||||
|
private static final String PREF_KEY = "wifi_tether_network_name";
|
||||||
|
@VisibleForTesting
|
||||||
|
static final String DEFAULT_SSID = "AndroidAP";
|
||||||
|
|
||||||
|
private String mSSID;
|
||||||
|
|
||||||
|
public WifiTetherSSIDPreferenceController(Context context,
|
||||||
|
OnTetherConfigUpdateListener listener) {
|
||||||
|
super(context, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPreferenceKey() {
|
||||||
|
return PREF_KEY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void displayPreference(PreferenceScreen screen) {
|
||||||
|
super.displayPreference(screen);
|
||||||
|
final WifiConfiguration config = mWifiManager.getWifiApConfiguration();
|
||||||
|
if (config != null) {
|
||||||
|
mSSID = config.SSID;
|
||||||
|
} else {
|
||||||
|
mSSID = DEFAULT_SSID;
|
||||||
|
}
|
||||||
|
((ValidatedEditTextPreference) mPreference).setValidator(this);
|
||||||
|
updateSsidDisplay((EditTextPreference) mPreference);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
|
mSSID = (String) newValue;
|
||||||
|
updateSsidDisplay((EditTextPreference) preference);
|
||||||
|
mListener.onTetherConfigUpdated();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isTextValid(String value) {
|
||||||
|
return !WifiUtils.isSSIDTooLong(value) && !WifiUtils.isSSIDTooShort(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSSID() {
|
||||||
|
return mSSID;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateSsidDisplay(EditTextPreference preference) {
|
||||||
|
preference.setText(mSSID);
|
||||||
|
preference.setSummary(mSSID);
|
||||||
|
}
|
||||||
|
}
|
192
src/com/android/settings/wifi/tether/WifiTetherSettings.java
Normal file
192
src/com/android/settings/wifi/tether/WifiTetherSettings.java
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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.tether;
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
|
import android.net.wifi.WifiConfiguration;
|
||||||
|
import android.net.wifi.WifiManager;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.SystemProperties;
|
||||||
|
import android.os.UserManager;
|
||||||
|
import android.support.annotation.VisibleForTesting;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.internal.logging.nano.MetricsProto;
|
||||||
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.SettingsActivity;
|
||||||
|
import com.android.settings.core.PreferenceController;
|
||||||
|
import com.android.settings.dashboard.RestrictedDashboardFragment;
|
||||||
|
import com.android.settings.widget.SwitchBar;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED;
|
||||||
|
import static android.net.wifi.WifiManager.WIFI_AP_STATE_CHANGED_ACTION;
|
||||||
|
|
||||||
|
public class WifiTetherSettings extends RestrictedDashboardFragment
|
||||||
|
implements WifiTetherBasePreferenceController.OnTetherConfigUpdateListener {
|
||||||
|
|
||||||
|
public static boolean isTetherSettingPageEnabled() {
|
||||||
|
return SystemProperties.getBoolean("settings.ui.wifi.tether.enabled", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final IntentFilter TETHER_STATE_CHANGE_FILTER;
|
||||||
|
|
||||||
|
private WifiTetherSwitchBarController mSwitchBarController;
|
||||||
|
private WifiTetherSSIDPreferenceController mSSIDPreferenceController;
|
||||||
|
private WifiTetherPasswordPreferenceController mPasswordPreferenceController;
|
||||||
|
private WifiTetherApBandPreferenceController mApBandPreferenceController;
|
||||||
|
|
||||||
|
private WifiManager mWifiManager;
|
||||||
|
private boolean mRestartWifiApAfterConfigChange;
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
TetherChangeReceiver mTetherChangeReceiver;
|
||||||
|
|
||||||
|
static {
|
||||||
|
TETHER_STATE_CHANGE_FILTER = new IntentFilter(ACTION_TETHER_STATE_CHANGED);
|
||||||
|
TETHER_STATE_CHANGE_FILTER.addAction(WIFI_AP_STATE_CHANGED_ACTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WifiTetherSettings() {
|
||||||
|
super(UserManager.DISALLOW_CONFIG_TETHERING);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMetricsCategory() {
|
||||||
|
return MetricsProto.MetricsEvent.WIFI_TETHER_SETTINGS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getLogTag() {
|
||||||
|
return "WifiTetherSettings";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(Context context) {
|
||||||
|
super.onAttach(context);
|
||||||
|
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
|
||||||
|
mTetherChangeReceiver = new TetherChangeReceiver();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActivityCreated(Bundle savedInstanceState) {
|
||||||
|
super.onActivityCreated(savedInstanceState);
|
||||||
|
// Assume we are in a SettingsActivity. This is only safe because we currently use
|
||||||
|
// SettingsActivity as base for all preference fragments.
|
||||||
|
final SettingsActivity activity = (SettingsActivity) getActivity();
|
||||||
|
final SwitchBar switchBar = activity.getSwitchBar();
|
||||||
|
mSwitchBarController = new WifiTetherSwitchBarController(activity, switchBar);
|
||||||
|
getLifecycle().addObserver(mSwitchBarController);
|
||||||
|
switchBar.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
final Context context = getContext();
|
||||||
|
if (context != null) {
|
||||||
|
context.registerReceiver(mTetherChangeReceiver, TETHER_STATE_CHANGE_FILTER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStop() {
|
||||||
|
super.onStop();
|
||||||
|
final Context context = getContext();
|
||||||
|
if (context != null) {
|
||||||
|
context.unregisterReceiver(mTetherChangeReceiver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getPreferenceScreenResId() {
|
||||||
|
return R.xml.wifi_tether_settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<PreferenceController> getPreferenceControllers(Context context) {
|
||||||
|
final List<PreferenceController> controllers = new ArrayList<>();
|
||||||
|
mSSIDPreferenceController = new WifiTetherSSIDPreferenceController(context, this);
|
||||||
|
mPasswordPreferenceController = new WifiTetherPasswordPreferenceController(context, this);
|
||||||
|
mApBandPreferenceController = new WifiTetherApBandPreferenceController(context, this);
|
||||||
|
|
||||||
|
controllers.add(mSSIDPreferenceController);
|
||||||
|
controllers.add(mPasswordPreferenceController);
|
||||||
|
controllers.add(mApBandPreferenceController);
|
||||||
|
return controllers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTetherConfigUpdated() {
|
||||||
|
final WifiConfiguration config = buildNewConfig();
|
||||||
|
/**
|
||||||
|
* if soft AP is stopped, bring up
|
||||||
|
* else restart with new config
|
||||||
|
* TODO: update config on a running access point when framework support is added
|
||||||
|
*/
|
||||||
|
if (mWifiManager.getWifiApState() == WifiManager.WIFI_AP_STATE_ENABLED) {
|
||||||
|
Log.d("TetheringSettings",
|
||||||
|
"Wifi AP config changed while enabled, stop and restart");
|
||||||
|
mRestartWifiApAfterConfigChange = true;
|
||||||
|
mSwitchBarController.stopTether();
|
||||||
|
}
|
||||||
|
mWifiManager.setWifiApConfiguration(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private WifiConfiguration buildNewConfig() {
|
||||||
|
final WifiConfiguration config = new WifiConfiguration();
|
||||||
|
|
||||||
|
config.SSID = mSSIDPreferenceController.getSSID();
|
||||||
|
config.preSharedKey = mPasswordPreferenceController.getPassword();
|
||||||
|
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA2_PSK);
|
||||||
|
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
|
||||||
|
config.apBand = mApBandPreferenceController.getBandIndex();
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
class TetherChangeReceiver extends BroadcastReceiver {
|
||||||
|
private static final String TAG = "TetherChangeReceiver";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context content, Intent intent) {
|
||||||
|
String action = intent.getAction();
|
||||||
|
if (action.equals(ACTION_TETHER_STATE_CHANGED)) {
|
||||||
|
if (mWifiManager.getWifiApState() == WifiManager.WIFI_AP_STATE_DISABLED
|
||||||
|
&& mRestartWifiApAfterConfigChange) {
|
||||||
|
mRestartWifiApAfterConfigChange = false;
|
||||||
|
Log.d(TAG, "Restarting WifiAp due to prior config change.");
|
||||||
|
mSwitchBarController.startTether();
|
||||||
|
}
|
||||||
|
} else if (action.equals(WIFI_AP_STATE_CHANGED_ACTION)) {
|
||||||
|
int state = intent.getIntExtra(WifiManager.EXTRA_WIFI_AP_STATE, 0);
|
||||||
|
if (state == WifiManager.WIFI_AP_STATE_DISABLED
|
||||||
|
&& mRestartWifiApAfterConfigChange) {
|
||||||
|
mRestartWifiApAfterConfigChange = false;
|
||||||
|
Log.d(TAG, "Restarting WifiAp due to prior config change.");
|
||||||
|
mSwitchBarController.startTether();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,138 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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.tether;
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.wifi.WifiManager;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.provider.Settings;
|
||||||
|
import android.widget.Switch;
|
||||||
|
|
||||||
|
import com.android.settings.datausage.DataSaverBackend;
|
||||||
|
import com.android.settings.widget.SwitchBar;
|
||||||
|
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||||
|
import com.android.settingslib.core.lifecycle.events.OnStart;
|
||||||
|
import com.android.settingslib.core.lifecycle.events.OnStop;
|
||||||
|
|
||||||
|
import static android.net.ConnectivityManager.TETHERING_WIFI;
|
||||||
|
|
||||||
|
public class WifiTetherSwitchBarController implements SwitchBar.OnSwitchChangeListener,
|
||||||
|
LifecycleObserver, OnStart, OnStop {
|
||||||
|
|
||||||
|
private final Context mContext;
|
||||||
|
private final SwitchBar mSwitchBar;
|
||||||
|
private final ConnectivityManager mConnectivityManager;
|
||||||
|
private final DataSaverBackend mDataSaverBackend;
|
||||||
|
private final NoOpOnStartTetheringCallback mOnStartTetheringCallback;
|
||||||
|
|
||||||
|
WifiTetherSwitchBarController(Context context, SwitchBar switchBar) {
|
||||||
|
mContext = context;
|
||||||
|
mSwitchBar = switchBar;
|
||||||
|
mDataSaverBackend = new DataSaverBackend(context);
|
||||||
|
mOnStartTetheringCallback = new NoOpOnStartTetheringCallback();
|
||||||
|
mConnectivityManager =
|
||||||
|
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
|
mSwitchBar.addOnSwitchChangeListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
mContext.registerReceiver(mReceiver,
|
||||||
|
WifiTetherPreferenceController.WIFI_TETHER_INTENT_FILTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStop() {
|
||||||
|
mContext.unregisterReceiver(mReceiver);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSwitchChanged(Switch switchView, boolean isChecked) {
|
||||||
|
if (isChecked) {
|
||||||
|
startTether();
|
||||||
|
} else {
|
||||||
|
stopTether();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void stopTether() {
|
||||||
|
mSwitchBar.setEnabled(false);
|
||||||
|
mConnectivityManager.stopTethering(TETHERING_WIFI);
|
||||||
|
}
|
||||||
|
|
||||||
|
void startTether() {
|
||||||
|
mSwitchBar.setEnabled(false);
|
||||||
|
mConnectivityManager.startTethering(TETHERING_WIFI, true /* showProvisioningUi */,
|
||||||
|
mOnStartTetheringCallback, new Handler(Looper.getMainLooper()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
String action = intent.getAction();
|
||||||
|
if (WifiManager.WIFI_AP_STATE_CHANGED_ACTION.equals(action)) {
|
||||||
|
final int state = intent.getIntExtra(
|
||||||
|
WifiManager.EXTRA_WIFI_AP_STATE, WifiManager.WIFI_AP_STATE_FAILED);
|
||||||
|
handleWifiApStateChanged(state);
|
||||||
|
} else if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)) {
|
||||||
|
enableWifiSwitch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private void handleWifiApStateChanged(int state) {
|
||||||
|
switch (state) {
|
||||||
|
case WifiManager.WIFI_AP_STATE_ENABLING:
|
||||||
|
mSwitchBar.setEnabled(false);
|
||||||
|
break;
|
||||||
|
case WifiManager.WIFI_AP_STATE_ENABLED:
|
||||||
|
if (!mSwitchBar.isChecked()) {
|
||||||
|
mSwitchBar.setChecked(true);
|
||||||
|
}
|
||||||
|
enableWifiSwitch();
|
||||||
|
break;
|
||||||
|
case WifiManager.WIFI_AP_STATE_DISABLING:
|
||||||
|
if (mSwitchBar.isChecked()) {
|
||||||
|
mSwitchBar.setChecked(false);
|
||||||
|
}
|
||||||
|
mSwitchBar.setEnabled(false);
|
||||||
|
break;
|
||||||
|
case WifiManager.WIFI_AP_STATE_DISABLED:
|
||||||
|
mSwitchBar.setChecked(false);
|
||||||
|
enableWifiSwitch();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mSwitchBar.setChecked(false);
|
||||||
|
enableWifiSwitch();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void enableWifiSwitch() {
|
||||||
|
boolean isAirplaneMode = Settings.Global.getInt(mContext.getContentResolver(),
|
||||||
|
Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
|
||||||
|
if (!isAirplaneMode) {
|
||||||
|
mSwitchBar.setEnabled(!mDataSaverBackend.isDataSaverEnabled());
|
||||||
|
} else {
|
||||||
|
mSwitchBar.setEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -13,3 +13,4 @@ com.android.settings.enterprise.ApplicationListFragment$AdminGrantedPermissionLo
|
|||||||
com.android.settings.enterprise.ApplicationListFragment$AdminGrantedPermissionMicrophone
|
com.android.settings.enterprise.ApplicationListFragment$AdminGrantedPermissionMicrophone
|
||||||
com.android.settings.enterprise.ApplicationListFragment$EnterpriseInstalledPackages
|
com.android.settings.enterprise.ApplicationListFragment$EnterpriseInstalledPackages
|
||||||
com.android.settings.enterprise.EnterpriseSetDefaultAppsListFragment
|
com.android.settings.enterprise.EnterpriseSetDefaultAppsListFragment
|
||||||
|
com.android.settings.wifi.tether.WifiTetherSettings
|
||||||
|
@@ -16,10 +16,10 @@
|
|||||||
|
|
||||||
package com.android.settings.core.codeinspection;
|
package com.android.settings.core.codeinspection;
|
||||||
|
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
|
||||||
import com.android.settings.TestConfig;
|
import com.android.settings.TestConfig;
|
||||||
import com.android.settings.core.instrumentation.InstrumentableFragmentCodeInspector;
|
import com.android.settings.core.instrumentation.InstrumentableFragmentCodeInspector;
|
||||||
import com.android.settings.search.SearchIndexProviderCodeInspector;
|
import com.android.settings.search.SearchIndexProviderCodeInspector;
|
||||||
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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.widget;
|
||||||
|
|
||||||
|
|
||||||
|
import android.text.InputType;
|
||||||
|
import android.text.TextWatcher;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.EditText;
|
||||||
|
|
||||||
|
import com.android.settings.TestConfig;
|
||||||
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
import org.robolectric.annotation.Config;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
import static org.mockito.Matchers.any;
|
||||||
|
import static org.mockito.Mockito.spy;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
|
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||||
|
public class ValidatedEditTextPreferenceTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private View mView;
|
||||||
|
@Mock
|
||||||
|
private ValidatedEditTextPreference.Validator mValidator;
|
||||||
|
|
||||||
|
private ValidatedEditTextPreference mPreference;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
mPreference = new ValidatedEditTextPreference(RuntimeEnvironment.application);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bindDialogView_noTextWatcher_shouldDoNothing() {
|
||||||
|
mPreference.onBindDialogView(mView);
|
||||||
|
|
||||||
|
verifyZeroInteractions(mView);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bindDialogView_hasValidator_shouldBindToEditText() {
|
||||||
|
final EditText editText = spy(new EditText(RuntimeEnvironment.application));
|
||||||
|
when(mView.findViewById(android.R.id.edit)).thenReturn(editText);
|
||||||
|
|
||||||
|
mPreference.setValidator(mValidator);
|
||||||
|
mPreference.onBindDialogView(mView);
|
||||||
|
|
||||||
|
verify(editText).addTextChangedListener(any(TextWatcher.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bindDialogView_isPassword_shouldSetInputType() {
|
||||||
|
final EditText editText = spy(new EditText(RuntimeEnvironment.application));
|
||||||
|
when(mView.findViewById(android.R.id.edit)).thenReturn(editText);
|
||||||
|
|
||||||
|
mPreference.setValidator(mValidator);
|
||||||
|
mPreference.setIsPassword(true);
|
||||||
|
mPreference.onBindDialogView(mView);
|
||||||
|
|
||||||
|
assertThat(editText.getInputType()
|
||||||
|
& (InputType.TYPE_TEXT_VARIATION_PASSWORD | InputType.TYPE_CLASS_TEXT))
|
||||||
|
.isNotEqualTo(0);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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;
|
||||||
|
|
||||||
|
|
||||||
|
import com.android.settings.TestConfig;
|
||||||
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.robolectric.annotation.Config;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
|
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||||
|
public class WifiUtilsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSSID() {
|
||||||
|
assertThat(WifiUtils.isSSIDTooLong("123")).isFalse();
|
||||||
|
assertThat(WifiUtils.isSSIDTooLong("☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎☎")).isTrue();
|
||||||
|
|
||||||
|
assertThat(WifiUtils.isSSIDTooShort("123")).isFalse();
|
||||||
|
assertThat(WifiUtils.isSSIDTooShort("")).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPassword() {
|
||||||
|
final String longPassword = "123456789012345678901234567890"
|
||||||
|
+ "1234567890123456789012345678901234567890";
|
||||||
|
assertThat(WifiUtils.isPasswordValid("123")).isFalse();
|
||||||
|
assertThat(WifiUtils.isPasswordValid("12345678")).isTrue();
|
||||||
|
assertThat(WifiUtils.isPasswordValid("1234567890")).isTrue();
|
||||||
|
assertThat(WifiUtils.isPasswordValid(longPassword)).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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.tether;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.wifi.WifiManager;
|
||||||
|
import android.support.v7.preference.ListPreference;
|
||||||
|
import android.support.v7.preference.PreferenceScreen;
|
||||||
|
|
||||||
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.TestConfig;
|
||||||
|
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;
|
||||||
|
import org.robolectric.annotation.Config;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
import static org.mockito.Matchers.anyString;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
|
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||||
|
public class WifiTetherApBandPreferenceControllerTest {
|
||||||
|
|
||||||
|
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||||
|
private Context mContext;
|
||||||
|
@Mock
|
||||||
|
private ConnectivityManager mConnectivityManager;
|
||||||
|
@Mock
|
||||||
|
private WifiManager mWifiManager;
|
||||||
|
@Mock
|
||||||
|
private WifiTetherBasePreferenceController.OnTetherConfigUpdateListener mListener;
|
||||||
|
@Mock
|
||||||
|
private PreferenceScreen mScreen;
|
||||||
|
|
||||||
|
private WifiTetherApBandPreferenceController mController;
|
||||||
|
private ListPreference mListPreference;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
mListPreference = new ListPreference(RuntimeEnvironment.application);
|
||||||
|
when(mContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifiManager);
|
||||||
|
when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE))
|
||||||
|
.thenReturn(mConnectivityManager);
|
||||||
|
when(mConnectivityManager.getTetherableWifiRegexs()).thenReturn(new String[]{"1", "2"});
|
||||||
|
when(mContext.getResources()).thenReturn(RuntimeEnvironment.application.getResources());
|
||||||
|
when(mScreen.findPreference(anyString())).thenReturn(mListPreference);
|
||||||
|
|
||||||
|
mController = new WifiTetherApBandPreferenceController(mContext, mListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void display_5GhzSupported_shouldDisplayFullList() {
|
||||||
|
when(mWifiManager.is5GHzBandSupported()).thenReturn(true);
|
||||||
|
|
||||||
|
mController.displayPreference(mScreen);
|
||||||
|
|
||||||
|
assertThat(mListPreference.getEntries().length).isEqualTo(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void display_5GhzNotSupported_shouldDisable() {
|
||||||
|
when(mWifiManager.is5GHzBandSupported()).thenReturn(false);
|
||||||
|
|
||||||
|
mController.displayPreference(mScreen);
|
||||||
|
|
||||||
|
assertThat(mListPreference.getEntries()).isNull();
|
||||||
|
assertThat(mListPreference.isEnabled()).isFalse();
|
||||||
|
assertThat(mListPreference.getSummary())
|
||||||
|
.isEqualTo(RuntimeEnvironment.application.getString(R.string.wifi_ap_choose_2G));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void changePreference_shouldUpdateValue() {
|
||||||
|
when(mWifiManager.is5GHzBandSupported()).thenReturn(true);
|
||||||
|
|
||||||
|
mController.displayPreference(mScreen);
|
||||||
|
mController.onPreferenceChange(mListPreference, "1");
|
||||||
|
assertThat(mController.getBandIndex()).isEqualTo(1);
|
||||||
|
|
||||||
|
mController.onPreferenceChange(mListPreference, "0");
|
||||||
|
assertThat(mController.getBandIndex()).isEqualTo(0);
|
||||||
|
|
||||||
|
verify(mListener, times(2)).onTetherConfigUpdated();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,102 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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.tether;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.wifi.WifiConfiguration;
|
||||||
|
import android.net.wifi.WifiManager;
|
||||||
|
import android.support.v7.preference.PreferenceScreen;
|
||||||
|
|
||||||
|
import com.android.settings.TestConfig;
|
||||||
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
import com.android.settings.widget.ValidatedEditTextPreference;
|
||||||
|
|
||||||
|
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;
|
||||||
|
import org.robolectric.annotation.Config;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
import static org.mockito.Matchers.anyString;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
|
||||||
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
|
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||||
|
public class WifiTetherPasswordPreferenceControllerTest {
|
||||||
|
|
||||||
|
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||||
|
private Context mContext;
|
||||||
|
@Mock
|
||||||
|
private ConnectivityManager mConnectivityManager;
|
||||||
|
@Mock
|
||||||
|
private WifiManager mWifiManager;
|
||||||
|
@Mock
|
||||||
|
private WifiTetherBasePreferenceController.OnTetherConfigUpdateListener mListener;
|
||||||
|
@Mock
|
||||||
|
private PreferenceScreen mScreen;
|
||||||
|
|
||||||
|
private WifiTetherPasswordPreferenceController mController;
|
||||||
|
private ValidatedEditTextPreference mPreference;
|
||||||
|
private WifiConfiguration mConfig;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
mPreference = new ValidatedEditTextPreference(RuntimeEnvironment.application);
|
||||||
|
mConfig = new WifiConfiguration();
|
||||||
|
mConfig.SSID = "test_1234";
|
||||||
|
mConfig.preSharedKey = "test_password";
|
||||||
|
|
||||||
|
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(mContext.getResources()).thenReturn(RuntimeEnvironment.application.getResources());
|
||||||
|
when(mScreen.findPreference(anyString())).thenReturn(mPreference);
|
||||||
|
|
||||||
|
mController = new WifiTetherPasswordPreferenceController(mContext, mListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void displayPreference_shouldStylePreference() {
|
||||||
|
mController.displayPreference(mScreen);
|
||||||
|
|
||||||
|
assertThat(mPreference.getText()).isEqualTo(mConfig.preSharedKey);
|
||||||
|
assertThat(mPreference.isPassword()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void changePreference_shouldUpdateValue() {
|
||||||
|
mController.displayPreference(mScreen);
|
||||||
|
mController.onPreferenceChange(mPreference, "1");
|
||||||
|
assertThat(mController.getPassword()).isEqualTo("1");
|
||||||
|
|
||||||
|
mController.onPreferenceChange(mPreference, "0");
|
||||||
|
assertThat(mController.getPassword()).isEqualTo("0");
|
||||||
|
|
||||||
|
verify(mListener, times(2)).onTetherConfigUpdated();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,186 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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.tether;
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.ContentResolver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.wifi.WifiConfiguration;
|
||||||
|
import android.net.wifi.WifiManager;
|
||||||
|
import android.provider.Settings;
|
||||||
|
import android.support.v7.preference.Preference;
|
||||||
|
import android.support.v7.preference.PreferenceScreen;
|
||||||
|
|
||||||
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.TestConfig;
|
||||||
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
import org.robolectric.annotation.Config;
|
||||||
|
import org.robolectric.annotation.Implementation;
|
||||||
|
import org.robolectric.annotation.Implements;
|
||||||
|
import org.robolectric.shadows.ShadowSettings;
|
||||||
|
import org.robolectric.util.ReflectionHelpers;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
import static org.mockito.Matchers.any;
|
||||||
|
import static org.mockito.Matchers.anyString;
|
||||||
|
import static org.mockito.Matchers.eq;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
|
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
|
||||||
|
shadows = {
|
||||||
|
WifiTetherPreferenceControllerTest.ShadowWifiTetherSettings.class
|
||||||
|
})
|
||||||
|
public class WifiTetherPreferenceControllerTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private Context mContext;
|
||||||
|
@Mock
|
||||||
|
private ConnectivityManager mConnectivityManager;
|
||||||
|
@Mock
|
||||||
|
private WifiManager mWifiManager;
|
||||||
|
@Mock
|
||||||
|
private PreferenceScreen mScreen;
|
||||||
|
|
||||||
|
private WifiTetherPreferenceController mController;
|
||||||
|
private Lifecycle mLifecycle;
|
||||||
|
private Preference mPreference;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
mLifecycle = new Lifecycle();
|
||||||
|
mPreference = new Preference(RuntimeEnvironment.application);
|
||||||
|
when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE))
|
||||||
|
.thenReturn(mConnectivityManager);
|
||||||
|
when(mContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifiManager);
|
||||||
|
when(mScreen.findPreference(anyString())).thenReturn(mPreference);
|
||||||
|
|
||||||
|
when(mConnectivityManager.getTetherableWifiRegexs()).thenReturn(new String[]{"1", "2"});
|
||||||
|
mController = new WifiTetherPreferenceController(mContext, mLifecycle);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isAvailable_noTetherRegex_shouldReturnFalse() {
|
||||||
|
when(mConnectivityManager.getTetherableWifiRegexs()).thenReturn(new String[]{});
|
||||||
|
mController = new WifiTetherPreferenceController(mContext, mLifecycle);
|
||||||
|
|
||||||
|
assertThat(mController.isAvailable()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isAvailable_hasTetherRegex_shouldReturnTrue() {
|
||||||
|
assertThat(mController.isAvailable()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void resumeAndPause_shouldRegisterUnregisterReceiver() {
|
||||||
|
final BroadcastReceiver receiver = ReflectionHelpers.getField(mController, "mReceiver");
|
||||||
|
|
||||||
|
mController.displayPreference(mScreen);
|
||||||
|
mLifecycle.onResume();
|
||||||
|
mLifecycle.onPause();
|
||||||
|
|
||||||
|
verify(mContext).registerReceiver(eq(receiver), any(IntentFilter.class));
|
||||||
|
verify(mContext).unregisterReceiver(receiver);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReceiver_apStateChangedToDisabled_shouldUpdatePreferenceSummary() {
|
||||||
|
mController.displayPreference(mScreen);
|
||||||
|
final BroadcastReceiver receiver = ReflectionHelpers.getField(mController, "mReceiver");
|
||||||
|
final Intent broadcast = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
|
||||||
|
broadcast.putExtra(WifiManager.EXTRA_WIFI_AP_STATE, WifiManager.WIFI_AP_STATE_DISABLED);
|
||||||
|
|
||||||
|
receiver.onReceive(RuntimeEnvironment.application, broadcast);
|
||||||
|
|
||||||
|
assertThat(mPreference.getSummary().toString()).isEqualTo(
|
||||||
|
RuntimeEnvironment.application.getString(R.string.wifi_hotspot_off_subtext));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReceiver_apStateChangedToDisabling_shouldUpdatePreferenceSummary() {
|
||||||
|
mController.displayPreference(mScreen);
|
||||||
|
final BroadcastReceiver receiver = ReflectionHelpers.getField(mController, "mReceiver");
|
||||||
|
final Intent broadcast = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
|
||||||
|
broadcast.putExtra(WifiManager.EXTRA_WIFI_AP_STATE, WifiManager.WIFI_AP_STATE_DISABLING);
|
||||||
|
|
||||||
|
receiver.onReceive(RuntimeEnvironment.application, broadcast);
|
||||||
|
|
||||||
|
assertThat(mPreference.getSummary().toString()).isEqualTo(
|
||||||
|
RuntimeEnvironment.application.getString(R.string.wifi_tether_stopping));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReceiver_goingToAirplaneMode_shouldClearPreferenceSummary() {
|
||||||
|
final ContentResolver cr = mock(ContentResolver.class);
|
||||||
|
when(mContext.getContentResolver()).thenReturn(cr);
|
||||||
|
ShadowSettings.ShadowGlobal.putInt(cr, Settings.Global.AIRPLANE_MODE_ON, 1);
|
||||||
|
mController.displayPreference(mScreen);
|
||||||
|
final BroadcastReceiver receiver = ReflectionHelpers.getField(mController, "mReceiver");
|
||||||
|
final Intent broadcast = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
|
||||||
|
|
||||||
|
receiver.onReceive(RuntimeEnvironment.application, broadcast);
|
||||||
|
|
||||||
|
assertThat(mPreference.getSummary().toString()).isEqualTo(
|
||||||
|
RuntimeEnvironment.application.getString(R.string.summary_placeholder));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReceiver_tetherEnabled_shouldUpdatePreferenceSummary() {
|
||||||
|
mController.displayPreference(mScreen);
|
||||||
|
final BroadcastReceiver receiver = ReflectionHelpers.getField(mController, "mReceiver");
|
||||||
|
final Intent broadcast = new Intent(ConnectivityManager.ACTION_TETHER_STATE_CHANGED);
|
||||||
|
final ArrayList<String> activeTethers = new ArrayList<>();
|
||||||
|
activeTethers.add("1");
|
||||||
|
broadcast.putStringArrayListExtra(ConnectivityManager.EXTRA_ACTIVE_TETHER, activeTethers);
|
||||||
|
broadcast.putStringArrayListExtra(ConnectivityManager.EXTRA_ERRORED_TETHER,
|
||||||
|
new ArrayList<>());
|
||||||
|
final WifiConfiguration configuration = new WifiConfiguration();
|
||||||
|
configuration.SSID = "test-ap";
|
||||||
|
when(mWifiManager.getWifiApConfiguration()).thenReturn(configuration);
|
||||||
|
|
||||||
|
receiver.onReceive(RuntimeEnvironment.application, broadcast);
|
||||||
|
|
||||||
|
verify(mContext).getString(eq(R.string.wifi_tether_enabled_subtext), any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Implements(WifiTetherSettings.class)
|
||||||
|
public static final class ShadowWifiTetherSettings {
|
||||||
|
|
||||||
|
@Implementation
|
||||||
|
public static boolean isTetherSettingPageEnabled() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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.tether;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.wifi.WifiConfiguration;
|
||||||
|
import android.net.wifi.WifiManager;
|
||||||
|
import android.support.v7.preference.PreferenceScreen;
|
||||||
|
|
||||||
|
import com.android.settings.TestConfig;
|
||||||
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
import com.android.settings.widget.ValidatedEditTextPreference;
|
||||||
|
|
||||||
|
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;
|
||||||
|
import org.robolectric.annotation.Config;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
import static org.mockito.Matchers.anyString;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
|
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||||
|
public class WifiTetherSSIDPreferenceControllerTest {
|
||||||
|
|
||||||
|
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||||
|
private Context mContext;
|
||||||
|
@Mock
|
||||||
|
private ConnectivityManager mConnectivityManager;
|
||||||
|
@Mock
|
||||||
|
private WifiManager mWifiManager;
|
||||||
|
@Mock
|
||||||
|
private WifiTetherBasePreferenceController.OnTetherConfigUpdateListener mListener;
|
||||||
|
@Mock
|
||||||
|
private PreferenceScreen mScreen;
|
||||||
|
|
||||||
|
private WifiTetherSSIDPreferenceController mController;
|
||||||
|
private ValidatedEditTextPreference mPreference;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
mPreference = new ValidatedEditTextPreference(RuntimeEnvironment.application);
|
||||||
|
|
||||||
|
when(mContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifiManager);
|
||||||
|
when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE))
|
||||||
|
.thenReturn(mConnectivityManager);
|
||||||
|
when(mConnectivityManager.getTetherableWifiRegexs()).thenReturn(new String[]{"1", "2"});
|
||||||
|
when(mContext.getResources()).thenReturn(RuntimeEnvironment.application.getResources());
|
||||||
|
when(mScreen.findPreference(anyString())).thenReturn(mPreference);
|
||||||
|
|
||||||
|
mController = new WifiTetherSSIDPreferenceController(mContext, mListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void displayPreference_noWifiConfig_shouldDisplayDefaultSSID() {
|
||||||
|
when(mWifiManager.getWifiApConfiguration()).thenReturn(null);
|
||||||
|
|
||||||
|
mController.displayPreference(mScreen);
|
||||||
|
assertThat(mController.getSSID())
|
||||||
|
.isEqualTo(WifiTetherSSIDPreferenceController.DEFAULT_SSID);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void displayPreference_hasCustomWifiConfig_shouldDisplayCustomSSID() {
|
||||||
|
final WifiConfiguration config = new WifiConfiguration();
|
||||||
|
config.SSID = "test_1234";
|
||||||
|
when(mWifiManager.getWifiApConfiguration()).thenReturn(config);
|
||||||
|
|
||||||
|
mController.displayPreference(mScreen);
|
||||||
|
assertThat(mController.getSSID()).isEqualTo(config.SSID);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void changePreference_shouldUpdateValue() {
|
||||||
|
mController.displayPreference(mScreen);
|
||||||
|
mController.onPreferenceChange(mPreference, "1");
|
||||||
|
assertThat(mController.getSSID()).isEqualTo("1");
|
||||||
|
|
||||||
|
mController.onPreferenceChange(mPreference, "0");
|
||||||
|
assertThat(mController.getSSID()).isEqualTo("0");
|
||||||
|
|
||||||
|
verify(mListener, times(2)).onTetherConfigUpdated();
|
||||||
|
}
|
||||||
|
}
|
@@ -9,10 +9,12 @@ LOCAL_JAVA_LIBRARIES := android.test.runner
|
|||||||
|
|
||||||
LOCAL_STATIC_JAVA_LIBRARIES := \
|
LOCAL_STATIC_JAVA_LIBRARIES := \
|
||||||
android-support-test \
|
android-support-test \
|
||||||
mockito-target-minus-junit4 \
|
|
||||||
espresso-core \
|
espresso-core \
|
||||||
|
legacy-android-test \
|
||||||
|
mockito-target-minus-junit4 \
|
||||||
truth-prebuilt \
|
truth-prebuilt \
|
||||||
legacy-android-test
|
ub-uiautomator \
|
||||||
|
|
||||||
|
|
||||||
# Include all test java files.
|
# Include all test java files.
|
||||||
LOCAL_SRC_FILES := $(call all-java-files-under, src)
|
LOCAL_SRC_FILES := $(call all-java-files-under, src)
|
||||||
|
@@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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.tether;
|
||||||
|
|
||||||
|
import android.app.Instrumentation;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.support.test.InstrumentationRegistry;
|
||||||
|
import android.support.test.filters.SmallTest;
|
||||||
|
import android.support.test.runner.AndroidJUnit4;
|
||||||
|
import android.support.test.uiautomator.By;
|
||||||
|
import android.support.test.uiautomator.UiDevice;
|
||||||
|
import android.support.test.uiautomator.UiObject2;
|
||||||
|
import android.support.test.uiautomator.Until;
|
||||||
|
|
||||||
|
import com.android.settings.Settings;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import static android.support.test.espresso.Espresso.onView;
|
||||||
|
import static android.support.test.espresso.assertion.ViewAssertions.matches;
|
||||||
|
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
|
||||||
|
import static android.support.test.espresso.matcher.ViewMatchers.withText;
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
@SmallTest
|
||||||
|
public class WifiTetherSettingsTest {
|
||||||
|
|
||||||
|
private static final long TIMEOUT = 2000L;
|
||||||
|
|
||||||
|
private Instrumentation mInstrumentation;
|
||||||
|
private Intent mTetherActivityIntent;
|
||||||
|
private UiDevice mDevice;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
mInstrumentation = InstrumentationRegistry.getInstrumentation();
|
||||||
|
mDevice = UiDevice.getInstance(mInstrumentation);
|
||||||
|
mTetherActivityIntent = new Intent()
|
||||||
|
.setClassName(mInstrumentation.getTargetContext().getPackageName(),
|
||||||
|
Settings.TetherSettingsActivity.class.getName())
|
||||||
|
.setPackage(mInstrumentation.getTargetContext().getPackageName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
mDevice.pressHome();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void launchTetherSettings_shouldHaveAllFields() {
|
||||||
|
launchWifiTetherActivity();
|
||||||
|
onView(withText("Network name")).check(matches(isDisplayed()));
|
||||||
|
onView(withText("Password")).check(matches(isDisplayed()));
|
||||||
|
onView(withText("Select AP Band")).check(matches(isDisplayed()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void launchWifiTetherActivity() {
|
||||||
|
mInstrumentation.startActivitySync(mTetherActivityIntent);
|
||||||
|
onView(withText("Portable Wi‑Fi hotspot")).perform();
|
||||||
|
UiObject2 item = mDevice.wait(Until.findObject(By.text("Portable Wi‑Fi hotspot")), TIMEOUT);
|
||||||
|
item.click();
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user