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 java.util.Timer;
36 import java.util.TimerTask;
37 
38 import com.android.settings.R;
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         super.onCreate(savedInstanceState);
183     }
184 
185     @Override
onStart()186     protected void onStart() {
187         /*
188          * increment timeout bar per second.
189          */
190         mTimer = new Timer(false);
191         mTimer.schedule(new TimerTask() {
192             @Override
193             public void run() {
194                 mHandler.post(new Runnable() {
195 
196                     @Override
197                     public void run() {
198                         mTimeoutBar.incrementProgressBy(1);
199                     }
200                 });
201             }
202         }, 1000, 1000);
203 
204         mContext.registerReceiver(mReceiver, mFilter);
205 
206         WpsInfo wpsConfig = new WpsInfo();
207         wpsConfig.setup = mWpsSetup;
208         mWifiManager.startWps(wpsConfig, mWpsListener);
209     }
210 
211     @Override
onStop()212     protected void onStop() {
213         if (mDialogState != DialogState.WPS_COMPLETE) {
214             mWifiManager.cancelWps(null);
215         }
216 
217         if (mReceiver != null) {
218             mContext.unregisterReceiver(mReceiver);
219             mReceiver = null;
220         }
221 
222         if (mTimer != null) {
223             mTimer.cancel();
224         }
225     }
226 
updateDialog(final DialogState state, final String msg)227     private void updateDialog(final DialogState state, final String msg) {
228         if (mDialogState.ordinal() >= state.ordinal()) {
229             //ignore.
230             return;
231         }
232         mDialogState = state;
233         mMsgString = msg;
234 
235         mHandler.post(new Runnable() {
236                 @Override
237                 public void run() {
238                     switch(state) {
239                         case WPS_COMPLETE:
240                             mTimeoutBar.setVisibility(View.GONE);
241                             mProgressBar.setVisibility(View.VISIBLE);
242                             break;
243                         case CONNECTED:
244                         case WPS_FAILED:
245                             mButton.setText(mContext.getString(R.string.dlg_ok));
246                             mTimeoutBar.setVisibility(View.GONE);
247                             mProgressBar.setVisibility(View.GONE);
248                             if (mReceiver != null) {
249                                 mContext.unregisterReceiver(mReceiver);
250                                 mReceiver = null;
251                             }
252                             break;
253                     }
254                     mTextView.setText(msg);
255                 }
256             });
257    }
258 
handleEvent(Context context, Intent intent)259     private void handleEvent(Context context, Intent intent) {
260         String action = intent.getAction();
261         if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {
262             NetworkInfo info = (NetworkInfo) intent.getParcelableExtra(
263                     WifiManager.EXTRA_NETWORK_INFO);
264             final NetworkInfo.DetailedState state = info.getDetailedState();
265             if (state == DetailedState.CONNECTED &&
266                     mDialogState == DialogState.WPS_COMPLETE) {
267                 WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
268                 if (wifiInfo != null) {
269                     String msg = String.format(mContext.getString(
270                             R.string.wifi_wps_connected), wifiInfo.getSSID());
271                     updateDialog(DialogState.CONNECTED, msg);
272                 }
273             }
274         }
275     }
276 
277 }
278