• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
WifiEnabler(Context context, Switch switch_)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 
resume()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 
pause()83     public void pause() {
84         mContext.unregisterReceiver(mReceiver);
85         mSwitch.setOnCheckedChangeListener(null);
86     }
87 
setSwitch(Switch switch_)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 
onCheckedChanged(CompoundButton buttonView, boolean isChecked)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 
handleWifiStateChanged(int state)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 
setSwitchChecked(boolean checked)152     private void setSwitchChecked(boolean checked) {
153         if (checked != mSwitch.isChecked()) {
154             mStateMachineEvent = true;
155             mSwitch.setChecked(checked);
156             mStateMachineEvent = false;
157         }
158     }
159 
handleStateChanged(@uppressWarnings"unused") NetworkInfo.DetailedState state)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