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.NetworkInfo;
     24 import android.net.wifi.SupplicantState;
     25 import android.net.wifi.WifiInfo;
     26 import android.net.wifi.WifiManager;
     27 import android.provider.Settings;
     28 import android.widget.CompoundButton;
     29 import android.widget.Switch;
     30 import android.widget.Toast;
     31 
     32 import com.android.settings.R;
     33 import com.android.settings.WirelessSettings;
     34 
     35 import java.util.concurrent.atomic.AtomicBoolean;
     36 
     37 public class WifiEnabler implements CompoundButton.OnCheckedChangeListener  {
     38     private final Context mContext;
     39     private Switch mSwitch;
     40     private AtomicBoolean mConnected = new AtomicBoolean(false);
     41 
     42     private final WifiManager mWifiManager;
     43     private boolean mStateMachineEvent;
     44     private final IntentFilter mIntentFilter;
     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_STATE_CHANGED_ACTION.equals(action)) {
     50                 handleWifiStateChanged(intent.getIntExtra(
     51                         WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN));
     52             } else if (WifiManager.SUPPLICANT_STATE_CHANGED_ACTION.equals(action)) {
     53                 if (!mConnected.get()) {
     54                     handleStateChanged(WifiInfo.getDetailedStateOf((SupplicantState)
     55                             intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE)));
     56                 }
     57             } else if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {
     58                 NetworkInfo info = (NetworkInfo) intent.getParcelableExtra(
     59                         WifiManager.EXTRA_NETWORK_INFO);
     60                 mConnected.set(info.isConnected());
     61                 handleStateChanged(info.getDetailedState());
     62             }
     63         }
     64     };
     65 
     66     public WifiEnabler(Context context, Switch switch_) {
     67         mContext = context;
     68         mSwitch = switch_;
     69 
     70         mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
     71         mIntentFilter = new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION);
     72         // The order matters! We really should not depend on this. :(
     73         mIntentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
     74         mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
     75     }
     76 
     77     public void resume() {
     78         // Wi-Fi state is sticky, so just let the receiver update UI
     79         mContext.registerReceiver(mReceiver, mIntentFilter);
     80         mSwitch.setOnCheckedChangeListener(this);
     81     }
     82 
     83     public void pause() {
     84         mContext.unregisterReceiver(mReceiver);
     85         mSwitch.setOnCheckedChangeListener(null);
     86     }
     87 
     88     public void setSwitch(Switch switch_) {
     89         if (mSwitch == switch_) return;
     90         mSwitch.setOnCheckedChangeListener(null);
     91         mSwitch = switch_;
     92         mSwitch.setOnCheckedChangeListener(this);
     93 
     94         final int wifiState = mWifiManager.getWifiState();
     95         boolean isEnabled = wifiState == WifiManager.WIFI_STATE_ENABLED;
     96         boolean isDisabled = wifiState == WifiManager.WIFI_STATE_DISABLED;
     97         mSwitch.setChecked(isEnabled);
     98         mSwitch.setEnabled(isEnabled || isDisabled);
     99     }
    100 
    101     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
    102         //Do nothing if called as a result of a state machine event
    103         if (mStateMachineEvent) {
    104             return;
    105         }
    106         // Show toast message if Wi-Fi is not allowed in airplane mode
    107         if (isChecked && !WirelessSettings.isRadioAllowed(mContext, Settings.System.RADIO_WIFI)) {
    108             Toast.makeText(mContext, R.string.wifi_in_airplane_mode, Toast.LENGTH_SHORT).show();
    109             // Reset switch to off. No infinite check/listenenr loop.
    110             buttonView.setChecked(false);
    111         }
    112 
    113         // Disable tethering if enabling Wifi
    114         int wifiApState = mWifiManager.getWifiApState();
    115         if (isChecked && ((wifiApState == WifiManager.WIFI_AP_STATE_ENABLING) ||
    116                 (wifiApState == WifiManager.WIFI_AP_STATE_ENABLED))) {
    117             mWifiManager.setWifiApEnabled(null, false);
    118         }
    119 
    120         if (mWifiManager.setWifiEnabled(isChecked)) {
    121             // Intent has been taken into account, disable until new state is active
    122             mSwitch.setEnabled(false);
    123         } else {
    124             // Error
    125             Toast.makeText(mContext, R.string.wifi_error, Toast.LENGTH_SHORT).show();
    126         }
    127     }
    128 
    129     private void handleWifiStateChanged(int state) {
    130         switch (state) {
    131             case WifiManager.WIFI_STATE_ENABLING:
    132                 mSwitch.setEnabled(false);
    133                 break;
    134             case WifiManager.WIFI_STATE_ENABLED:
    135                 setSwitchChecked(true);
    136                 mSwitch.setEnabled(true);
    137                 break;
    138             case WifiManager.WIFI_STATE_DISABLING:
    139                 mSwitch.setEnabled(false);
    140                 break;
    141             case WifiManager.WIFI_STATE_DISABLED:
    142                 setSwitchChecked(false);
    143                 mSwitch.setEnabled(true);
    144                 break;
    145             default:
    146                 setSwitchChecked(false);
    147                 mSwitch.setEnabled(true);
    148                 break;
    149         }
    150     }
    151 
    152     private void setSwitchChecked(boolean checked) {
    153         if (checked != mSwitch.isChecked()) {
    154             mStateMachineEvent = true;
    155             mSwitch.setChecked(checked);
    156             mStateMachineEvent = false;
    157         }
    158     }
    159 
    160     private void handleStateChanged(@SuppressWarnings("unused") NetworkInfo.DetailedState state) {
    161         // After the refactoring from a CheckBoxPreference to a Switch, this method is useless since
    162         // there is nowhere to display a summary.
    163         // This code is kept in case a future change re-introduces an associated text.
    164         /*
    165         // WifiInfo is valid if and only if Wi-Fi is enabled.
    166         // Here we use the state of the switch as an optimization.
    167         if (state != null && mSwitch.isChecked()) {
    168             WifiInfo info = mWifiManager.getConnectionInfo();
    169             if (info != null) {
    170                 //setSummary(Summary.get(mContext, info.getSSID(), state));
    171             }
    172         }
    173         */
    174     }
    175 }
    176