WifiEnabler.java revision 1c4e96864f054f0d3d754d21eb4803fe0df6d89f
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, WifiManager wifiManager, 69 CheckBoxPreference wifiCheckBoxPreference) { 70 mContext = context; 71 mWifiCheckBoxPref = wifiCheckBoxPreference; 72 mWifiManager = wifiManager; 73 74 mOriginalSummary = wifiCheckBoxPreference.getSummary(); 75 wifiCheckBoxPreference.setPersistent(false); 76 77 mWifiStateFilter = new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION); 78 mWifiStateFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); 79 } 80 81 public void resume() { 82 int state = mWifiManager.getWifiState(); 83 // This is the widget enabled state, not the preference toggled state 84 mWifiCheckBoxPref.setEnabled(state == WIFI_STATE_ENABLED || state == WIFI_STATE_DISABLED 85 || state == WIFI_STATE_UNKNOWN); 86 87 mContext.registerReceiver(mWifiStateReceiver, mWifiStateFilter); 88 mWifiCheckBoxPref.setOnPreferenceChangeListener(this); 89 } 90 91 public void pause() { 92 mContext.unregisterReceiver(mWifiStateReceiver); 93 mWifiCheckBoxPref.setOnPreferenceChangeListener(null); 94 } 95 96 public boolean onPreferenceChange(Preference preference, Object value) { 97 // Turn on/off Wi-Fi 98 setWifiEnabled((Boolean) value); 99 100 // Don't update UI to opposite state until we're sure 101 return false; 102 } 103 104 private void setWifiEnabled(final boolean enable) { 105 // Disable button 106 mWifiCheckBoxPref.setEnabled(false); 107 108 if (!mWifiManager.setWifiEnabled(enable)) { 109 mWifiCheckBoxPref.setSummary(enable ? R.string.error_starting : R.string.error_stopping); 110 } 111 } 112 113 private void handleWifiStateChanged(int wifiState, int previousWifiState) { 114 115 if (LOCAL_LOGD) { 116 Log.d(TAG, "Received wifi state changed from " 117 + getHumanReadableWifiState(previousWifiState) + " to " 118 + getHumanReadableWifiState(wifiState)); 119 } 120 121 if (wifiState == WIFI_STATE_DISABLED || wifiState == WIFI_STATE_ENABLED) { 122 mWifiCheckBoxPref.setChecked(wifiState == WIFI_STATE_ENABLED); 123 mWifiCheckBoxPref 124 .setSummary(wifiState == WIFI_STATE_DISABLED ? mOriginalSummary : null); 125 126 final boolean hasDependency = !TextUtils.isEmpty(mWifiCheckBoxPref.getDependency()); 127 final boolean wifiAllowed = isWifiAllowed(mContext); 128 129 // Avoid disabling when dependencies have been manually set, 130 // workaround for framework bug http://b/2053751 131 if (wifiAllowed) { 132 mWifiCheckBoxPref.setEnabled(true); 133 } else if (!hasDependency) { 134 mWifiCheckBoxPref.setEnabled(false); 135 } 136 137 } else if (wifiState == WIFI_STATE_DISABLING || wifiState == WIFI_STATE_ENABLING) { 138 mWifiCheckBoxPref.setSummary(wifiState == WIFI_STATE_ENABLING ? R.string.wifi_starting 139 : R.string.wifi_stopping); 140 141 } else if (wifiState == WIFI_STATE_UNKNOWN) { 142 int message = R.string.wifi_error; 143 if (previousWifiState == WIFI_STATE_ENABLING) message = R.string.error_starting; 144 else if (previousWifiState == WIFI_STATE_DISABLING) message = R.string.error_stopping; 145 146 mWifiCheckBoxPref.setChecked(false); 147 mWifiCheckBoxPref.setSummary(message); 148 mWifiCheckBoxPref.setEnabled(true); 149 } 150 } 151 152 private void handleNetworkStateChanged(NetworkInfo networkInfo) { 153 154 if (LOCAL_LOGD) { 155 Log.d(TAG, "Received network state changed to " + networkInfo); 156 } 157 158 if (mWifiManager.isWifiEnabled()) { 159 String summary = WifiStatus.getStatus(mContext, 160 mWifiManager.getConnectionInfo().getSSID(), networkInfo.getDetailedState()); 161 mWifiCheckBoxPref.setSummary(summary); 162 } 163 } 164 165 private static boolean isWifiAllowed(Context context) { 166 // allowed if we are not in airplane mode 167 if (!AirplaneModeEnabler.isAirplaneModeOn(context)) { 168 return true; 169 } 170 // allowed if wifi is not in AIRPLANE_MODE_RADIOS 171 String radios = Settings.System.getString(context.getContentResolver(), 172 Settings.System.AIRPLANE_MODE_RADIOS); 173 if (radios == null || !radios.contains(Settings.System.RADIO_WIFI)) { 174 return true; 175 } 176 // allowed if wifi is in AIRPLANE_MODE_TOGGLEABLE_RADIOS 177 radios = Settings.System.getString(context.getContentResolver(), 178 Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS); 179 return (radios != null && radios.contains(Settings.System.RADIO_WIFI)); 180 } 181 182 private static String getHumanReadableWifiState(int wifiState) { 183 switch (wifiState) { 184 case WIFI_STATE_DISABLED: 185 return "Disabled"; 186 case WIFI_STATE_DISABLING: 187 return "Disabling"; 188 case WIFI_STATE_ENABLED: 189 return "Enabled"; 190 case WIFI_STATE_ENABLING: 191 return "Enabling"; 192 case WIFI_STATE_UNKNOWN: 193 return "Unknown"; 194 default: 195 return "Some other state!"; 196 } 197 } 198} 199