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 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 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 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 if (dialogState == DialogState.WPS_START) { 154 startWps(); 155 } 156 } 157 } 158 159 @Override 160 protected void onCreate(Bundle savedInstanceState) { 161 mView = getLayoutInflater().inflate(R.layout.wifi_wps_dialog, null); 162 163 mTextView = (TextView) mView.findViewById(R.id.wps_dialog_txt); 164 mTextView.setText(R.string.wifi_wps_setup_msg); 165 166 mTimeoutBar = ((ProgressBar) mView.findViewById(R.id.wps_timeout_bar)); 167 mTimeoutBar.setMax(WPS_TIMEOUT_S); 168 mTimeoutBar.setProgress(0); 169 170 mProgressBar = ((ProgressBar) mView.findViewById(R.id.wps_progress_bar)); 171 mProgressBar.setVisibility(View.GONE); 172 173 mButton = ((Button) mView.findViewById(R.id.wps_dialog_btn)); 174 mButton.setText(R.string.wifi_cancel); 175 mButton.setOnClickListener(new View.OnClickListener() { 176 @Override 177 public void onClick(View v) { 178 dismiss(); 179 } 180 }); 181 182 mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); 183 184 setView(mView); 185 if (savedInstanceState == null) { 186 startWps(); 187 } 188 super.onCreate(savedInstanceState); 189 } 190 191 @Override 192 protected void onStart() { 193 /* 194 * increment timeout bar per second. 195 */ 196 mTimer = new Timer(false); 197 mTimer.schedule(new TimerTask() { 198 @Override 199 public void run() { 200 mHandler.post(new Runnable() { 201 202 @Override 203 public void run() { 204 mTimeoutBar.incrementProgressBy(1); 205 } 206 }); 207 } 208 }, 1000, 1000); 209 210 mContext.registerReceiver(mReceiver, mFilter); 211 212 } 213 214 @Override 215 protected void onStop() { 216 if (mDialogState != DialogState.WPS_COMPLETE) { 217 mWifiManager.cancelWps(null); 218 } 219 220 if (mReceiver != null) { 221 mContext.unregisterReceiver(mReceiver); 222 mReceiver = null; 223 } 224 225 if (mTimer != null) { 226 mTimer.cancel(); 227 } 228 } 229 230 private void updateDialog(final DialogState state, final String msg) { 231 if (mDialogState.ordinal() >= state.ordinal()) { 232 //ignore. 233 return; 234 } 235 mDialogState = state; 236 mMsgString = msg; 237 238 mHandler.post(new Runnable() { 239 @Override 240 public void run() { 241 switch(state) { 242 case WPS_COMPLETE: 243 mTimeoutBar.setVisibility(View.GONE); 244 mProgressBar.setVisibility(View.VISIBLE); 245 break; 246 case CONNECTED: 247 case WPS_FAILED: 248 mButton.setText(mContext.getString(R.string.dlg_ok)); 249 mTimeoutBar.setVisibility(View.GONE); 250 mProgressBar.setVisibility(View.GONE); 251 if (mReceiver != null) { 252 mContext.unregisterReceiver(mReceiver); 253 mReceiver = null; 254 } 255 break; 256 } 257 mTextView.setText(msg); 258 } 259 }); 260 } 261 262 private void handleEvent(Context context, Intent intent) { 263 String action = intent.getAction(); 264 if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) { 265 NetworkInfo info = (NetworkInfo) intent.getParcelableExtra( 266 WifiManager.EXTRA_NETWORK_INFO); 267 final NetworkInfo.DetailedState state = info.getDetailedState(); 268 if (state == DetailedState.CONNECTED && 269 mDialogState == DialogState.WPS_COMPLETE) { 270 WifiInfo wifiInfo = mWifiManager.getConnectionInfo(); 271 if (wifiInfo != null) { 272 String msg = String.format(mContext.getString( 273 R.string.wifi_wps_connected), wifiInfo.getSSID()); 274 updateDialog(DialogState.CONNECTED, msg); 275 } 276 } 277 } 278 } 279 280 private void startWps() { 281 WpsInfo wpsConfig = new WpsInfo(); 282 wpsConfig.setup = mWpsSetup; 283 mWifiManager.startWps(wpsConfig, mWpsListener); 284 } 285 } 286