From b90452f3d26201ea6a231f2150204241e66cd3fb Mon Sep 17 00:00:00 2001 From: Chia-chi Yeh Date: Wed, 13 Jan 2010 06:11:29 +0800 Subject: [PATCH] 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 --- res/values/strings.xml | 8 +- .../android/settings/WirelessSettings.java | 17 +- .../settings/bluetooth/BluetoothEnabler.java | 134 +++++------- .../android/settings/wifi/WifiEnabler.java | 201 ++++++------------ 4 files changed, 139 insertions(+), 221 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index c289038aa93..b86950b982d 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -707,12 +707,14 @@ IP address Signal strength - + Turning on\u2026 - + Turning off\u2026 - + Error + + In airplane mode Unable to start Wi-Fi diff --git a/src/com/android/settings/WirelessSettings.java b/src/com/android/settings/WirelessSettings.java index 1d0b2d89a52..bf75e27af7b 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 @@ public class WirelessSettings extends PreferenceActivity { // 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 @@ public class WirelessSettings extends PreferenceActivity { 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 @@ public class WirelessSettings extends PreferenceActivity { 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 46793cea759..426a4d3ac0a 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.Preference; 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 @@ import android.util.Config; * 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 class BluetoothEnabler implements Preference.OnPreferenceChangeListener { } }; - 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 @@ public class BluetoothEnabler implements Preference.OnPreferenceChangeListener { 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 @@ public class BluetoothEnabler implements Preference.OnPreferenceChangeListener { } 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 b6e758d34ec..d5376dec148 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.Preference; 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); } } }