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.view.View; 31import android.widget.Button; 32import android.widget.ProgressBar; 33import android.widget.TextView; 34 35import com.android.settings.R; 36 37import java.util.Timer; 38import java.util.TimerTask; 39 40 41/** 42 * Dialog to show WPS progress. 43 */ 44public 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 } 154 } 155 156 @Override 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 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 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 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 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