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