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.CheckBoxPreference; 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 CheckBoxPreference mCheckBox; 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 enableWifiCheckBox(); 70 } 71 72 } 73 }; 74 75 public WifiApEnabler(Context context, CheckBoxPreference checkBox) { 76 mContext = context; 77 mCheckBox = checkBox; 78 mOriginalSummary = checkBox.getSummary(); 79 checkBox.setPersistent(false); 80 81 mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); 82 mCm = (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE); 83 84 mWifiRegexs = mCm.getTetherableWifiRegexs(); 85 86 mIntentFilter = new IntentFilter(WifiManager.WIFI_AP_STATE_CHANGED_ACTION); 87 mIntentFilter.addAction(ConnectivityManager.ACTION_TETHER_STATE_CHANGED); 88 mIntentFilter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED); 89 } 90 91 public void resume() { 92 mContext.registerReceiver(mReceiver, mIntentFilter); 93 enableWifiCheckBox(); 94 } 95 96 public void pause() { 97 mContext.unregisterReceiver(mReceiver); 98 } 99 100 private void enableWifiCheckBox() { 101 boolean isAirplaneMode = Settings.Global.getInt(mContext.getContentResolver(), 102 Settings.Global.AIRPLANE_MODE_ON, 0) != 0; 103 if(!isAirplaneMode) { 104 mCheckBox.setEnabled(true); 105 } else { 106 mCheckBox.setSummary(mOriginalSummary); 107 mCheckBox.setEnabled(false); 108 } 109 } 110 111 public void setSoftapEnabled(boolean enable) { 112 final ContentResolver cr = mContext.getContentResolver(); 113 /** 114 * Disable Wifi if enabling tethering 115 */ 116 int wifiState = mWifiManager.getWifiState(); 117 if (enable && ((wifiState == WifiManager.WIFI_STATE_ENABLING) || 118 (wifiState == WifiManager.WIFI_STATE_ENABLED))) { 119 mWifiManager.setWifiEnabled(false); 120 Settings.Global.putInt(cr, Settings.Global.WIFI_SAVED_STATE, 1); 121 } 122 123 if (mWifiManager.setWifiApEnabled(null, enable)) { 124 /* Disable here, enabled on receiving success broadcast */ 125 mCheckBox.setEnabled(false); 126 } else { 127 mCheckBox.setSummary(R.string.wifi_error); 128 } 129 130 /** 131 * If needed, restore Wifi on tether disable 132 */ 133 if (!enable) { 134 int wifiSavedState = 0; 135 try { 136 wifiSavedState = Settings.Global.getInt(cr, Settings.Global.WIFI_SAVED_STATE); 137 } catch (Settings.SettingNotFoundException e) { 138 ; 139 } 140 if (wifiSavedState == 1) { 141 mWifiManager.setWifiEnabled(true); 142 Settings.Global.putInt(cr, Settings.Global.WIFI_SAVED_STATE, 0); 143 } 144 } 145 } 146 147 public void updateConfigSummary(WifiConfiguration wifiConfig) { 148 String s = mContext.getString( 149 com.android.internal.R.string.wifi_tether_configure_ssid_default); 150 mCheckBox.setSummary(String.format( 151 mContext.getString(R.string.wifi_tether_enabled_subtext), 152 (wifiConfig == null) ? s : wifiConfig.SSID)); 153 } 154 155 private void updateTetherState(Object[] available, Object[] tethered, Object[] errored) { 156 boolean wifiTethered = false; 157 boolean wifiErrored = false; 158 159 for (Object o : tethered) { 160 String s = (String)o; 161 for (String regex : mWifiRegexs) { 162 if (s.matches(regex)) wifiTethered = true; 163 } 164 } 165 for (Object o: errored) { 166 String s = (String)o; 167 for (String regex : mWifiRegexs) { 168 if (s.matches(regex)) wifiErrored = true; 169 } 170 } 171 172 if (wifiTethered) { 173 WifiConfiguration wifiConfig = mWifiManager.getWifiApConfiguration(); 174 updateConfigSummary(wifiConfig); 175 } else if (wifiErrored) { 176 mCheckBox.setSummary(R.string.wifi_error); 177 } 178 } 179 180 private void handleWifiApStateChanged(int state) { 181 switch (state) { 182 case WifiManager.WIFI_AP_STATE_ENABLING: 183 mCheckBox.setSummary(R.string.wifi_tether_starting); 184 mCheckBox.setEnabled(false); 185 break; 186 case WifiManager.WIFI_AP_STATE_ENABLED: 187 /** 188 * Summary on enable is handled by tether 189 * broadcast notice 190 */ 191 mCheckBox.setChecked(true); 192 /* Doesnt need the airplane check */ 193 mCheckBox.setEnabled(true); 194 break; 195 case WifiManager.WIFI_AP_STATE_DISABLING: 196 mCheckBox.setSummary(R.string.wifi_tether_stopping); 197 mCheckBox.setEnabled(false); 198 break; 199 case WifiManager.WIFI_AP_STATE_DISABLED: 200 mCheckBox.setChecked(false); 201 mCheckBox.setSummary(mOriginalSummary); 202 enableWifiCheckBox(); 203 break; 204 default: 205 mCheckBox.setChecked(false); 206 mCheckBox.setSummary(R.string.wifi_error); 207 enableWifiCheckBox(); 208 } 209 } 210 } 211