Home | History | Annotate | Download | only in wifi
      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