1 /*
2  * Copyright (C) 2012 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 package com.android.settings.wifi;
17 
18 import android.app.AlertDialog;
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.NetworkInfo.DetailedState;
25 import android.net.wifi.WifiInfo;
26 import android.net.wifi.WifiManager;
27 import android.net.wifi.WpsInfo;
28 import android.os.Bundle;
29 import android.os.Handler;
30 import android.view.View;
31 import android.widget.Button;
32 import android.widget.ProgressBar;
33 import android.widget.TextView;
34 
35 import com.android.settings.R;
36 
37 import java.util.Timer;
38 import java.util.TimerTask;
39 
40 
41 /**
42  * Dialog to show WPS progress.
43  */
44 public class WpsDialog extends AlertDialog {
45 
46     private final static String TAG = "WpsDialog";
47     private static final String DIALOG_STATE = "android:dialogState";
48     private static final String DIALOG_MSG_STRING = "android:dialogMsg";
49 
50     private View mView;
51     private TextView mTextView;
52     private ProgressBar mTimeoutBar;
53     private ProgressBar mProgressBar;
54     private Button mButton;
55     private Timer mTimer;
56 
57     private static final int WPS_TIMEOUT_S = 120;
58 
59     private WifiManager mWifiManager;
60     private WifiManager.WpsCallback mWpsListener;
61     private int mWpsSetup;
62 
63     private final IntentFilter mFilter;
64     private BroadcastReceiver mReceiver;
65 
66     private Context mContext;
67     private Handler mHandler = new Handler();
68     private String mMsgString = "";
69 
70     private enum DialogState {
71         WPS_INIT,
72         WPS_START,
73         WPS_COMPLETE,
74         CONNECTED, //WPS + IP config is done
75         WPS_FAILED
76     }
77     DialogState mDialogState = DialogState.WPS_INIT;
78 
WpsDialog(Context context, int wpsSetup)79     public WpsDialog(Context context, int wpsSetup) {
80         super(context);
81         mContext = context;
82         mWpsSetup = wpsSetup;
83 
84         class WpsListener extends WifiManager.WpsCallback {
85 
86             public void onStarted(String pin) {
87                 if (pin != null) {
88                     updateDialog(DialogState.WPS_START, String.format(
89                             mContext.getString(R.string.wifi_wps_onstart_pin), pin));
90                 } else {
91                     updateDialog(DialogState.WPS_START, mContext.getString(
92                             R.string.wifi_wps_onstart_pbc));
93                 }
94             }
95 
96             public void onSucceeded() {
97                 updateDialog(DialogState.WPS_COMPLETE,
98                         mContext.getString(R.string.wifi_wps_complete));
99             }
100 
101             public void onFailed(int reason) {
102                 String msg;
103                 switch (reason) {
104                     case WifiManager.WPS_OVERLAP_ERROR:
105                         msg = mContext.getString(R.string.wifi_wps_failed_overlap);
106                         break;
107                     case WifiManager.WPS_WEP_PROHIBITED:
108                         msg = mContext.getString(R.string.wifi_wps_failed_wep);
109                         break;
110                     case WifiManager.WPS_TKIP_ONLY_PROHIBITED:
111                         msg = mContext.getString(R.string.wifi_wps_failed_tkip);
112                         break;
113                     case WifiManager.IN_PROGRESS:
114                         msg = mContext.getString(R.string.wifi_wps_in_progress);
115                         break;
116                     default:
117                         msg = mContext.getString(R.string.wifi_wps_failed_generic);
118                         break;
119                 }
120                 updateDialog(DialogState.WPS_FAILED, msg);
121             }
122         }
123 
124         mWpsListener = new WpsListener();
125 
126 
127         mFilter = new IntentFilter();
128         mFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
129         mReceiver = new BroadcastReceiver() {
130             @Override
131             public void onReceive(Context context, Intent intent) {
132                 handleEvent(context, intent);
133             }
134         };
135         setCanceledOnTouchOutside(false);
136     }
137 
138     @Override
onSaveInstanceState()139     public Bundle onSaveInstanceState () {
140         Bundle bundle  = super.onSaveInstanceState();
141         bundle.putString(DIALOG_STATE, mDialogState.toString());
142         bundle.putString(DIALOG_MSG_STRING, mMsgString.toString());
143         return bundle;
144     }
145 
146     @Override
onRestoreInstanceState(Bundle savedInstanceState)147     public void onRestoreInstanceState(Bundle savedInstanceState) {
148         if (savedInstanceState != null) {
149             super.onRestoreInstanceState(savedInstanceState);
150             DialogState dialogState = mDialogState.valueOf(savedInstanceState.getString(DIALOG_STATE));
151             String msg = savedInstanceState.getString(DIALOG_MSG_STRING);
152             updateDialog(dialogState, msg);
153         }
154     }
155 
156     @Override
onCreate(Bundle savedInstanceState)157     protected void onCreate(Bundle savedInstanceState) {
158         mView = getLayoutInflater().inflate(R.layout.wifi_wps_dialog, null);
159 
160         mTextView = (TextView) mView.findViewById(R.id.wps_dialog_txt);
161         mTextView.setText(R.string.wifi_wps_setup_msg);
162 
163         mTimeoutBar = ((ProgressBar) mView.findViewById(R.id.wps_timeout_bar));
164         mTimeoutBar.setMax(WPS_TIMEOUT_S);
165         mTimeoutBar.setProgress(0);
166 
167         mProgressBar = ((ProgressBar) mView.findViewById(R.id.wps_progress_bar));
168         mProgressBar.setVisibility(View.GONE);
169 
170         mButton = ((Button) mView.findViewById(R.id.wps_dialog_btn));
171         mButton.setText(R.string.wifi_cancel);
172         mButton.setOnClickListener(new View.OnClickListener() {
173             @Override
174             public void onClick(View v) {
175                 dismiss();
176             }
177         });
178 
179         mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
180 
181         setView(mView);
182         if (savedInstanceState == null) {
183             WpsInfo wpsConfig = new WpsInfo();
184             wpsConfig.setup = mWpsSetup;
185             mWifiManager.startWps(wpsConfig, mWpsListener);
186         }
187         super.onCreate(savedInstanceState);
188     }
189 
190     @Override
onStart()191     protected void onStart() {
192         /*
193          * increment timeout bar per second.
194          */
195         mTimer = new Timer(false);
196         mTimer.schedule(new TimerTask() {
197             @Override
198             public void run() {
199                 mHandler.post(new Runnable() {
200 
201                     @Override
202                     public void run() {
203                         mTimeoutBar.incrementProgressBy(1);
204                     }
205                 });
206             }
207         }, 1000, 1000);
208 
209         mContext.registerReceiver(mReceiver, mFilter);
210 
211     }
212 
213     @Override
onStop()214     protected void onStop() {
215         if (mDialogState != DialogState.WPS_COMPLETE) {
216             mWifiManager.cancelWps(null);
217         }
218 
219         if (mReceiver != null) {
220             mContext.unregisterReceiver(mReceiver);
221             mReceiver = null;
222         }
223 
224         if (mTimer != null) {
225             mTimer.cancel();
226         }
227     }
228 
updateDialog(final DialogState state, final String msg)229     private void updateDialog(final DialogState state, final String msg) {
230         if (mDialogState.ordinal() >= state.ordinal()) {
231             //ignore.
232             return;
233         }
234         mDialogState = state;
235         mMsgString = msg;
236 
237         mHandler.post(new Runnable() {
238                 @Override
239                 public void run() {
240                     switch(state) {
241                         case WPS_COMPLETE:
242                             mTimeoutBar.setVisibility(View.GONE);
243                             mProgressBar.setVisibility(View.VISIBLE);
244                             break;
245                         case CONNECTED:
246                         case WPS_FAILED:
247                             mButton.setText(mContext.getString(R.string.dlg_ok));
248                             mTimeoutBar.setVisibility(View.GONE);
249                             mProgressBar.setVisibility(View.GONE);
250                             if (mReceiver != null) {
251                                 mContext.unregisterReceiver(mReceiver);
252                                 mReceiver = null;
253                             }
254                             break;
255                     }
256                     mTextView.setText(msg);
257                 }
258             });
259    }
260 
handleEvent(Context context, Intent intent)261     private void handleEvent(Context context, Intent intent) {
262         String action = intent.getAction();
263         if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {
264             NetworkInfo info = (NetworkInfo) intent.getParcelableExtra(
265                     WifiManager.EXTRA_NETWORK_INFO);
266             final NetworkInfo.DetailedState state = info.getDetailedState();
267             if (state == DetailedState.CONNECTED &&
268                     mDialogState == DialogState.WPS_COMPLETE) {
269                 WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
270                 if (wifiInfo != null) {
271                     String msg = String.format(mContext.getString(
272                             R.string.wifi_wps_connected), wifiInfo.getSSID());
273                     updateDialog(DialogState.CONNECTED, msg);
274                 }
275             }
276         }
277     }
278 
279 }
280