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