OSDN Git Service

Enhance and fix WPS UI
authorIrfan Sheriff <isheriff@google.com>
Tue, 28 Feb 2012 00:20:29 +0000 (16:20 -0800)
committerIrfan Sheriff <isheriff@google.com>
Fri, 2 Mar 2012 22:25:00 +0000 (14:25 -0800)
- Fixes WPS usage for open network
- Exposes WPS on UI for easy access to push button and pin based techniques
- Adds support for cancelling WPS
- Adds a dialog that reports a progress since WPS can take quite a bit of time
to complete

The WpsDialog code is enhanced from contribution by yoshihiko.ikenaga@jp.sony.com
on partner source.

Change-Id: Ib0103507e0192e8195e7bfeb1c8e8855c20e23ca

res/layout/wifi_dialog.xml
res/layout/wifi_wps_dialog.xml [new file with mode: 0644]
res/values/arrays.xml
res/values/strings.xml
src/com/android/settings/wifi/WifiConfigController.java
src/com/android/settings/wifi/WifiSettings.java
src/com/android/settings/wifi/WpsDialog.java [new file with mode: 0644]

index f06c332..0e6d63a 100644 (file)
                     android:layout_height="wrap_content"
                     android:orientation="vertical"
                     android:visibility="gone">
-            <LinearLayout android:id="@+id/setup_fields"
-                    style="@style/wifi_item"
-                    android:visibility="gone">
-
-                <TextView
-                        style="@style/wifi_item_label"
-                        android:text="@string/wifi_network_setup" />
-
-                <Spinner android:id="@+id/network_setup"
-                        style="@style/wifi_item_content"
-                        android:prompt="@string/wifi_network_setup"
-                        android:entries="@array/wifi_network_setup" />
-
-            </LinearLayout>
-
-            <LinearLayout android:id="@+id/wps_fields"
-                    style="@style/wifi_item"
-                    android:visibility="gone">
-
-                <TextView
-                        style="@style/wifi_item_label"
-                        android:text="@string/wifi_wps_pin" />
-
-                <EditText android:id="@+id/wps_pin"
-                        style="@style/wifi_item_content"
-                        android:singleLine="true"
-                        android:inputType="textPassword" />
-
-            </LinearLayout>
 
             <LinearLayout android:id="@+id/proxy_settings_fields"
                     style="@style/wifi_item"
diff --git a/res/layout/wifi_wps_dialog.xml b/res/layout/wifi_wps_dialog.xml
new file mode 100644 (file)
index 0000000..3594436
--- /dev/null
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+         android:layout_width="300sp"
+         android:layout_height="wrap_content">
+
+    <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:padding="8dip"
+            android:orientation="vertical">
+
+        <TextView
+                android:id="@+id/wps_dialog_txt"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="8dip" />
+
+        <ProgressBar
+                android:id="@+id/wps_timeout_bar"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="20dip"
+                style="?android:attr/progressBarStyleHorizontal" />
+
+        <ProgressBar
+                android:id="@+id/wps_progress_bar"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="20dip"
+                style="?android:attr/progressBarStyle" />
+
+        <RelativeLayout
+                android:gravity="center"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content">
+
+            <Button
+                    android:id="@+id/wps_dialog_btn"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/cancel" />
+        </RelativeLayout>
+    </LinearLayout>
+</ScrollView>
index e89c00c..c9bbd04 100644 (file)
         <item>GTC</item>
     </string-array>
 
-    <!-- Wi-Fi set up options -->
-    <!-- Note that adding/removing/moving items will need wifi settings code change. -->
-    <string-array name="wifi_network_setup">
-        <!-- Manual wifi configuration [CHAR LIMIT=25]-->
-        <item>Off</item>
-        <!-- WPS is a new standard that allowes secure connection establishment to a home wireless network using a simplified process. WPS push button based configuration involves pushing a button on the router and the device [CHAR LIMIT=25]-->
-        <item>Push button</item>
-        <!-- WPS pin method based configuration. This requires entering a pin obtained from the access point [CHAR LIMIT=25] -->
-        <item>PIN from access point</item>
-        <!-- WPS pin method based configuration. This requires generating a pin from this device [CHAR LIMIT=25] -->
-        <item>PIN from this device</item>
-    </string-array>
-
     <!-- Wi-Fi IP settings. -->
    <!-- Note that adding/removing/moving the items will need wifi settings code change. -->
     <string-array name="wifi_ip_settings">
index b65339f..544ecf8 100644 (file)
     <string name="wifi_add_network">Add network</string>
     <!-- Header for the list of wifi networks-->
     <string name="wifi_access_points">Wi-Fi networks</string>
+    <!-- Menu option to do WPS Push Button [CHAR LIMIT=20]-->
+    <string name="wifi_menu_wps_pbc">WPS Push Button</string>
+    <!-- Menu option to do WPS Pin Entry [CHAR LIMIT=20]-->
+    <string name="wifi_menu_wps_pin">WPS Pin Entry</string>
     <!-- Menu option to scan Wi-Fi networks -->
     <string name="wifi_menu_scan">Scan</string>
     <!-- Menu option to Wi-Fi advanced settings -->
     <!-- Dialog for Access Points --> <skip />
     <!-- Label to show/hide advanced options -->
     <string name="wifi_show_advanced">Show advanced options</string>
-    <!-- Label for network setup [CHAR LIMIT=50] -->
-    <string name="wifi_network_setup">WPS</string>
-    <!-- Label for the text view for WPS pin input [CHAR LIMIT=50] -->
-    <string name="wifi_wps_pin">Type PIN from access point</string>
     <!-- Title for the WPS setup dialog [CHAR LIMIT=50] -->
-    <string name="wifi_wps_setup_title">WPS setup</string>
-    <!-- Text displayed in the WPS pin display dialog [CHAR LIMIT=75] -->
-    <string name="wifi_wps_pin_output">Type the PIN <xliff:g id="wps_pin">%1$s</xliff:g> on the access point</string>
-    <!-- Text displayed when WPS setup is in progress [CHAR LIMIT=75] -->
-    <string name="wifi_wps_in_progress">WPS is already in progress and can take tens of seconds to complete</string>
-    <!-- Text displayed when WPS fails to start [CHAR LIMIT=75] -->
-    <string name="wifi_wps_failed">Couldn\'t start WPS. Try again.</string>
+    <string name="wifi_wps_setup_title">Wi-Fi Protected Setup</string>
+    <!-- Message in WPS dialog at start up [CHAR LIMIT=150] -->
+    <string name="wifi_wps_setup_msg">Starting WPS\u2026</string>
+    <!-- Message in WPS dialog for PBC after start up [CHAR LIMIT=150] -->
+    <string name="wifi_wps_onstart_pbc">Push the WPS button on your Wi-Fi router. The setup can take upto two minutes to complete.</string>
+    <!-- Message in WPS dialog for PIN after start up [CHAR LIMIT=150] -->
+    <string name="wifi_wps_onstart_pin">Enter pin <xliff:g id="pin">%1$s</xliff:g> on your Wi-Fi router. The setup can take upto two minutes to complete.</string>
+    <!-- Text displayed when WPS succeeds [CHAR LIMIT=150] -->
+    <string name="wifi_wps_complete">WPS succeeded. Connecting to the network\u2026</string>
+    <!-- Text displayed when Wi-Fi is connected through WPS [CHAR LIMIT=150] -->
+    <string name="wifi_wps_connected">Connected to Wi-Fi network <xliff:g id="network_name">%s</xliff:g></string>
+    <!-- Text displayed when WPS setup is in progress [CHAR LIMIT=150] -->
+    <string name="wifi_wps_in_progress">WPS is already in progress and can take upto two minutes to complete</string>
+    <!-- Text displayed when WPS fails to start [CHAR LIMIT=150] -->
+    <string name="wifi_wps_failed_generic">WPS failed. Please try again in a few minutes.</string>
+    <!-- Text displayed when WPS fails due to WEP [CHAR LIMIT=150] -->
+    <string name="wifi_wps_failed_wep">The wireless router security setting (WEP) is not supported</string>
+     <!-- Text displayed when WPS fails to TKIP [CHAR LIMIT=150] -->
+    <string name="wifi_wps_failed_tkip">The wireless router security setting (TKIP) is not supported</string>
+     <!-- Text displayed when WPS fails due to authentication issues [CHAR LIMIT=150] -->
+    <string name="wifi_wps_failed_auth">Authentication failure. Please try again.</string>
+     <!-- Text displayed when WPS fails due to another session [CHAR LIMIT=150] -->
+    <string name="wifi_wps_failed_overlap">Another WPS session was detected. Please try again in a few minutes.</string>
     <!-- Label for the SSID of the network -->
     <string name="wifi_ssid">Network SSID</string>
     <!-- Label for the security of the connection -->
     <!-- Summary for the remembered network but currently not in range. -->
     <string name="wifi_not_in_range">Not in range</string>
     <!-- Substring of status line when Wi-Fi Protected Setup (WPS) is available and
-         string is listed first -->
-    <string name="wifi_wps_available_first_item">Protected network available</string>
+         string is listed first [CHAR LIMIT=20]-->
+    <string name="wifi_wps_available_first_item">WPS available</string>
     <!-- Substring of wifi status when Wi-Fi Protected Setup (WPS) is available and
          string is listed after a wifi_secured_* string-->
     <string name="wifi_wps_available_second_item">\u0020(protected network available)</string>
     <!-- Button label to dismiss the dialog -->
     <string name="wifi_cancel">Cancel</string>
 
-    <!-- Errors reported on wifi settings page -->
-    <!-- Toast message indicating WPS overlap detection [CHAR LIMIT=75] -->
-    <string name="wifi_wps_overlap_error">Another Wi-Fi protected session was detected. Try again in a few minutes.</string>
-
     <!-- Wi-Fi Advanced Settings --> <skip />
     <!-- Wi-Fi settings screen, advanced, settings section.  This is a header shown above advanced wifi settings. -->
     <string name="wifi_advanced_titlebar">Advanced Wi-Fi</string>
index 76a9a45..8962b90 100644 (file)
@@ -33,7 +33,6 @@ import android.net.wifi.WifiConfiguration.KeyMgmt;
 import android.net.wifi.WifiConfiguration.ProxySettings;
 import android.net.wifi.WifiConfiguration.Status;
 import android.net.wifi.WifiInfo;
-import android.net.wifi.WpsInfo;
 import android.security.Credentials;
 import android.security.KeyStore;
 import android.text.Editable;
@@ -88,12 +87,6 @@ public class WifiConfigController implements TextWatcher,
     private static final int DHCP = 0;
     private static final int STATIC_IP = 1;
 
-    /* These values come from "wifi_network_setup" resource array */
-    public static final int MANUAL = 0;
-    public static final int WPS_PBC = 1;
-    public static final int WPS_KEYPAD = 2;
-    public static final int WPS_DISPLAY = 3;
-
     /* These values come from "wifi_proxy_settings" resource array */
     public static final int PROXY_NONE = 0;
     public static final int PROXY_STATIC = 1;
@@ -106,7 +99,6 @@ public class WifiConfigController implements TextWatcher,
 
     private static final String TAG = "WifiConfigController";
 
-    private Spinner mNetworkSetupSpinner;
     private Spinner mIpSettingsSpinner;
     private TextView mIpAddressView;
     private TextView mGatewayView;
@@ -232,11 +224,6 @@ public class WifiConfigController implements TextWatcher,
 
             }
 
-            /* Show network setup options only for a new network */
-            if (mAccessPoint.networkId == INVALID_NETWORK_ID && mAccessPoint.wpsAvailable) {
-                showNetworkSetupFields();
-            }
-
             if (mAccessPoint.networkId == INVALID_NETWORK_ID || mEdit) {
                 showSecurityFields();
                 showIpConfigFields();
@@ -286,10 +273,8 @@ public class WifiConfigController implements TextWatcher,
         boolean enabled = false;
         boolean passwordInvalid = false;
 
-        /* Check password invalidity for manual network set up alone */
-        if (chosenNetworkSetupMethod() == MANUAL &&
-            ((mAccessPointSecurity == AccessPoint.SECURITY_WEP && mPasswordView.length() == 0) ||
-            (mAccessPointSecurity == AccessPoint.SECURITY_PSK && mPasswordView.length() < 8))) {
+        if ((mAccessPointSecurity == AccessPoint.SECURITY_WEP && mPasswordView.length() == 0) ||
+            (mAccessPointSecurity == AccessPoint.SECURITY_PSK && mPasswordView.length() < 8)) {
             passwordInvalid = true;
         }
 
@@ -484,35 +469,6 @@ public class WifiConfigController implements TextWatcher,
         return 0;
     }
 
-    int chosenNetworkSetupMethod() {
-        if (mNetworkSetupSpinner != null) {
-            return mNetworkSetupSpinner.getSelectedItemPosition();
-        }
-        return MANUAL;
-    }
-
-    WpsInfo getWpsConfig() {
-        WpsInfo config = new WpsInfo();
-        switch (mNetworkSetupSpinner.getSelectedItemPosition()) {
-            case WPS_PBC:
-                config.setup = WpsInfo.PBC;
-                break;
-            case WPS_KEYPAD:
-                config.setup = WpsInfo.KEYPAD;
-                break;
-            case WPS_DISPLAY:
-                config.setup = WpsInfo.DISPLAY;
-                break;
-            default:
-                config.setup = WpsInfo.INVALID;
-                Log.e(TAG, "WPS not selected type");
-                return config;
-        }
-        config.pin = ((TextView) mView.findViewById(R.id.wps_pin)).getText().toString();
-        config.BSSID = (mAccessPoint != null) ? mAccessPoint.bssid : null;
-        return config;
-    }
-
     private void showSecurityFields() {
         if (mInXlSetupWizard) {
             // Note: XL SetupWizard won't hide "EAP" settings here.
@@ -583,33 +539,6 @@ public class WifiConfigController implements TextWatcher,
             mView.findViewById(R.id.l_anonymous).setVisibility(View.VISIBLE);
         }
     }
-    
-    private void showNetworkSetupFields() {
-        mView.findViewById(R.id.setup_fields).setVisibility(View.VISIBLE);
-
-        if (mNetworkSetupSpinner == null) {
-            mNetworkSetupSpinner = (Spinner) mView.findViewById(R.id.network_setup);
-            mNetworkSetupSpinner.setOnItemSelectedListener(this);
-        }
-
-        int pos = mNetworkSetupSpinner.getSelectedItemPosition();
-
-        /* Show pin text input if needed */
-        if (pos == WPS_KEYPAD) {
-            mView.findViewById(R.id.wps_fields).setVisibility(View.VISIBLE);
-        } else {
-            mView.findViewById(R.id.wps_fields).setVisibility(View.GONE);
-        }
-
-        /* show/hide manual security fields appropriately */
-        if ((pos == WPS_DISPLAY) || (pos == WPS_KEYPAD)
-                || (pos == WPS_PBC)) {
-            mView.findViewById(R.id.security_fields).setVisibility(View.GONE);
-        } else {
-            mView.findViewById(R.id.security_fields).setVisibility(View.VISIBLE);
-        }
-
-    }
 
     private void showIpConfigFields() {
         WifiConfiguration config = null;
@@ -785,8 +714,6 @@ public class WifiConfigController implements TextWatcher,
             showSecurityFields();
         } else if (parent == mEapMethodSpinner) {
             showSecurityFields();
-        } else if (parent == mNetworkSetupSpinner) {
-            showNetworkSetupFields();
         } else if (parent == mProxySettingsSpinner) {
             showProxyFields();
         } else {
index 306ce33..164434c 100644 (file)
@@ -36,7 +36,7 @@ import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiConfiguration.KeyMgmt;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
-import android.net.wifi.WpsResult;
+import android.net.wifi.WpsInfo;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
@@ -82,14 +82,18 @@ import java.util.concurrent.atomic.AtomicBoolean;
 public class WifiSettings extends SettingsPreferenceFragment
         implements DialogInterface.OnClickListener  {
     private static final String TAG = "WifiSettings";
-    private static final int MENU_ID_SCAN = Menu.FIRST;
-    private static final int MENU_ID_ADD_NETWORK = Menu.FIRST + 1;
-    private static final int MENU_ID_ADVANCED = Menu.FIRST + 2;
-    private static final int MENU_ID_CONNECT = Menu.FIRST + 3;
-    private static final int MENU_ID_FORGET = Menu.FIRST + 4;
-    private static final int MENU_ID_MODIFY = Menu.FIRST + 5;
+    private static final int MENU_ID_WPS_PBC = Menu.FIRST;
+    private static final int MENU_ID_WPS_PIN = Menu.FIRST + 1;
+    private static final int MENU_ID_ADD_NETWORK = Menu.FIRST + 2;
+    private static final int MENU_ID_ADVANCED = Menu.FIRST + 3;
+    private static final int MENU_ID_SCAN = Menu.FIRST + 4;
+    private static final int MENU_ID_CONNECT = Menu.FIRST + 5;
+    private static final int MENU_ID_FORGET = Menu.FIRST + 6;
+    private static final int MENU_ID_MODIFY = Menu.FIRST + 7;
 
     private static final int WIFI_DIALOG_ID = 1;
+    private static final int WPS_PBC_DIALOG_ID = 2;
+    private static final int WPS_PIN_DIALOG_ID = 3;
 
     // Combo scans can take 5-6s to complete - set to 10s.
     private static final int WIFI_RESCAN_INTERVAL_MS = 10 * 1000;
@@ -107,7 +111,7 @@ public class WifiSettings extends SettingsPreferenceFragment
     private WifiManager.ActionListener mConnectListener;
     private WifiManager.ActionListener mSaveListener;
     private WifiManager.ActionListener mForgetListener;
-    private WifiManager.WpsListener mWpsListener;
+
 
     private WifiEnabler mWifiEnabler;
     // An access point being editted is stored here.
@@ -207,44 +211,6 @@ public class WifiSettings extends SettingsPreferenceFragment
                                    }
                                };
 
-        class WpsListener implements WifiManager.WpsListener {
-            public void onStartSuccess(String pin) {
-                //TODO: Add progress bar instead
-                if (pin != null) {
-                    AlertDialog.Builder dialog = new AlertDialog.Builder(getActivity())
-                        .setTitle(R.string.wifi_wps_setup_title)
-                        .setPositiveButton(android.R.string.ok, null);
-                    dialog.setMessage(getResources().getString(
-                                R.string.wifi_wps_pin_output, pin));
-                    dialog.show();
-                }
-            }
-            public void onCompletion() {
-                //TODO: Dismiss progress bar
-            }
-            public void onFailure(int reason) {
-                AlertDialog.Builder dialog = new AlertDialog.Builder(getActivity())
-                    .setTitle(R.string.wifi_wps_setup_title)
-                    .setPositiveButton(android.R.string.ok, null);
-                switch (reason) {
-                    case WifiManager.IN_PROGRESS:
-                        dialog.setMessage(R.string.wifi_wps_in_progress);
-                        dialog.show();
-                        break;
-                    case WifiManager.WPS_OVERLAP_ERROR:
-                        Toast.makeText(getActivity(), R.string.wifi_wps_overlap_error,
-                                Toast.LENGTH_SHORT).show();
-                        break;
-                    default:
-                        dialog.setMessage(R.string.wifi_wps_failed);
-                        dialog.show();
-                        break;
-                }
-            }
-        }
-
-       mWpsListener = new WpsListener();
-
         if (savedInstanceState != null
                 && savedInstanceState.containsKey(SAVE_DIALOG_ACCESS_POINT_STATE)) {
             mDlgEdit = savedInstanceState.getBoolean(SAVE_DIALOG_EDIT_MODE);
@@ -337,17 +303,23 @@ public class WifiSettings extends SettingsPreferenceFragment
         // We don't want menus in Setup Wizard XL.
         if (!mInXlSetupWizard) {
             final boolean wifiIsEnabled = mWifiManager.isWifiEnabled();
-            menu.add(Menu.NONE, MENU_ID_SCAN, 0, R.string.wifi_menu_scan)
-                    //.setIcon(R.drawable.ic_menu_scan_network)
+            menu.add(Menu.NONE, MENU_ID_WPS_PBC, 0, R.string.wifi_menu_wps_pbc)
                     .setEnabled(wifiIsEnabled)
                     .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
             menu.add(Menu.NONE, MENU_ID_ADD_NETWORK, 0, R.string.wifi_add_network)
                     .setEnabled(wifiIsEnabled)
                     .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+            menu.add(Menu.NONE, MENU_ID_SCAN, 0, R.string.wifi_menu_scan)
+                    //.setIcon(R.drawable.ic_menu_scan_network)
+                    .setEnabled(wifiIsEnabled)
+                    .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+            menu.add(Menu.NONE, MENU_ID_WPS_PIN, 0, R.string.wifi_menu_wps_pin)
+                    .setEnabled(wifiIsEnabled)
+                    .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
             menu.add(Menu.NONE, MENU_ID_ADVANCED, 0, R.string.wifi_menu_advanced)
                     //.setIcon(android.R.drawable.ic_menu_manage)
                     .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
-        }
+       }
         super.onCreateOptionsMenu(menu, inflater);
     }
 
@@ -369,6 +341,12 @@ public class WifiSettings extends SettingsPreferenceFragment
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
+            case MENU_ID_WPS_PBC:
+                showDialog(WPS_PBC_DIALOG_ID);
+                return true;
+            case MENU_ID_WPS_PIN:
+                showDialog(WPS_PIN_DIALOG_ID);
+                return true;
             case MENU_ID_SCAN:
                 if (mWifiManager.isWifiEnabled()) {
                     mScanner.forceScan();
@@ -496,18 +474,26 @@ public class WifiSettings extends SettingsPreferenceFragment
 
     @Override
     public Dialog onCreateDialog(int dialogId) {
-        AccessPoint ap = mDlgAccessPoint; // For manual launch
-        if (ap == null) { // For re-launch from saved state
-            if (mAccessPointSavedState != null) {
-                ap = new AccessPoint(getActivity(), mAccessPointSavedState);
-                // For repeated orientation changes
-                mDlgAccessPoint = ap;
-            }
+        switch (dialogId) {
+            case WIFI_DIALOG_ID:
+                AccessPoint ap = mDlgAccessPoint; // For manual launch
+                if (ap == null) { // For re-launch from saved state
+                    if (mAccessPointSavedState != null) {
+                        ap = new AccessPoint(getActivity(), mAccessPointSavedState);
+                        // For repeated orientation changes
+                        mDlgAccessPoint = ap;
+                    }
+                }
+                // If it's still null, fine, it's for Add Network
+                mSelectedAccessPoint = ap;
+                mDialog = new WifiDialog(getActivity(), this, ap, mDlgEdit);
+                return mDialog;
+            case WPS_PBC_DIALOG_ID:
+                return new WpsDialog(getActivity(), WpsInfo.PBC);
+            case WPS_PIN_DIALOG_ID:
+                return new WpsDialog(getActivity(), WpsInfo.DISPLAY);
         }
-        // If it's still null, fine, it's for Add Network
-        mSelectedAccessPoint = ap;
-        mDialog = new WifiDialog(getActivity(), this, ap, mDlgEdit);
-        return mDialog;
+        return super.onCreateDialog(dialogId);
     }
 
     private boolean requireKeyStore(WifiConfiguration config) {
@@ -780,35 +766,26 @@ public class WifiSettings extends SettingsPreferenceFragment
     }
 
     /* package */ void submit(WifiConfigController configController) {
-        int networkSetup = configController.chosenNetworkSetupMethod();
-        switch(networkSetup) {
-            case WifiConfigController.WPS_PBC:
-            case WifiConfigController.WPS_DISPLAY:
-            case WifiConfigController.WPS_KEYPAD:
-                mWifiManager.startWps(mChannel, configController.getWpsConfig(), mWpsListener);
-                break;
-            case WifiConfigController.MANUAL:
-                final WifiConfiguration config = configController.getConfig();
 
-                if (config == null) {
-                    if (mSelectedAccessPoint != null
-                            && !requireKeyStore(mSelectedAccessPoint.getConfig())
-                            && mSelectedAccessPoint.networkId != INVALID_NETWORK_ID) {
-                        mWifiManager.connect(mChannel, mSelectedAccessPoint.networkId,
-                                mConnectListener);
-                    }
-                } else if (config.networkId != INVALID_NETWORK_ID) {
-                    if (mSelectedAccessPoint != null) {
-                        saveNetwork(config);
-                    }
-                } else {
-                    if (configController.isEdit() || requireKeyStore(config)) {
-                        saveNetwork(config);
-                    } else {
-                        mWifiManager.connect(mChannel, config, mConnectListener);
-                    }
-                }
-                break;
+        final WifiConfiguration config = configController.getConfig();
+
+        if (config == null) {
+            if (mSelectedAccessPoint != null
+                    && !requireKeyStore(mSelectedAccessPoint.getConfig())
+                    && mSelectedAccessPoint.networkId != INVALID_NETWORK_ID) {
+                mWifiManager.connect(mChannel, mSelectedAccessPoint.networkId,
+                        mConnectListener);
+            }
+        } else if (config.networkId != INVALID_NETWORK_ID) {
+            if (mSelectedAccessPoint != null) {
+                saveNetwork(config);
+            }
+        } else {
+            if (configController.isEdit() || requireKeyStore(config)) {
+                saveNetwork(config);
+            } else {
+                mWifiManager.connect(mChannel, config, mConnectListener);
+            }
         }
 
         if (mWifiManager.isWifiEnabled()) {
diff --git a/src/com/android/settings/wifi/WpsDialog.java b/src/com/android/settings/wifi/WpsDialog.java
new file mode 100644 (file)
index 0000000..6cf6867
--- /dev/null
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settings.wifi;
+
+import android.app.AlertDialog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.NetworkInfo;
+import android.net.NetworkInfo.DetailedState;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+import android.net.wifi.WpsInfo;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.view.View;
+import android.widget.Button;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import java.util.Timer;
+import java.util.TimerTask;
+
+import com.android.settings.R;
+
+
+/**
+ * Dialog to show WPS progress.
+ */
+public class WpsDialog extends AlertDialog {
+
+    private final static String TAG = "WpsDialog";
+
+    private View mView;
+    private TextView mTextView;
+    private ProgressBar mTimeoutBar;
+    private ProgressBar mProgressBar;
+    private Button mButton;
+    private Timer mTimer;
+
+    private static final int WPS_TIMEOUT_S = 120;
+
+    private WifiManager mWifiManager;
+    private WifiManager.Channel mChannel;
+    private WifiManager.WpsListener mWpsListener;
+    private int mWpsSetup;
+
+    private final IntentFilter mFilter;
+    private BroadcastReceiver mReceiver;
+
+    private Context mContext;
+    private Handler mHandler = new Handler();
+
+    private enum DialogState {
+        WPS_INIT,
+        WPS_START,
+        WPS_COMPLETE,
+        CONNECTED, //WPS + IP config is done
+        WPS_FAILED
+    }
+    DialogState mDialogState = DialogState.WPS_INIT;
+
+    public WpsDialog(Context context, int wpsSetup) {
+        super(context);
+        mContext = context;
+        mWpsSetup = wpsSetup;
+
+        class WpsListener implements WifiManager.WpsListener {
+            public void onStartSuccess(String pin) {
+                if (pin != null) {
+                    updateDialog(DialogState.WPS_START, String.format(
+                            mContext.getString(R.string.wifi_wps_onstart_pin), pin));
+                } else {
+                    updateDialog(DialogState.WPS_START, mContext.getString(
+                            R.string.wifi_wps_onstart_pbc));
+                }
+            }
+            public void onCompletion() {
+                updateDialog(DialogState.WPS_COMPLETE,
+                        mContext.getString(R.string.wifi_wps_complete));
+            }
+
+            public void onFailure(int reason) {
+                String msg;
+                switch (reason) {
+                    case WifiManager.WPS_OVERLAP_ERROR:
+                        msg = mContext.getString(R.string.wifi_wps_failed_overlap);
+                        break;
+                    case WifiManager.WPS_WEP_PROHIBITED:
+                        msg = mContext.getString(R.string.wifi_wps_failed_wep);
+                        break;
+                    case WifiManager.WPS_TKIP_ONLY_PROHIBITED:
+                        msg = mContext.getString(R.string.wifi_wps_failed_tkip);
+                        break;
+                    case WifiManager.IN_PROGRESS:
+                        msg = mContext.getString(R.string.wifi_wps_in_progress);
+                        break;
+                    default:
+                        msg = mContext.getString(R.string.wifi_wps_failed_generic);
+                        break;
+                }
+                updateDialog(DialogState.WPS_FAILED, msg);
+            }
+        }
+
+        mWpsListener = new WpsListener();
+
+
+        mFilter = new IntentFilter();
+        mFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+        mReceiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                handleEvent(context, intent);
+            }
+        };
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        setTitle(R.string.wifi_wps_setup_title);
+        mView = getLayoutInflater().inflate(R.layout.wifi_wps_dialog, null);
+
+        mTextView = (TextView) mView.findViewById(R.id.wps_dialog_txt);
+        mTextView.setText(R.string.wifi_wps_setup_msg);
+
+        mTimeoutBar = ((ProgressBar) mView.findViewById(R.id.wps_timeout_bar));
+        mTimeoutBar.setMax(WPS_TIMEOUT_S);
+        mTimeoutBar.setProgress(0);
+
+        mProgressBar = ((ProgressBar) mView.findViewById(R.id.wps_progress_bar));
+        mProgressBar.setVisibility(View.GONE);
+
+        mButton = ((Button) mView.findViewById(R.id.wps_dialog_btn));
+        mButton.setText(R.string.wifi_cancel);
+        mButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                dismiss();
+            }
+        });
+
+        mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
+        mChannel = mWifiManager.initialize(mContext, mContext.getMainLooper(), null);
+
+        setView(mView);
+        super.onCreate(savedInstanceState);
+    }
+
+    @Override
+    protected void onStart() {
+        /*
+         * increment timeout bar per second.
+         */
+        mTimer = new Timer(false);
+        mTimer.schedule(new TimerTask() {
+            @Override
+            public void run() {
+                mHandler.post(new Runnable() {
+
+                    @Override
+                    public void run() {
+                        mTimeoutBar.incrementProgressBy(1);
+                    }
+                });
+            }
+        }, 1000, 1000);
+
+        mContext.registerReceiver(mReceiver, mFilter);
+
+        WpsInfo wpsConfig = new WpsInfo();
+        wpsConfig.setup = mWpsSetup;
+        mWifiManager.startWps(mChannel, wpsConfig, mWpsListener);
+    }
+
+    @Override
+    protected void onStop() {
+        if (mDialogState != DialogState.WPS_COMPLETE) {
+            mWifiManager.cancelWps(mChannel, null);
+        }
+
+        if (mReceiver != null) {
+            mContext.unregisterReceiver(mReceiver);
+            mReceiver = null;
+        }
+
+        if (mTimer != null) {
+            mTimer.cancel();
+        }
+    }
+
+    private void updateDialog(DialogState state, String msg) {
+        if (mDialogState.ordinal() >= state.ordinal()) {
+            //ignore.
+            return;
+        }
+        mDialogState = state;
+
+        switch(state) {
+            case WPS_COMPLETE:
+                mTimeoutBar.setVisibility(View.GONE);
+                mProgressBar.setVisibility(View.VISIBLE);
+                break;
+            case CONNECTED:
+            case WPS_FAILED:
+                mButton.setText(mContext.getString(R.string.dlg_ok));
+                mTimeoutBar.setVisibility(View.GONE);
+                mProgressBar.setVisibility(View.GONE);
+                if (mReceiver != null) {
+                    mContext.unregisterReceiver(mReceiver);
+                    mReceiver = null;
+                }
+                break;
+        }
+        mTextView.setText(msg);
+    }
+
+    private void handleEvent(Context context, Intent intent) {
+        String action = intent.getAction();
+        if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {
+            NetworkInfo info = (NetworkInfo) intent.getParcelableExtra(
+                    WifiManager.EXTRA_NETWORK_INFO);
+            final NetworkInfo.DetailedState state = info.getDetailedState();
+            if (state == DetailedState.CONNECTED &&
+                    mDialogState == DialogState.WPS_COMPLETE) {
+                WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
+                if (wifiInfo != null) {
+                    String msg = String.format(mContext.getString(
+                            R.string.wifi_wps_connected), wifiInfo.getSSID());
+                    updateDialog(DialogState.CONNECTED, msg);
+                }
+            }
+        }
+    }
+
+}