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