WifiEnabler.java revision 4e14211d21387d645ecdad406f3350d36e5a8643
1/* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.settings.wifi; 18 19import static android.net.wifi.WifiManager.WIFI_STATE_DISABLED; 20import static android.net.wifi.WifiManager.WIFI_STATE_DISABLING; 21import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED; 22import static android.net.wifi.WifiManager.WIFI_STATE_ENABLING; 23import static android.net.wifi.WifiManager.WIFI_STATE_UNKNOWN; 24 25import com.android.settings.R; 26import com.android.settings.AirplaneModeEnabler; 27 28import android.content.BroadcastReceiver; 29import android.content.Context; 30import android.content.Intent; 31import android.content.IntentFilter; 32import android.net.NetworkInfo; 33import android.net.wifi.WifiManager; 34import android.preference.Preference; 35import android.preference.CheckBoxPreference; 36import android.provider.Settings; 37import android.text.TextUtils; 38import android.util.Config; 39import android.util.Log; 40 41public class WifiEnabler implements Preference.OnPreferenceChangeListener { 42 43 private static final boolean LOCAL_LOGD = Config.LOGD || WifiLayer.LOGV; 44 private static final String TAG = "SettingsWifiEnabler"; 45 46 private final Context mContext; 47 private final WifiManager mWifiManager; 48 private final CheckBoxPreference mWifiCheckBoxPref; 49 private final CharSequence mOriginalSummary; 50 51 private final IntentFilter mWifiStateFilter; 52 private final BroadcastReceiver mWifiStateReceiver = new BroadcastReceiver() { 53 54 @Override 55 public void onReceive(Context context, Intent intent) { 56 if (intent.getAction().equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { 57 handleWifiStateChanged( 58 intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WIFI_STATE_UNKNOWN), 59 intent.getIntExtra(WifiManager.EXTRA_PREVIOUS_WIFI_STATE, 60 WIFI_STATE_UNKNOWN)); 61 } else if (intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { 62 handleNetworkStateChanged( 63 (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO)); 64 } 65 } 66 }; 67 68 public WifiEnabler(Context context, CheckBoxPreference wifiCheckBoxPreference) { 69 this(context, (WifiManager) context.getSystemService(Context.WIFI_SERVICE), 70 wifiCheckBoxPreference); 71 } 72 73 public WifiEnabler(Context context, WifiManager wifiManager, 74 CheckBoxPreference wifiCheckBoxPreference) { 75 mContext = context; 76 mWifiCheckBoxPref = wifiCheckBoxPreference; 77 mWifiManager = wifiManager; 78 79 mOriginalSummary = wifiCheckBoxPreference.getSummary(); 80 wifiCheckBoxPreference.setPersistent(false); 81 82 mWifiStateFilter = new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION); 83 mWifiStateFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); 84 } 85 86 public void resume() { 87 int state = mWifiManager.getWifiState(); 88 // This is the widget enabled state, not the preference toggled state 89 mWifiCheckBoxPref.setEnabled(state == WIFI_STATE_ENABLED || state == WIFI_STATE_DISABLED 90 || state == WIFI_STATE_UNKNOWN); 91 92 mContext.registerReceiver(mWifiStateReceiver, mWifiStateFilter); 93 mWifiCheckBoxPref.setOnPreferenceChangeListener(this); 94 } 95 96 public void pause() { 97 mContext.unregisterReceiver(mWifiStateReceiver); 98 mWifiCheckBoxPref.setOnPreferenceChangeListener(null); 99 } 100 101 public boolean onPreferenceChange(Preference preference, Object value) { 102 // Turn on/off Wi-Fi 103 setWifiEnabled((Boolean) value); 104 105 // Don't update UI to opposite state until we're sure 106 return false; 107 } 108 109 private void setWifiEnabled(final boolean enable) { 110 // Disable button 111 mWifiCheckBoxPref.setEnabled(false); 112 113 if (!mWifiManager.setWifiEnabled(enable)) { 114 mWifiCheckBoxPref.setSummary(enable ? R.string.error_starting : R.string.error_stopping); 115 } 116 } 117 118 private void handleWifiStateChanged(int wifiState, int previousWifiState) { 119 120 if (LOCAL_LOGD) { 121 Log.d(TAG, "Received wifi state changed from " 122 + getHumanReadableWifiState(previousWifiState) + " to " 123 + getHumanReadableWifiState(wifiState)); 124 } 125 126 if (wifiState == WIFI_STATE_DISABLED || wifiState == WIFI_STATE_ENABLED) { 127 mWifiCheckBoxPref.setChecked(wifiState == WIFI_STATE_ENABLED); 128 mWifiCheckBoxPref 129 .setSummary(wifiState == WIFI_STATE_DISABLED ? mOriginalSummary : null); 130 131 final boolean hasDependency = !TextUtils.isEmpty(mWifiCheckBoxPref.getDependency()); 132 final boolean wifiAllowed = isWifiAllowed(mContext); 133 134 // Avoid disabling when dependencies have been manually set, 135 // workaround for framework bug http://b/2053751 136 if (wifiAllowed) { 137 mWifiCheckBoxPref.setEnabled(true); 138 } else if (!hasDependency) { 139 mWifiCheckBoxPref.setEnabled(false); 140 } 141 142 } else if (wifiState == WIFI_STATE_DISABLING || wifiState == WIFI_STATE_ENABLING) { 143 mWifiCheckBoxPref.setSummary(wifiState == WIFI_STATE_ENABLING ? R.string.wifi_starting 144 : R.string.wifi_stopping); 145 146 } else if (wifiState == WIFI_STATE_UNKNOWN) { 147 int message = R.string.wifi_error; 148 if (previousWifiState == WIFI_STATE_ENABLING) message = R.string.error_starting; 149 else if (previousWifiState == WIFI_STATE_DISABLING) message = R.string.error_stopping; 150 151 mWifiCheckBoxPref.setChecked(false); 152 mWifiCheckBoxPref.setSummary(message); 153 mWifiCheckBoxPref.setEnabled(true); 154 } 155 } 156 157 private void handleNetworkStateChanged(NetworkInfo networkInfo) { 158 159 if (LOCAL_LOGD) { 160 Log.d(TAG, "Received network state changed to " + networkInfo); 161 } 162 163 if (mWifiManager.isWifiEnabled()) { 164 String summary = WifiStatus.getStatus(mContext, 165 mWifiManager.getConnectionInfo().getSSID(), networkInfo.getDetailedState()); 166 mWifiCheckBoxPref.setSummary(summary); 167 } 168 } 169 170 private static boolean isWifiAllowed(Context context) { 171 // allowed if we are not in airplane mode 172 if (!AirplaneModeEnabler.isAirplaneModeOn(context)) { 173 return true; 174 } 175 // allowed if wifi is not in AIRPLANE_MODE_RADIOS 176 String radios = Settings.System.getString(context.getContentResolver(), 177 Settings.System.AIRPLANE_MODE_RADIOS); 178 if (radios == null || !radios.contains(Settings.System.RADIO_WIFI)) { 179 return true; 180 } 181 // allowed if wifi is in AIRPLANE_MODE_TOGGLEABLE_RADIOS 182 radios = Settings.System.getString(context.getContentResolver(), 183 Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS); 184 return (radios != null && radios.contains(Settings.System.RADIO_WIFI)); 185 } 186 187 private static String getHumanReadableWifiState(int wifiState) { 188 switch (wifiState) { 189 case WIFI_STATE_DISABLED: 190 return "Disabled"; 191 case WIFI_STATE_DISABLING: 192 return "Disabling"; 193 case WIFI_STATE_ENABLED: 194 return "Enabled"; 195 case WIFI_STATE_ENABLING: 196 return "Enabling"; 197 case WIFI_STATE_UNKNOWN: 198 return "Unknown"; 199 default: 200 return "Some other state!"; 201 } 202 } 203} 204