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