1/* 2 * Copyright (C) 2010 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 com.android.settings.R; 20import com.android.settings.WirelessSettings; 21 22import java.util.ArrayList; 23 24import android.app.AlertDialog; 25import android.content.BroadcastReceiver; 26import android.content.ContentResolver; 27import android.content.Context; 28import android.content.Intent; 29import android.content.IntentFilter; 30import android.net.ConnectivityManager; 31import android.net.NetworkInfo; 32import android.net.wifi.SupplicantState; 33import android.net.wifi.WifiConfiguration; 34import android.net.wifi.WifiInfo; 35import android.net.wifi.WifiManager; 36import android.preference.Preference; 37import android.preference.CheckBoxPreference; 38import android.provider.Settings; 39import android.text.TextUtils; 40import android.util.Log; 41import android.widget.Toast; 42 43public class WifiApEnabler implements Preference.OnPreferenceChangeListener { 44 private final Context mContext; 45 private final CheckBoxPreference mCheckBox; 46 private final CharSequence mOriginalSummary; 47 48 private WifiManager mWifiManager; 49 private final IntentFilter mIntentFilter; 50 51 ConnectivityManager mCm; 52 private String[] mWifiRegexs; 53 54 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 55 @Override 56 public void onReceive(Context context, Intent intent) { 57 String action = intent.getAction(); 58 if (WifiManager.WIFI_AP_STATE_CHANGED_ACTION.equals(action)) { 59 handleWifiApStateChanged(intent.getIntExtra( 60 WifiManager.EXTRA_WIFI_AP_STATE, WifiManager.WIFI_AP_STATE_FAILED)); 61 } else if (ConnectivityManager.ACTION_TETHER_STATE_CHANGED.equals(action)) { 62 ArrayList<String> available = intent.getStringArrayListExtra( 63 ConnectivityManager.EXTRA_AVAILABLE_TETHER); 64 ArrayList<String> active = intent.getStringArrayListExtra( 65 ConnectivityManager.EXTRA_ACTIVE_TETHER); 66 ArrayList<String> errored = intent.getStringArrayListExtra( 67 ConnectivityManager.EXTRA_ERRORED_TETHER); 68 updateTetherState(available.toArray(), active.toArray(), errored.toArray()); 69 } 70 71 } 72 }; 73 74 public WifiApEnabler(Context context, CheckBoxPreference checkBox) { 75 mContext = context; 76 mCheckBox = checkBox; 77 mOriginalSummary = checkBox.getSummary(); 78 checkBox.setPersistent(false); 79 80 mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); 81 mCm = (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE); 82 83 mWifiRegexs = mCm.getTetherableWifiRegexs(); 84 85 mIntentFilter = new IntentFilter(WifiManager.WIFI_AP_STATE_CHANGED_ACTION); 86 mIntentFilter.addAction(ConnectivityManager.ACTION_TETHER_STATE_CHANGED); 87 } 88 89 public void resume() { 90 mContext.registerReceiver(mReceiver, mIntentFilter); 91 enableWifiCheckBox(); 92 mCheckBox.setOnPreferenceChangeListener(this); 93 } 94 95 public void pause() { 96 mContext.unregisterReceiver(mReceiver); 97 mCheckBox.setOnPreferenceChangeListener(null); 98 } 99 100 private void enableWifiCheckBox() { 101 boolean isAirplaneMode = Settings.System.getInt(mContext.getContentResolver(), 102 Settings.System.AIRPLANE_MODE_ON, 0) != 0; 103 if(!isAirplaneMode) { 104 mCheckBox.setEnabled(true); 105 } else { 106 mCheckBox.setEnabled(false); 107 } 108 } 109 110 public boolean onPreferenceChange(Preference preference, Object value) { 111 112 final ContentResolver cr = mContext.getContentResolver(); 113 boolean enable = (Boolean)value; 114 115 /** 116 * Disable Wifi if enabling tethering 117 */ 118 int wifiState = mWifiManager.getWifiState(); 119 if (enable && ((wifiState == WifiManager.WIFI_STATE_ENABLING) || 120 (wifiState == WifiManager.WIFI_STATE_ENABLED))) { 121 mWifiManager.setWifiEnabled(false); 122 Settings.Secure.putInt(cr, Settings.Secure.WIFI_SAVED_STATE, 1); 123 } 124 125 if (mWifiManager.setWifiApEnabled(null, enable)) { 126 /* Disable here, enabled on receiving success broadcast */ 127 mCheckBox.setEnabled(false); 128 } else { 129 mCheckBox.setSummary(R.string.wifi_error); 130 } 131 132 /** 133 * If needed, restore Wifi on tether disable 134 */ 135 if (!enable) { 136 int wifiSavedState = 0; 137 try { 138 wifiSavedState = Settings.Secure.getInt(cr, Settings.Secure.WIFI_SAVED_STATE); 139 } catch (Settings.SettingNotFoundException e) { 140 ; 141 } 142 if (wifiSavedState == 1) { 143 mWifiManager.setWifiEnabled(true); 144 Settings.Secure.putInt(cr, Settings.Secure.WIFI_SAVED_STATE, 0); 145 } 146 } 147 148 return false; 149 } 150 151 void updateConfigSummary(WifiConfiguration wifiConfig) { 152 String s = mContext.getString( 153 com.android.internal.R.string.wifi_tether_configure_ssid_default); 154 mCheckBox.setSummary(String.format( 155 mContext.getString(R.string.wifi_tether_enabled_subtext), 156 (wifiConfig == null) ? s : wifiConfig.SSID)); 157 } 158 159 private void updateTetherState(Object[] available, Object[] tethered, Object[] errored) { 160 boolean wifiTethered = false; 161 boolean wifiErrored = false; 162 163 for (Object o : tethered) { 164 String s = (String)o; 165 for (String regex : mWifiRegexs) { 166 if (s.matches(regex)) wifiTethered = true; 167 } 168 } 169 for (Object o: errored) { 170 String s = (String)o; 171 for (String regex : mWifiRegexs) { 172 if (s.matches(regex)) wifiErrored = true; 173 } 174 } 175 176 if (wifiTethered) { 177 WifiConfiguration wifiConfig = mWifiManager.getWifiApConfiguration(); 178 updateConfigSummary(wifiConfig); 179 } else if (wifiErrored) { 180 mCheckBox.setSummary(R.string.wifi_error); 181 } 182 } 183 184 private void handleWifiApStateChanged(int state) { 185 switch (state) { 186 case WifiManager.WIFI_AP_STATE_ENABLING: 187 mCheckBox.setSummary(R.string.wifi_starting); 188 mCheckBox.setEnabled(false); 189 break; 190 case WifiManager.WIFI_AP_STATE_ENABLED: 191 /** 192 * Summary on enable is handled by tether 193 * broadcast notice 194 */ 195 mCheckBox.setChecked(true); 196 /* Doesnt need the airplane check */ 197 mCheckBox.setEnabled(true); 198 break; 199 case WifiManager.WIFI_AP_STATE_DISABLING: 200 mCheckBox.setSummary(R.string.wifi_stopping); 201 mCheckBox.setEnabled(false); 202 break; 203 case WifiManager.WIFI_AP_STATE_DISABLED: 204 mCheckBox.setChecked(false); 205 mCheckBox.setSummary(mOriginalSummary); 206 enableWifiCheckBox(); 207 break; 208 default: 209 mCheckBox.setChecked(false); 210 mCheckBox.setSummary(R.string.wifi_error); 211 enableWifiCheckBox(); 212 } 213 } 214} 215