Settings: revise WifiEnabler and BluetoothEnabler.
This mainly changes the way both enablers react to the airplane mode. Now
enablers show a toast message instead of disabling the check box directly. This
avoids the inconsistent state introduced by WirelessSettings which controls the
check box using layout dependency.
Related bug: 2053751
diff --git a/res/values/strings.xml b/res/values/strings.xml
index c289038..b86950b 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -707,12 +707,14 @@
<string name="ip_address">IP address</string>
<!-- Label for the signal strength -->
<string name="signal">Signal strength</string>
- <!--Wireless controls setting screen, Wi-Fi check box summary text when turning Wi-Fi on -->
+ <!-- Summary text when turning Wi-Fi or bluetooth on -->
<string name="wifi_starting">Turning on\u2026</string>
- <!--Wireless controls setting screen, Wi-Fi check box summary text when turning Wi-Fi off -->
+ <!-- Summary text when turning Wi-Fi or bluetooth off -->
<string name="wifi_stopping">Turning off\u2026</string>
- <!-- Generic error message , probably not used-->
+ <!-- Summary text when Wi-Fi or bluetooth has error -->
<string name="wifi_error">Error</string>
+ <!-- Toast message when Wi-Fi or bluetooth is disallowed in airplane mode -->
+ <string name="wifi_in_airplane_mode">In airplane mode</string>
<!-- Error message when Wi-Fi can't start -->
<string name="error_starting">Unable to start Wi-Fi</string>
<!-- Error message when Wi-Fi can't stop -->
diff --git a/src/com/android/settings/WirelessSettings.java b/src/com/android/settings/WirelessSettings.java
index 1d0b2d8..bf75e27 100644
--- a/src/com/android/settings/WirelessSettings.java
+++ b/src/com/android/settings/WirelessSettings.java
@@ -17,6 +17,7 @@
package com.android.settings;
import android.bluetooth.BluetoothAdapter;
+import android.content.Context;
import android.content.Intent;
import android.net.wifi.WifiManager;
import android.os.Bundle;
@@ -67,7 +68,17 @@
// Let the intents be launched by the Preference manager
return false;
}
-
+
+ public static boolean isRadioAllowed(Context context, String type) {
+ if (!AirplaneModeEnabler.isAirplaneModeOn(context)) {
+ return true;
+ }
+ // Here we use the same logic in onCreate().
+ String toggleable = Settings.System.getString(context.getContentResolver(),
+ Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS);
+ return toggleable != null && toggleable.contains(type);
+ }
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -86,7 +97,7 @@
String toggleable = Settings.System.getString(getContentResolver(),
Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS);
- // Manually set up dependencies for Wifi when not toggleable.
+ // Manually set dependencies for Wifi when not toggleable.
if (toggleable == null || !toggleable.contains(Settings.System.RADIO_WIFI)) {
wifi.setDependency(KEY_TOGGLE_AIRPLANE);
findPreference(KEY_WIFI_SETTINGS).setDependency(KEY_TOGGLE_AIRPLANE);
@@ -99,7 +110,7 @@
findPreference(KEY_BT_SETTINGS).setDependency(KEY_TOGGLE_AIRPLANE);
}
- // Disable BT Settings if BT service is not available.
+ // Disable Bluetooth Settings if Bluetooth service is not available.
if (ServiceManager.getService(BluetoothAdapter.BLUETOOTH_SERVICE) == null) {
findPreference(KEY_BT_SETTINGS).setEnabled(false);
}
diff --git a/src/com/android/settings/bluetooth/BluetoothEnabler.java b/src/com/android/settings/bluetooth/BluetoothEnabler.java
index 46793ce..426a4d3 100644
--- a/src/com/android/settings/bluetooth/BluetoothEnabler.java
+++ b/src/com/android/settings/bluetooth/BluetoothEnabler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2010 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.
@@ -16,8 +16,8 @@
package com.android.settings.bluetooth;
-import com.android.settings.AirplaneModeEnabler;
import com.android.settings.R;
+import com.android.settings.WirelessSettings;
import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
@@ -28,7 +28,7 @@
import android.preference.CheckBoxPreference;
import android.provider.Settings;
import android.text.TextUtils;
-import android.util.Config;
+import android.widget.Toast;
/**
* BluetoothEnabler is a helper to manage the Bluetooth on/off checkbox
@@ -36,16 +36,12 @@
* preference reflects the current state.
*/
public class BluetoothEnabler implements Preference.OnPreferenceChangeListener {
-
- private static final boolean LOCAL_LOGD = Config.LOGD || false;
- private static final String TAG = "BluetoothEnabler";
-
private final Context mContext;
- private final CheckBoxPreference mCheckBoxPreference;
+ private final CheckBoxPreference mCheckBox;
private final CharSequence mOriginalSummary;
private final LocalBluetoothManager mLocalManager;
-
+ private final IntentFilter mIntentFilter;
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -54,18 +50,18 @@
}
};
- public BluetoothEnabler(Context context, CheckBoxPreference checkBoxPreference) {
+ public BluetoothEnabler(Context context, CheckBoxPreference checkBox) {
mContext = context;
- mCheckBoxPreference = checkBoxPreference;
-
- mOriginalSummary = checkBoxPreference.getSummary();
- checkBoxPreference.setPersistent(false);
+ mCheckBox = checkBox;
+ mOriginalSummary = checkBox.getSummary();
+ checkBox.setPersistent(false);
mLocalManager = LocalBluetoothManager.getInstance(context);
if (mLocalManager == null) {
- // Bluetooth not supported
- checkBoxPreference.setEnabled(false);
+ // Bluetooth is not supported
+ checkBox.setEnabled(false);
}
+ mIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
}
public void resume() {
@@ -73,16 +69,11 @@
return;
}
- int state = mLocalManager.getBluetoothState();
- // This is the widget enabled state, not the preference toggled state
- mCheckBoxPreference.setEnabled(state == BluetoothAdapter.STATE_ON ||
- state == BluetoothAdapter.STATE_OFF);
- // BT state is not a sticky broadcast, so set it manually
- handleStateChanged(state);
+ // Bluetooth state is not sticky, so set it manually
+ handleStateChanged(mLocalManager.getBluetoothState());
- mContext.registerReceiver(mReceiver,
- new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
- mCheckBoxPreference.setOnPreferenceChangeListener(this);
+ mContext.registerReceiver(mReceiver, mIntentFilter);
+ mCheckBox.setOnPreferenceChangeListener(this);
}
public void pause() {
@@ -91,72 +82,51 @@
}
mContext.unregisterReceiver(mReceiver);
- mCheckBoxPreference.setOnPreferenceChangeListener(null);
+ mCheckBox.setOnPreferenceChangeListener(null);
}
public boolean onPreferenceChange(Preference preference, Object value) {
- // Turn on/off BT
- setEnabled((Boolean) value);
+ boolean enable = (Boolean) value;
+
+ // Show toast message if Bluetooth is not allowed in airplane mode
+ if (enable && !WirelessSettings
+ .isRadioAllowed(mContext, Settings.System.RADIO_BLUETOOTH)) {
+ Toast.makeText(mContext, R.string.wifi_in_airplane_mode,
+ Toast.LENGTH_SHORT).show();
+ return false;
+ }
+
+ mLocalManager.setBluetoothEnabled(enable);
+ mCheckBox.setEnabled(false);
// Don't update UI to opposite state until we're sure
return false;
}
- private void setEnabled(final boolean enable) {
- // Disable preference
- mCheckBoxPreference.setEnabled(false);
-
- mLocalManager.setBluetoothEnabled(enable);
- }
-
private void handleStateChanged(int state) {
-
- if (state == BluetoothAdapter.STATE_OFF ||
- state == BluetoothAdapter.STATE_ON) {
- mCheckBoxPreference.setChecked(state == BluetoothAdapter.STATE_ON);
- mCheckBoxPreference.setSummary(state == BluetoothAdapter.STATE_OFF ?
- mOriginalSummary :
- null);
-
- final boolean hasDependency = !TextUtils.isEmpty(mCheckBoxPreference.getDependency());
- final boolean bluetoothAllowed = isBluetoothAllowed(mContext);
-
- // Avoid disabling when dependencies have been manually set,
- // workaround for framework bug http://b/2053751
- if (bluetoothAllowed) {
- mCheckBoxPreference.setEnabled(true);
- } else if (!hasDependency) {
- mCheckBoxPreference.setEnabled(false);
- }
-
- } else if (state == BluetoothAdapter.STATE_TURNING_ON ||
- state == BluetoothAdapter.STATE_TURNING_OFF) {
- mCheckBoxPreference.setSummary(state == BluetoothAdapter.STATE_TURNING_ON
- ? R.string.wifi_starting
- : R.string.wifi_stopping);
-
- } else {
- mCheckBoxPreference.setChecked(false);
- mCheckBoxPreference.setSummary(R.string.wifi_error);
- mCheckBoxPreference.setEnabled(true);
+ switch (state) {
+ case BluetoothAdapter.STATE_TURNING_ON:
+ mCheckBox.setSummary(R.string.wifi_starting);
+ mCheckBox.setEnabled(false);
+ break;
+ case BluetoothAdapter.STATE_ON:
+ mCheckBox.setChecked(true);
+ mCheckBox.setSummary(null);
+ mCheckBox.setEnabled(true);
+ break;
+ case BluetoothAdapter.STATE_TURNING_OFF:
+ mCheckBox.setSummary(R.string.wifi_stopping);
+ mCheckBox.setEnabled(false);
+ break;
+ case BluetoothAdapter.STATE_OFF:
+ mCheckBox.setChecked(false);
+ mCheckBox.setSummary(mOriginalSummary);
+ mCheckBox.setEnabled(true);
+ break;
+ default:
+ mCheckBox.setChecked(false);
+ mCheckBox.setSummary(R.string.wifi_error);
+ mCheckBox.setEnabled(true);
}
}
-
- private static boolean isBluetoothAllowed(Context context) {
- // allowed if we are not in airplane mode
- if (!AirplaneModeEnabler.isAirplaneModeOn(context)) {
- return true;
- }
- // allowed if bluetooth is not in AIRPLANE_MODE_RADIOS
- String radios = Settings.System.getString(context.getContentResolver(),
- Settings.System.AIRPLANE_MODE_RADIOS);
- if (radios == null || !radios.contains(Settings.System.RADIO_BLUETOOTH)) {
- return true;
- }
- // allowed if bluetooth is in AIRPLANE_MODE_TOGGLEABLE_RADIOS
- radios = Settings.System.getString(context.getContentResolver(),
- Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS);
- return (radios != null && radios.contains(Settings.System.RADIO_BLUETOOTH));
- }
-
}
diff --git a/src/com/android/settings/wifi/WifiEnabler.java b/src/com/android/settings/wifi/WifiEnabler.java
index b6e758d..d5376de 100644
--- a/src/com/android/settings/wifi/WifiEnabler.java
+++ b/src/com/android/settings/wifi/WifiEnabler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 The Android Open Source Project
+ * Copyright (C) 2010 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.
@@ -16,14 +16,8 @@
package com.android.settings.wifi;
-import static android.net.wifi.WifiManager.WIFI_STATE_DISABLED;
-import static android.net.wifi.WifiManager.WIFI_STATE_DISABLING;
-import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED;
-import static android.net.wifi.WifiManager.WIFI_STATE_ENABLING;
-import static android.net.wifi.WifiManager.WIFI_STATE_UNKNOWN;
-
import com.android.settings.R;
-import com.android.settings.AirplaneModeEnabler;
+import com.android.settings.WirelessSettings;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -35,169 +29,110 @@
import android.preference.CheckBoxPreference;
import android.provider.Settings;
import android.text.TextUtils;
-import android.util.Config;
-import android.util.Log;
+import android.widget.Toast;
public class WifiEnabler implements Preference.OnPreferenceChangeListener {
-
- private static final boolean LOCAL_LOGD = Config.LOGD || WifiLayer.LOGV;
- private static final String TAG = "SettingsWifiEnabler";
-
private final Context mContext;
- private final WifiManager mWifiManager;
- private final CheckBoxPreference mWifiCheckBoxPref;
+ private final CheckBoxPreference mCheckBox;
private final CharSequence mOriginalSummary;
-
- private final IntentFilter mWifiStateFilter;
- private final BroadcastReceiver mWifiStateReceiver = new BroadcastReceiver() {
+ private final WifiManager mWifiManager;
+ private final IntentFilter mIntentFilter;
+ private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- if (intent.getAction().equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
- handleWifiStateChanged(
- intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WIFI_STATE_UNKNOWN),
- intent.getIntExtra(WifiManager.EXTRA_PREVIOUS_WIFI_STATE,
- WIFI_STATE_UNKNOWN));
- } else if (intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
- handleNetworkStateChanged(
- (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO));
+ String action = intent.getAction();
+ if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {
+ handleWifiStateChanged(intent.getIntExtra(
+ WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN));
+ } else if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {
+ handleNetworkStateChanged((NetworkInfo)
+ intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO));
}
}
};
- public WifiEnabler(Context context, CheckBoxPreference wifiCheckBoxPreference) {
+ public WifiEnabler(Context context, CheckBoxPreference checkBox) {
this(context, (WifiManager) context.getSystemService(Context.WIFI_SERVICE),
- wifiCheckBoxPreference);
+ checkBox);
}
public WifiEnabler(Context context, WifiManager wifiManager,
- CheckBoxPreference wifiCheckBoxPreference) {
+ CheckBoxPreference checkBox) {
mContext = context;
- mWifiCheckBoxPref = wifiCheckBoxPreference;
+ mCheckBox = checkBox;
mWifiManager = wifiManager;
+ mOriginalSummary = checkBox.getSummary();
+ checkBox.setPersistent(false);
- mOriginalSummary = wifiCheckBoxPreference.getSummary();
- wifiCheckBoxPreference.setPersistent(false);
-
- mWifiStateFilter = new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION);
- mWifiStateFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+ mIntentFilter = new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION);
+ mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
}
public void resume() {
- int state = mWifiManager.getWifiState();
- // This is the widget enabled state, not the preference toggled state
- mWifiCheckBoxPref.setEnabled(state == WIFI_STATE_ENABLED || state == WIFI_STATE_DISABLED
- || state == WIFI_STATE_UNKNOWN);
-
- mContext.registerReceiver(mWifiStateReceiver, mWifiStateFilter);
- mWifiCheckBoxPref.setOnPreferenceChangeListener(this);
+ // Wi-Fi state is sticky, so just let the receiver update UI
+ mContext.registerReceiver(mReceiver, mIntentFilter);
+ mCheckBox.setOnPreferenceChangeListener(this);
}
public void pause() {
- mContext.unregisterReceiver(mWifiStateReceiver);
- mWifiCheckBoxPref.setOnPreferenceChangeListener(null);
+ mContext.unregisterReceiver(mReceiver);
+ mCheckBox.setOnPreferenceChangeListener(null);
}
public boolean onPreferenceChange(Preference preference, Object value) {
- // Turn on/off Wi-Fi
- setWifiEnabled((Boolean) value);
-
+ boolean enable = (Boolean) value;
+
+ // Show toast message if Wi-Fi is not allowed in airplane mode
+ if (enable && !WirelessSettings
+ .isRadioAllowed(mContext, Settings.System.RADIO_WIFI)) {
+ Toast.makeText(mContext, R.string.wifi_in_airplane_mode,
+ Toast.LENGTH_SHORT).show();
+ return false;
+ }
+
+ if (mWifiManager.setWifiEnabled(enable)) {
+ mCheckBox.setEnabled(false);
+ } else {
+ mCheckBox.setSummary(R.string.wifi_error);
+ }
+
// Don't update UI to opposite state until we're sure
return false;
}
- private void setWifiEnabled(final boolean enable) {
- // Disable button
- mWifiCheckBoxPref.setEnabled(false);
-
- if (!mWifiManager.setWifiEnabled(enable)) {
- mWifiCheckBoxPref.setSummary(enable ? R.string.error_starting : R.string.error_stopping);
- }
- }
-
- private void handleWifiStateChanged(int wifiState, int previousWifiState) {
-
- if (LOCAL_LOGD) {
- Log.d(TAG, "Received wifi state changed from "
- + getHumanReadableWifiState(previousWifiState) + " to "
- + getHumanReadableWifiState(wifiState));
- }
-
- if (wifiState == WIFI_STATE_DISABLED || wifiState == WIFI_STATE_ENABLED) {
- mWifiCheckBoxPref.setChecked(wifiState == WIFI_STATE_ENABLED);
- mWifiCheckBoxPref
- .setSummary(wifiState == WIFI_STATE_DISABLED ? mOriginalSummary : null);
-
- final boolean hasDependency = !TextUtils.isEmpty(mWifiCheckBoxPref.getDependency());
- final boolean wifiAllowed = isWifiAllowed(mContext);
-
- // Avoid disabling when dependencies have been manually set,
- // workaround for framework bug http://b/2053751
- if (wifiAllowed) {
- mWifiCheckBoxPref.setEnabled(true);
- } else if (!hasDependency) {
- mWifiCheckBoxPref.setEnabled(false);
- }
-
- } else if (wifiState == WIFI_STATE_DISABLING || wifiState == WIFI_STATE_ENABLING) {
- mWifiCheckBoxPref.setSummary(wifiState == WIFI_STATE_ENABLING ? R.string.wifi_starting
- : R.string.wifi_stopping);
-
- } else if (wifiState == WIFI_STATE_UNKNOWN) {
- int message = R.string.wifi_error;
- if (previousWifiState == WIFI_STATE_ENABLING) message = R.string.error_starting;
- else if (previousWifiState == WIFI_STATE_DISABLING) message = R.string.error_stopping;
-
- mWifiCheckBoxPref.setChecked(false);
- mWifiCheckBoxPref.setSummary(message);
- mWifiCheckBoxPref.setEnabled(true);
+ private void handleWifiStateChanged(int state) {
+ switch (state) {
+ case WifiManager.WIFI_STATE_ENABLING:
+ mCheckBox.setSummary(R.string.wifi_starting);
+ mCheckBox.setEnabled(false);
+ break;
+ case WifiManager.WIFI_STATE_ENABLED:
+ mCheckBox.setChecked(true);
+ mCheckBox.setSummary(null);
+ mCheckBox.setEnabled(true);
+ break;
+ case WifiManager.WIFI_STATE_DISABLING:
+ mCheckBox.setSummary(R.string.wifi_stopping);
+ mCheckBox.setEnabled(false);
+ break;
+ case WifiManager.WIFI_STATE_DISABLED:
+ mCheckBox.setChecked(false);
+ mCheckBox.setSummary(mOriginalSummary);
+ mCheckBox.setEnabled(true);
+ break;
+ default:
+ mCheckBox.setChecked(false);
+ mCheckBox.setSummary(R.string.wifi_error);
+ mCheckBox.setEnabled(true);
}
}
private void handleNetworkStateChanged(NetworkInfo networkInfo) {
-
- if (LOCAL_LOGD) {
- Log.d(TAG, "Received network state changed to " + networkInfo);
- }
-
if (mWifiManager.isWifiEnabled()) {
String summary = WifiStatus.getStatus(mContext,
mWifiManager.getConnectionInfo().getSSID(), networkInfo.getDetailedState());
- mWifiCheckBoxPref.setSummary(summary);
- }
- }
-
- private static boolean isWifiAllowed(Context context) {
- // allowed if we are not in airplane mode
- if (!AirplaneModeEnabler.isAirplaneModeOn(context)) {
- return true;
- }
- // allowed if wifi is not in AIRPLANE_MODE_RADIOS
- String radios = Settings.System.getString(context.getContentResolver(),
- Settings.System.AIRPLANE_MODE_RADIOS);
- if (radios == null || !radios.contains(Settings.System.RADIO_WIFI)) {
- return true;
- }
- // allowed if wifi is in AIRPLANE_MODE_TOGGLEABLE_RADIOS
- radios = Settings.System.getString(context.getContentResolver(),
- Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS);
- return (radios != null && radios.contains(Settings.System.RADIO_WIFI));
- }
-
- private static String getHumanReadableWifiState(int wifiState) {
- switch (wifiState) {
- case WIFI_STATE_DISABLED:
- return "Disabled";
- case WIFI_STATE_DISABLING:
- return "Disabling";
- case WIFI_STATE_ENABLED:
- return "Enabled";
- case WIFI_STATE_ENABLING:
- return "Enabling";
- case WIFI_STATE_UNKNOWN:
- return "Unknown";
- default:
- return "Some other state!";
+ mCheckBox.setSummary(summary);
}
}
}