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