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.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