Home | History | Annotate | Download | only in wifi
      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