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