• 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.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 
WifiEnabler(Context context, Switch switch_)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 
resume()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 
pause()85     public void pause() {
86         mContext.unregisterReceiver(mReceiver);
87         mSwitch.setOnCheckedChangeListener(null);
88     }
89 
setSwitch(Switch switch_)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 
onCheckedChanged(CompoundButton buttonView, boolean isChecked)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         }
114 
115         // Disable tethering if enabling Wifi
116         int wifiApState = mWifiManager.getWifiApState();
117         if (isChecked && ((wifiApState == WifiManager.WIFI_AP_STATE_ENABLING) ||
118                 (wifiApState == WifiManager.WIFI_AP_STATE_ENABLED))) {
119             mWifiManager.setWifiApEnabled(null, false);
120         }
121 
122         if (mWifiManager.setWifiEnabled(isChecked)) {
123             // Intent has been taken into account, disable until new state is active
124             mSwitch.setEnabled(false);
125         } else {
126             // Error
127             Toast.makeText(mContext, R.string.wifi_error, Toast.LENGTH_SHORT).show();
128         }
129     }
130 
handleWifiStateChanged(int state)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 
setSwitchChecked(boolean checked)154     private void setSwitchChecked(boolean checked) {
155         if (checked != mSwitch.isChecked()) {
156             mStateMachineEvent = true;
157             mSwitch.setChecked(checked);
158             mStateMachineEvent = false;
159         }
160     }
161 
handleStateChanged(@uppressWarnings"unused") NetworkInfo.DetailedState state)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