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