Merge "Add a delete button to quickly delete a word in the user dictionary."
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index ecb7b2a..fb294ba 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -384,7 +384,7 @@
         <activity-alias android:name=".ManageApplications"
             android:targetActivity=".applications.ManageApplications"
             android:exported="true" />
-        
+
         <activity android:name=".applications.InstalledAppDetails"
                 android:theme="@android:style/Theme.NoTitleBar"
                 android:label="@string/application_info_label">
@@ -407,7 +407,7 @@
                 <category android:name="com.android.settings.SHORTCUT" />
             </intent-filter>
         </activity-alias>
-        
+
         <!-- Provide direct entry into manage apps showing running services. -->
         <activity-alias android:name=".applications.StorageUse"
                 android:label="@string/storageuse_settings_title"
@@ -420,7 +420,7 @@
                 <category android:name="com.android.settings.SHORTCUT" />
             </intent-filter>
         </activity-alias>
-        
+
         <activity android:name=".applications.RunningServiceDetails"
                 android:theme="@android:style/Theme.NoTitleBar"
                 android:label="@string/runningservicedetails_settings_title">
diff --git a/res/layout/wifi_config_preference.xml b/res/layout/wifi_config_preference.xml
index b7f183f..095b94f 100644
--- a/res/layout/wifi_config_preference.xml
+++ b/res/layout/wifi_config_preference.xml
@@ -23,6 +23,47 @@
                   android:layout_width="fill_parent"
                   android:layout_height="wrap_content"
                   android:orientation="vertical" />
+
+    <LinearLayout android:id="@+id/setup_fields"
+                  android:layout_width="fill_parent"
+                  android:layout_height="wrap_content"
+                  android:orientation="vertical"
+                  android:visibility="gone">
+
+        <TextView
+                  android:layout_width="fill_parent"
+                  android:layout_height="wrap_content"
+                  android:text="@string/wifi_network_setup" />
+
+        <Spinner android:id="@+id/network_setup"
+                 android:layout_width="fill_parent"
+                 android:layout_height="wrap_content"
+                 android:prompt="@string/wifi_network_setup"
+                 android:entries="@array/wifi_network_setup" />
+
+      </LinearLayout>
+
+    <LinearLayout android:id="@+id/wps_fields"
+                  android:layout_width="fill_parent"
+                  android:layout_height="wrap_content"
+                  android:orientation="vertical"
+                  android:visibility="gone">
+
+        <TextView
+                  android:layout_width="fill_parent"
+                  android:layout_height="wrap_content"
+                  android:text="@string/wifi_wps_pin" />
+
+        <EditText android:id="@+id/wps_pin"
+                  android:layout_width="fill_parent"
+                  android:layout_height="wrap_content"
+                  android:singleLine="true"
+                  android:inputType="textPassword" />
+
+    </LinearLayout>
+
+
+
     <LinearLayout android:id="@+id/type"
                  android:layout_width="fill_parent"
                  android:layout_height="wrap_content"
@@ -50,7 +91,7 @@
                 android:entries="@array/wifi_security" />
     </LinearLayout>  <!-- android:id="@+id/type" -->
 
-    <LinearLayout android:id="@+id/fields"
+    <LinearLayout android:id="@+id/security_fields"
                   android:layout_width="fill_parent"
                   android:layout_height="wrap_content"
                   android:orientation="vertical"
@@ -141,9 +182,9 @@
                   android:layout_width="fill_parent"
                   android:layout_height="wrap_content"
                   android:text="@string/wifi_show_password" />
-    </LinearLayout>  <!-- android:id="@+id/fields" -->
+    </LinearLayout>  <!-- android:id="@+id/security_fields" -->
 
-    <LinearLayout android:id="@+id/ipfields"
+    <LinearLayout android:id="@+id/ip_fields"
                   android:layout_width="fill_parent"
                   android:layout_height="wrap_content"
                   android:orientation="vertical"
@@ -154,7 +195,7 @@
             android:layout_height="wrap_content"
             android:text="@string/wifi_ip_settings" />
 
-        <Spinner android:id="@+id/ipsettings"
+        <Spinner android:id="@+id/ip_settings"
                  android:layout_width="fill_parent"
                  android:layout_height="wrap_content"
                  android:prompt="@string/wifi_ip_settings"
diff --git a/res/layout/wifi_dialog.xml b/res/layout/wifi_dialog.xml
index 8bf1fca..189f717 100644
--- a/res/layout/wifi_dialog.xml
+++ b/res/layout/wifi_dialog.xml
@@ -29,6 +29,49 @@
                 android:layout_height="wrap_content"
                 android:orientation="vertical" />
 
+        <LinearLayout android:id="@+id/setup_fields"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical"
+                android:visibility="gone">
+
+            <TextView
+                    style="?android:attr/textAppearanceSmallInverse"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="8dip"
+                    android:text="@string/wifi_network_setup" />
+
+            <Spinner android:id="@+id/network_setup"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:prompt="@string/wifi_network_setup"
+                    android:entries="@array/wifi_network_setup" />
+
+        </LinearLayout>
+
+        <LinearLayout android:id="@+id/wps_fields"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical"
+                android:visibility="gone">
+
+            <TextView
+                    style="?android:attr/textAppearanceSmallInverse"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="8dip"
+                    android:text="@string/wifi_wps_pin" />
+
+            <EditText android:id="@+id/wps_pin"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:singleLine="true"
+                    android:inputType="textPassword" />
+
+        </LinearLayout>
+
+
         <LinearLayout android:id="@+id/type"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
@@ -62,7 +105,7 @@
                     android:entries="@array/wifi_security" />
         </LinearLayout>
 
-        <LinearLayout android:id="@+id/fields"
+        <LinearLayout android:id="@+id/security_fields"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:orientation="vertical"
@@ -171,7 +214,7 @@
                     android:text="@string/wifi_show_password" />
         </LinearLayout>
 
-        <LinearLayout android:id="@+id/ipfields"
+        <LinearLayout android:id="@+id/ip_fields"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:orientation="vertical"
@@ -184,7 +227,7 @@
                     android:layout_marginTop="8dip"
                     android:text="@string/wifi_ip_settings" />
 
-            <Spinner android:id="@+id/ipsettings"
+            <Spinner android:id="@+id/ip_settings"
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
                     android:prompt="@string/wifi_ip_settings"
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index e3acc10..87eb2dd 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -341,11 +341,23 @@
         <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>Manual</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>WPS push button</item>
+        <!-- WPS pin method based configuration. This requires entering a pin obtained from the access point [CHAR LIMIT=25] -->
+        <item>WPS pin method</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">
-        <!-- Do not translate. -->
+        <!-- Use DHCP (Dynamic Host Configuration Protocol) for obtaining IP settings [CHAR LIMIT=25] -->
         <item>DHCP</item>
-        <!-- Do not translate. -->
+        <!-- Use statically defined IP settings [CHAR LIMIT=25]-->
         <item>Static</item>
     </string-array>
 
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 97e4725..28a72e8 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -498,12 +498,22 @@
     <string name="date_and_time_settings_title">Date &amp; time</string>
     <!-- Main Settings screen setting option summary text for the item to go into the date and time settings. -->
     <string name="date_and_time_settings_summary">Set date, time, time zone &amp; formats</string>
-    <!-- Date & time setting screen setting check box title if the date and time should be determined automatically -->
-    <string name="date_time_auto">Automatic</string>
-    <!-- Date & time setting screen setting option summary text when Automatic check box is selected (that is, when date and time should be determined automatically) -->
-    <string name="date_time_auto_summaryOn">Use network-provided values</string>
-    <!-- Date & time setting screen setting option summary text when Automatic check box is clear -->
-    <string name="date_time_auto_summaryOff">Use network-provided values</string>
+    <!-- Date & time setting screen setting check box title if the date and time should be determined automatically [CHAR LIMIT=25] -->
+    <string name="date_time_auto">Automatic date &amp; time</string>
+    <!-- Date & time setting screen setting option summary text when Automatic check box is selected
+        (that is, when date and time should be determined automatically) [CHAR LIMIT=100] -->
+    <string name="date_time_auto_summaryOn">Use network-provided time</string>
+    <!-- Date & time setting screen setting option summary text when Automatic check box is clear
+        [CHAR LIMIT=100] -->
+    <string name="date_time_auto_summaryOff">Use network-provided time</string>
+    <!-- Date & time setting screen setting check box title if the time zone should be determined automatically [CHAR LIMIT=25] -->
+    <string name="zone_auto">Automatic time zone</string>
+    <!-- Date & time setting screen setting option summary text when Automatic time zone check box is selected (that is, when date and time should be determined automatically)
+        [CHAR LIMIT=100]  -->
+    <string name="zone_auto_summaryOn">Use network-provided time zone</string>
+    <!-- Date & time setting screen setting option summary text when Automatic time zone check box is clear
+        [CHAR LIMIT=100] -->
+    <string name="zone_auto_summaryOff">Use network-provided time zone</string>
     <!-- Date & time setting screen setting check box title -->
     <string name="date_time_24hour">Use 24-hour format</string>
     <!-- Date & time setting screen setting option title -->
@@ -525,7 +535,7 @@
     <string name="lock_after_timeout">Lock device after timeout</string>
     <!-- Security settings screen, setting option summary to change screen timeout -->
     <string name="lock_after_timeout_summary">Adjust the delay before the device automatically locks</string>
-    
+
     <!-- Main Settings screen setting option title for the item to take you the security and location screen -->
     <string name="security_settings_title">Location &amp; security</string>
     <!-- Location & security settings screen title -->
@@ -868,6 +878,10 @@
     <string name="wifi_menu_modify">Modify network</string>
 
     <!-- Dialog for Access Points --> <skip />
+    <!-- Label for network setup [CHAR LIMIT=50] -->
+    <string name="wifi_network_setup">Network Setup</string>
+    <!-- Label for the text view for WPS pin input [CHAR LIMIT=50] -->
+    <string name="wifi_wps_pin">Enter pin from access point</string>
     <!-- Label for the SSID of the network -->
     <string name="wifi_ssid">Network SSID</string>
     <!-- Label for the security of the connection -->
@@ -896,7 +910,7 @@
     <string name="wifi_password">Password</string>
     <!-- Label for the check box to show password -->
     <string name="wifi_show_password">Show password</string>
-    <!-- Label for the spinner to show ip settings  -->
+    <!-- Label for the spinner to show ip settings [CHAR LIMIT=25] -->
     <string name="wifi_ip_settings">IP settings</string>
     <!-- Hint for unchanged fields -->
     <string name="wifi_unchanged">(unchanged)</string>
@@ -910,6 +924,8 @@
     <string name="wifi_not_in_range">Not in range</string>
     <!-- Summary for the secured network. -->
     <string name="wifi_secured">Secured with <xliff:g id="wifi_security">%1$s</xliff:g></string>
+    <!-- Summary for the secured network with WPS being available [CHAR LIMIT=50]-->
+    <string name="wifi_secured_with_wps">Secured with <xliff:g id="wifi_security">%1$s</xliff:g> (WPS available)</string>
     <!-- Summary for the secured and remembered network. Status can be "Remembered", "Disabled" or "Not in range". -->
     <string name="wifi_secured_with_status"><xliff:g id="wifi_status">%2$s</xliff:g>, secured with <xliff:g id="wifi_security">%1$s</xliff:g></string>
     <!-- Button label to connect to a Wi-Fi network -->
@@ -1927,7 +1943,7 @@
     <!-- Message that a process's provider is in use. -->
     <string name="process_provider_in_use_description">Provider <xliff:g id="comp_name">%1$s</xliff:g>
         is in use.</string>
-    
+
     <!-- Language Settings --> <skip />
     <!-- Title of setting on main settings screen.  This item will take the user to the screen to tweak settings realted to locale and text -->
     <string name="language_settings">Language &amp; keyboard</string>
@@ -2077,7 +2093,7 @@
 
     <!-- Used to show an amount of time in the form "s seconds" in BatteryHistory -->
     <string name="battery_history_seconds"><xliff:g id="seconds">%1$d</xliff:g>s</string>
-    
+
     <!-- XXX remove? Strings used for displaying usage statistics -->
     <string name="usage_stats_label">Usage statistics</string>
 
diff --git a/res/xml/date_time_prefs.xml b/res/xml/date_time_prefs.xml
index 08c5d5c..657d6b3 100644
--- a/res/xml/date_time_prefs.xml
+++ b/res/xml/date_time_prefs.xml
@@ -4,9 +4,9 @@
      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.
@@ -16,31 +16,36 @@
 
 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
         android:title="@string/date_and_time">
-    <CheckBoxPreference android:key="auto_time" 
+    <CheckBoxPreference android:key="auto_time"
         android:title="@string/date_time_auto"
         android:summaryOn="@string/date_time_auto_summaryOn"
         android:summaryOff="@string/date_time_auto_summaryOff"
         />
-    <Preference android:key="date" 
-        android:title="@string/date_time_set_date" 
+    <CheckBoxPreference android:key="auto_zone"
+        android:title="@string/zone_auto"
+        android:summaryOn="@string/zone_auto_summaryOn"
+        android:summaryOff="@string/zone_auto_summaryOff"
+        />
+    <Preference android:key="date"
+        android:title="@string/date_time_set_date"
         android:summary="03/10/2008"
         />
+    <Preference android:key="time"
+        android:title="@string/date_time_set_time"
+        android:summary="12:00am"
+        />
     <PreferenceScreen
         android:fragment="com.android.settings.ZonePicker"
         android:key="timezone"
         android:title="@string/date_time_set_timezone"
         android:summary="GMT-8:00"
         />
-    <Preference android:key="time" 
-        android:title="@string/date_time_set_time" 
-        android:summary="12:00am"
-        />
-    <CheckBoxPreference android:key="24 hour" 
+    <CheckBoxPreference android:key="24 hour"
         android:title="@string/date_time_24hour"
         android:summaryOn="@string/date_time_24_hour_sample"
         android:summaryOff="@string/date_time_12_hour_sample"/>
     <ListPreference
         android:key="date_format"
-        android:title="@string/date_time_date_format" 
+        android:title="@string/date_time_date_format"
         android:summary="mm/dd/yyyy"/>
 </PreferenceScreen>
diff --git a/src/com/android/settings/DateTimeSettings.java b/src/com/android/settings/DateTimeSettings.java
index 5a8f148..4d199b8 100644
--- a/src/com/android/settings/DateTimeSettings.java
+++ b/src/com/android/settings/DateTimeSettings.java
@@ -48,47 +48,50 @@
 
     private static final String HOURS_12 = "12";
     private static final String HOURS_24 = "24";
-    
+
     // Used for showing the current date format, which looks like "12/31/2010", "2010/12/13", etc.
     // The date value is dummy (independent of actual date).
     private Calendar mDummyDate;
 
     private static final String KEY_DATE_FORMAT = "date_format";
     private static final String KEY_AUTO_TIME = "auto_time";
+    private static final String KEY_AUTO_TIME_ZONE = "auto_zone";
 
     private static final int DIALOG_DATEPICKER = 0;
     private static final int DIALOG_TIMEPICKER = 1;
-    
-    private CheckBoxPreference mAutoPref;
+
+    private CheckBoxPreference mAutoTimePref;
     private Preference mTimePref;
     private Preference mTime24Pref;
+    private CheckBoxPreference mAutoTimeZonePref;
     private Preference mTimeZone;
     private Preference mDatePref;
     private ListPreference mDateFormat;
-    
+
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
-        
+
         addPreferencesFromResource(R.xml.date_time_prefs);
-        
-        initUI();        
+
+        initUI();
     }
-    
+
     private void initUI() {
-        boolean autoEnabled = getAutoState();
+        boolean autoTimeEnabled = getAutoState(Settings.System.AUTO_TIME);
+        boolean autoTimeZoneEnabled = getAutoState(Settings.System.AUTO_TIME_ZONE);
 
         mDummyDate = Calendar.getInstance();
         mDummyDate.set(mDummyDate.get(Calendar.YEAR), 11, 31, 13, 0, 0);
-        
-        mAutoPref = (CheckBoxPreference) findPreference(KEY_AUTO_TIME);
-        mAutoPref.setChecked(autoEnabled);
+
+        mAutoTimePref = (CheckBoxPreference) findPreference(KEY_AUTO_TIME);
+        mAutoTimePref.setChecked(autoTimeEnabled);
         mTimePref = findPreference("time");
         mTime24Pref = findPreference("24 hour");
         mTimeZone = findPreference("timezone");
         mDatePref = findPreference("date");
         mDateFormat = (ListPreference) findPreference(KEY_DATE_FORMAT);
-        
+
         String [] dateFormats = getResources().getStringArray(R.array.date_format_values);
         String [] formattedDates = new String[dateFormats.length];
         String currentFormat = getDateFormat();
@@ -109,22 +112,23 @@
                 formattedDates[i] = formatted;
             }
         }
-        
+
         mDateFormat.setEntries(formattedDates);
         mDateFormat.setEntryValues(R.array.date_format_values);
         mDateFormat.setValue(currentFormat);
-        
-        mTimePref.setEnabled(!autoEnabled);
-        mDatePref.setEnabled(!autoEnabled);
-        mTimeZone.setEnabled(!autoEnabled);
+
+        mTimePref.setEnabled(!autoTimeEnabled);
+        mDatePref.setEnabled(!autoTimeEnabled);
+        mTimeZone.setEnabled(!autoTimeZoneEnabled);
     }
 
-    
+
     @Override
     public void onResume() {
         super.onResume();
-        
-        getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
+
+        getPreferenceScreen().getSharedPreferences()
+                .registerOnSharedPreferenceChangeListener(this);
 
         ((CheckBoxPreference)mTime24Pref).setChecked(is24Hour());
 
@@ -138,13 +142,14 @@
         updateTimeAndDateDisplay(getActivity());
     }
 
-    @Override 
+    @Override
     public void onPause() {
         super.onPause();
         getActivity().unregisterReceiver(mIntentReceiver);
-        getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
+        getPreferenceScreen().getSharedPreferences()
+                .unregisterOnSharedPreferenceChangeListener(this);
     }
-    
+
     private void updateTimeAndDateDisplay(Context context) {
         java.text.DateFormat shortDateFormat = DateFormat.getDateFormat(context);
         final Calendar now = Calendar.getInstance();
@@ -180,19 +185,22 @@
     @Override
     public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
         if (key.equals(KEY_DATE_FORMAT)) {
-            String format = preferences.getString(key, 
+            String format = preferences.getString(key,
                     getResources().getString(R.string.default_date_format));
-            Settings.System.putString(getContentResolver(), 
+            Settings.System.putString(getContentResolver(),
                     Settings.System.DATE_FORMAT, format);
             updateTimeAndDateDisplay(getActivity());
         } else if (key.equals(KEY_AUTO_TIME)) {
             boolean autoEnabled = preferences.getBoolean(key, true);
-            Settings.System.putInt(getContentResolver(), 
-                    Settings.System.AUTO_TIME, 
+            Settings.System.putInt(getContentResolver(), Settings.System.AUTO_TIME,
                     autoEnabled ? 1 : 0);
             mTimePref.setEnabled(!autoEnabled);
             mDatePref.setEnabled(!autoEnabled);
-            mTimeZone.setEnabled(!autoEnabled);
+        } else if (key.equals(KEY_AUTO_TIME_ZONE)) {
+            boolean autoZoneEnabled = preferences.getBoolean(key, true);
+            Settings.System.putInt(
+                    getContentResolver(), Settings.System.AUTO_TIME_ZONE, autoZoneEnabled ? 1 : 0);
+            mTimeZone.setEnabled(!autoZoneEnabled);
         }
     }
 
@@ -272,39 +280,38 @@
         }
         return super.onPreferenceTreeClick(preferenceScreen, preference);
     }
-    
+
     @Override
     public void onActivityResult(int requestCode, int resultCode,
             Intent data) {
         updateTimeAndDateDisplay(getActivity());
     }
-    
+
     private void timeUpdated() {
         Intent timeChanged = new Intent(Intent.ACTION_TIME_CHANGED);
         getActivity().sendBroadcast(timeChanged);
     }
-    
+
     /*  Get & Set values from the system settings  */
-    
+
     private boolean is24Hour() {
         return DateFormat.is24HourFormat(getActivity());
     }
-    
+
     private void set24Hour(boolean is24Hour) {
         Settings.System.putString(getContentResolver(),
                 Settings.System.TIME_12_24,
                 is24Hour? HOURS_24 : HOURS_12);
     }
-    
+
     private String getDateFormat() {
-        return Settings.System.getString(getContentResolver(), 
+        return Settings.System.getString(getContentResolver(),
                 Settings.System.DATE_FORMAT);
     }
-    
-    private boolean getAutoState() {
+
+    private boolean getAutoState(String name) {
         try {
-            return Settings.System.getInt(getContentResolver(), 
-                Settings.System.AUTO_TIME) > 0;            
+            return Settings.System.getInt(getContentResolver(), name) > 0;
         } catch (SettingNotFoundException snfe) {
             return true;
         }
@@ -346,7 +353,7 @@
             append(", ").
             append(tz.getDisplayName(daylight, TimeZone.LONG));
 
-        return sb.toString();        
+        return sb.toString();
     }
 
     private static char[] formatOffset(int off) {
@@ -364,7 +371,7 @@
             buf[3] = '+';
         }
 
-        int hours = off / 60; 
+        int hours = off / 60;
         int minutes = off % 60;
 
         buf[4] = (char) ('0' + hours / 10);
@@ -377,7 +384,7 @@
 
         return buf;
     }
-    
+
     private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
diff --git a/src/com/android/settings/DateTimeSettingsSetupWizard.java b/src/com/android/settings/DateTimeSettingsSetupWizard.java
index 016a7f2..c47af0a 100644
--- a/src/com/android/settings/DateTimeSettingsSetupWizard.java
+++ b/src/com/android/settings/DateTimeSettingsSetupWizard.java
@@ -43,6 +43,8 @@
     private boolean mXLargeScreenSize;
 
     /* Available only in XL */
+    private CompoundButton mAutoDateTimeButton;
+    private CompoundButton mAutoTimeZoneButton;
     private Button mTimeZone;
     private TimePicker mTimePicker;
     private DatePicker mDatePicker;
@@ -65,28 +67,25 @@
     }
 
     public void initUiForXl() {
-        // TODO: use system value
-        final boolean autoTimeZoneEnabled = false;
-        final CompoundButton autoTimeZoneButton =
-                (CompoundButton)findViewById(R.id.time_zone_auto);
-        autoTimeZoneButton.setChecked(autoTimeZoneEnabled);
-        autoTimeZoneButton.setOnCheckedChangeListener(this);
-        // TODO: remove this after the system support.
-        autoTimeZoneButton.setEnabled(false);
-
-        final boolean autoDateTimeEnabled = isAutoDateTimeEnabled();
-        final CompoundButton autoDateTimeButton =
-                (CompoundButton)findViewById(R.id.date_time_auto);
-        autoDateTimeButton.setChecked(autoDateTimeEnabled);
-        autoDateTimeButton.setText(autoDateTimeEnabled ? R.string.date_time_auto_summaryOn :
-                R.string.date_time_auto_summaryOff);
-        autoDateTimeButton.setOnCheckedChangeListener(this);
+        final boolean autoTimeZoneEnabled = isAutoTimeZoneEnabled();
+        mAutoTimeZoneButton = (CompoundButton)findViewById(R.id.time_zone_auto);
+        mAutoTimeZoneButton.setChecked(autoTimeZoneEnabled);
+        mAutoTimeZoneButton.setOnCheckedChangeListener(this);
+        mAutoTimeZoneButton.setText(autoTimeZoneEnabled ? R.string.zone_auto_summaryOn :
+                R.string.zone_auto_summaryOff);
 
         final TimeZone tz = TimeZone.getDefault();
         mTimeZone = (Button)findViewById(R.id.current_time_zone);
         mTimeZone.setText(DateTimeSettings.getTimeZoneText(tz));
         mTimeZone.setOnClickListener(this);
-        mTimeZone.setEnabled(!autoDateTimeEnabled);
+        mTimeZone.setEnabled(!autoTimeZoneEnabled);
+
+        final boolean autoDateTimeEnabled = isAutoDateTimeEnabled();
+        mAutoDateTimeButton = (CompoundButton)findViewById(R.id.date_time_auto);
+        mAutoDateTimeButton.setChecked(autoDateTimeEnabled);
+        mAutoDateTimeButton.setText(autoDateTimeEnabled ? R.string.date_time_auto_summaryOn :
+                R.string.date_time_auto_summaryOff);
+        mAutoDateTimeButton.setOnCheckedChangeListener(this);
 
         mTimePicker = (TimePicker)findViewById(R.id.time_picker);
         mTimePicker.setEnabled(!autoDateTimeEnabled);
@@ -112,6 +111,13 @@
         }
         case R.id.next_button: {
             if (mXLargeScreenSize) {
+                Settings.System.putInt(getContentResolver(), Settings.System.AUTO_TIME_ZONE,
+                        mAutoTimeZoneButton.isChecked() ? 1 : 0);
+                Settings.System.putInt(getContentResolver(), Settings.System.AUTO_TIME,
+                        mAutoDateTimeButton.isChecked() ? 1 : 0);
+                // Note: in non-XL, Date & Time is stored by DatePickerDialog/TimePickerDialog,
+                // so we don't need to save those values there, while in XL, we need to as
+                // we don't use those Dialogs.
                 DateTimeSettings.setDate(mDatePicker.getYear(), mDatePicker.getMonth(),
                         mDatePicker.getDayOfMonth());
                 DateTimeSettings.setTime(
@@ -129,16 +135,27 @@
     @Override
     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
         final boolean autoEnabled = isChecked;  // just for readibility.
-        Settings.System.putInt(getContentResolver(),
-                Settings.System.AUTO_TIME,
-                isChecked ? 1 : 0);
-        if (isChecked) {
-            findViewById(R.id.current_time_zone).setVisibility(View.VISIBLE);
-            findViewById(R.id.zone_picker).setVisibility(View.GONE);
+        if (buttonView == mAutoTimeZoneButton) {
+            // In XL screen, we save all the state only when the next button is pressed.
+            if (!mXLargeScreenSize) {
+                Settings.System.putInt(getContentResolver(),
+                        Settings.System.AUTO_TIME_ZONE,
+                        isChecked ? 1 : 0);
+            }
+            mTimeZone.setEnabled(!autoEnabled);
+            if (isChecked) {
+                findViewById(R.id.current_time_zone).setVisibility(View.VISIBLE);
+                findViewById(R.id.zone_picker).setVisibility(View.GONE);
+            }
+        } else if (buttonView == mAutoDateTimeButton) {
+            if (!mXLargeScreenSize) {
+                Settings.System.putInt(getContentResolver(),
+                        Settings.System.AUTO_TIME,
+                        isChecked ? 1 : 0);
+            }
+            mTimePicker.setEnabled(!autoEnabled);
+            mDatePicker.setEnabled(!autoEnabled);
         }
-        mTimeZone.setEnabled(!autoEnabled);
-        mTimePicker.setEnabled(!autoEnabled);
-        mDatePicker.setEnabled(!autoEnabled);
         if (autoEnabled) {
             final View focusedView = getCurrentFocus();
             if (focusedView != null) {
@@ -167,4 +184,13 @@
             return true;
         }
     }
+
+    private boolean isAutoTimeZoneEnabled() {
+        try {
+            return Settings.System.getInt(getContentResolver(),
+                    Settings.System.AUTO_TIME_ZONE) > 0;
+        } catch (SettingNotFoundException e) {
+            return true;
+        }
+    }
 }
diff --git a/src/com/android/settings/bluetooth/BluetoothNamePreference.java b/src/com/android/settings/bluetooth/BluetoothNamePreference.java
index 7a9a0c1..c99ab4c 100644
--- a/src/com/android/settings/bluetooth/BluetoothNamePreference.java
+++ b/src/com/android/settings/bluetooth/BluetoothNamePreference.java
@@ -27,8 +27,8 @@
 import android.preference.EditTextPreference;
 import android.text.Editable;
 import android.text.InputFilter;
+import android.text.Spanned;
 import android.text.TextWatcher;
-import android.text.InputFilter.LengthFilter;
 import android.util.AttributeSet;
 import android.widget.Button;
 import android.widget.EditText;
@@ -40,8 +40,7 @@
  */
 public class BluetoothNamePreference extends EditTextPreference implements TextWatcher {
     private static final String TAG = "BluetoothNamePreference";
-    // TODO(): Investigate bluetoothd/dbus crash when length is set to 248, limit as per spec.
-    private static final int BLUETOOTH_NAME_MAX_LENGTH = 200;
+    private static final int BLUETOOTH_NAME_MAX_LENGTH_BYTES = 248;
 
     private LocalBluetoothManager mLocalManager;
 
@@ -75,8 +74,11 @@
 
         // Make sure the OK button is disabled (if necessary) after rotation
         EditText et = getEditText();
-        et.setFilters(new InputFilter[] {new LengthFilter(BLUETOOTH_NAME_MAX_LENGTH)});
         if (et != null) {
+            et.setFilters(new InputFilter[] {
+                    new Utf8ByteLengthFilter(BLUETOOTH_NAME_MAX_LENGTH_BYTES)
+            });
+
             et.addTextChangedListener(this);
             Dialog d = getDialog();
             if (d instanceof AlertDialog) {
@@ -136,4 +138,68 @@
     public void onTextChanged(CharSequence s, int start, int before, int count) {
         // not used
     }
+
+    /**
+     * This filter will constrain edits so that the text length is not
+     * greater than the specified number of bytes using UTF-8 encoding.
+     * <p>The JNI method used by {@link android.server.BluetoothService}
+     * to convert UTF-16 to UTF-8 doesn't support surrogate pairs,
+     * therefore code points outside of the basic multilingual plane
+     * (0000-FFFF) will be encoded as a pair of 3-byte UTF-8 characters,
+     * rather than a single 4-byte UTF-8 encoding. Dalvik implements this
+     * conversion in {@code convertUtf16ToUtf8()} in
+     * {@code dalvik/vm/UtfString.c}.
+     * <p>This JNI method is unlikely to change in the future due to
+     * backwards compatibility requirements. It's also unclear whether
+     * the installed base of Bluetooth devices would correctly handle the
+     * encoding of surrogate pairs in UTF-8 as 4 bytes rather than 6.
+     * However, this filter will still work in scenarios where surrogate
+     * pairs are encoded as 4 bytes, with the caveat that the maximum
+     * length will be constrained more conservatively than necessary.
+     */
+    public static class Utf8ByteLengthFilter implements InputFilter {
+        private int mMaxBytes;
+
+        public Utf8ByteLengthFilter(int maxBytes) {
+            mMaxBytes = maxBytes;
+        }
+
+        public CharSequence filter(CharSequence source, int start, int end,
+                                   Spanned dest, int dstart, int dend) {
+            int srcByteCount = 0;
+            // count UTF-8 bytes in source substring
+            for (int i = start; i < end; i++) {
+                char c = source.charAt(i);
+                srcByteCount += (c < 0x0080) ? 1 : (c < 0x0800 ? 2 : 3);
+            }
+            int destLen = dest.length();
+            int destByteCount = 0;
+            // count UTF-8 bytes in destination excluding replaced section
+            for (int i = 0; i < destLen; i++) {
+                if (i < dstart || i >= dend) {
+                    char c = dest.charAt(i);
+                    destByteCount += (c < 0x0080) ? 1 : (c < 0x0800 ? 2 : 3);
+                }
+            }
+            int keepBytes = mMaxBytes - destByteCount;
+            if (keepBytes <= 0) {
+                return "";
+            } else if (keepBytes >= srcByteCount) {
+                return null; // use original dest string
+            } else {
+                // find end position of largest sequence that fits in keepBytes
+                for (int i = start; i < end; i++) {
+                    char c = source.charAt(i);
+                    keepBytes -= (c < 0x0080) ? 1 : (c < 0x0800 ? 2 : 3);
+                    if (keepBytes < 0) {
+                        return source.subSequence(start, i);
+                    }
+                }
+                // If the entire substring fits, we should have returned null
+                // above, so this line should not be reached. If for some
+                // reason it is, return null to use the original dest string.
+                return null;
+            }
+        }
+    }
 }
diff --git a/src/com/android/settings/wifi/AccessPoint.java b/src/com/android/settings/wifi/AccessPoint.java
index fcc9eb2..054c6ff 100644
--- a/src/com/android/settings/wifi/AccessPoint.java
+++ b/src/com/android/settings/wifi/AccessPoint.java
@@ -69,8 +69,10 @@
     static final int SECURITY_EAP = 3;
 
     final String ssid;
+    final String bssid;
     final int security;
     final int networkId;
+    boolean wpsAvailable = false;
 
     private WifiConfiguration mConfig;
     private int mRssi;
@@ -104,6 +106,7 @@
         super(context);
         setWidgetLayoutResource(R.layout.preference_widget_wifi_signal);
         ssid = (config.SSID == null ? "" : removeDoubleQuotes(config.SSID));
+        bssid = config.BSSID;
         security = getSecurity(config);
         networkId = config.networkId;
         mConfig = config;
@@ -114,7 +117,10 @@
         super(context);
         setWidgetLayoutResource(R.layout.preference_widget_wifi_signal);
         ssid = result.SSID;
+        bssid = result.BSSID;
         security = getSecurity(result);
+        wpsAvailable = security != SECURITY_NONE && security != SECURITY_EAP &&
+                result.capabilities.contains("WPS");
         networkId = -1;
         mRssi = result.level;
     }
@@ -218,8 +224,13 @@
             if (security == SECURITY_NONE) {
                 setSummary(status);
             } else {
-                String format = context.getString((status == null) ?
-                        R.string.wifi_secured : R.string.wifi_secured_with_status);
+                String format;
+                if (wpsAvailable && mConfig == null) {
+                    format = context.getString(R.string.wifi_secured_with_wps);
+                } else {
+                    format = context.getString((status == null) ?
+                            R.string.wifi_secured : R.string.wifi_secured_with_status);
+                }
                 String[] type = context.getResources().getStringArray(R.array.wifi_security);
                 setSummary(String.format(format, type[security], status));
             }
diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java
index d9fb239..4c04fb5 100644
--- a/src/com/android/settings/wifi/WifiConfigController.java
+++ b/src/com/android/settings/wifi/WifiConfigController.java
@@ -25,6 +25,7 @@
 import android.net.wifi.WifiConfiguration.IpAssignment;
 import android.net.wifi.WifiConfiguration.AuthAlgorithm;
 import android.net.wifi.WifiConfiguration.KeyMgmt;
+import static android.net.wifi.WifiConfiguration.INVALID_NETWORK_ID;
 import android.net.wifi.WifiInfo;
 import android.security.Credentials;
 import android.security.KeyStore;
@@ -72,7 +73,15 @@
     private TextView mEapIdentityView;
     private TextView mEapAnonymousView;
 
-    private static final String STATIC_IP = "Static";
+    /* This value comes from "wifi_ip_settings" resource array */
+    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_PIN = 2;
+
+    private Spinner mNetworkSetupSpinner;
     private Spinner mIpSettingsSpinner;
     private TextView mIpAddressView;
     private TextView mGatewayView;
@@ -140,7 +149,12 @@
                 }
             }
 
-            if (mAccessPoint.networkId == -1 || mEdit) {
+            /* 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();
             }
@@ -151,22 +165,20 @@
                 if (state == null && level != -1) {
                     mConfigUi.setSubmitButton(context.getString(R.string.wifi_connect));
                 } else {
-                    mView.findViewById(R.id.ipfields).setVisibility(View.GONE);
+                    mView.findViewById(R.id.ip_fields).setVisibility(View.GONE);
                 }
-                if (mAccessPoint.networkId != -1) {
+                if (mAccessPoint.networkId != INVALID_NETWORK_ID) {
                     mConfigUi.setForgetButton(context.getString(R.string.wifi_forget));
                 }
             }
         }
 
-        mIpSettingsSpinner = ((Spinner) mView.findViewById(R.id.ipsettings));
-        if (mAccessPoint != null && mAccessPoint.networkId != -1) {
+        if (mAccessPoint != null && mAccessPoint.networkId != INVALID_NETWORK_ID) {
             WifiConfiguration config = mAccessPoint.getConfig();
             if (config.ipAssignment == IpAssignment.STATIC) {
-                setSelection(mIpSettingsSpinner, STATIC_IP);
+                mIpSettingsSpinner.setSelection(STATIC_IP);
             }
         }
-        mIpSettingsSpinner.setOnItemSelectedListener(this);
 
         mConfigUi.setCancelButton(context.getString(R.string.wifi_cancel));
         if (mConfigUi.getSubmitButton() != null) {
@@ -184,7 +196,7 @@
     /* show submit button if the password is valid */
     private void enableSubmitIfAppropriate() {
         if ((mSsidView != null && mSsidView.length() == 0) ||
-            ((mAccessPoint == null || mAccessPoint.networkId == -1) &&
+            ((mAccessPoint == null || mAccessPoint.networkId == INVALID_NETWORK_ID) &&
             ((mAccessPointSecurity == AccessPoint.SECURITY_WEP && mPasswordView.length() == 0) ||
             (mAccessPointSecurity == AccessPoint.SECURITY_PSK && mPasswordView.length() < 8)))) {
             mConfigUi.getSubmitButton().setEnabled(false);
@@ -194,7 +206,7 @@
     }
 
     /* package */ WifiConfiguration getConfig() {
-        if (mAccessPoint != null && mAccessPoint.networkId != -1 && !mEdit) {
+        if (mAccessPoint != null && mAccessPoint.networkId != INVALID_NETWORK_ID && !mEdit) {
             return null;
         }
 
@@ -205,7 +217,7 @@
                     mSsidView.getText().toString());
             // If the user adds a network manually, assume that it is hidden.
             config.hiddenSSID = true;
-        } else if (mAccessPoint.networkId == -1) {
+        } else if (mAccessPoint.networkId == INVALID_NETWORK_ID) {
             config.SSID = AccessPoint.convertToQuotedString(
                     mAccessPoint.ssid);
         } else {
@@ -275,7 +287,7 @@
                     return null;
         }
 
-        config.ipAssignment = mIpSettingsSpinner.getSelectedItem().toString().equals(STATIC_IP) ?
+        config.ipAssignment = (mIpSettingsSpinner.getSelectedItemPosition() == STATIC_IP) ?
                 IpAssignment.STATIC : IpAssignment.DHCP;
 
         if (config.ipAssignment == IpAssignment.STATIC) {
@@ -299,19 +311,35 @@
         return config;
     }
 
+    int chosenNetworkSetupMethod() {
+        if (mNetworkSetupSpinner != null) {
+            return mNetworkSetupSpinner.getSelectedItemPosition();
+        }
+        return MANUAL;
+    }
+
+    int getWpsPin() {
+        try {
+            String wpsPin = ((TextView) mView.findViewById(R.id.wps_pin)).getText().toString();
+            return Integer.parseInt(wpsPin);
+        } catch (NumberFormatException e) {
+            return -1;
+        }
+    }
+
     private void showSecurityFields() {
         if (mAccessPointSecurity == AccessPoint.SECURITY_NONE) {
-            mView.findViewById(R.id.fields).setVisibility(View.GONE);
+            mView.findViewById(R.id.security_fields).setVisibility(View.GONE);
             return;
         }
-        mView.findViewById(R.id.fields).setVisibility(View.VISIBLE);
+        mView.findViewById(R.id.security_fields).setVisibility(View.VISIBLE);
 
         if (mPasswordView == null) {
             mPasswordView = (TextView) mView.findViewById(R.id.password);
             mPasswordView.addTextChangedListener(this);
             ((CheckBox) mView.findViewById(R.id.show_password)).setOnClickListener(this);
 
-            if (mAccessPoint != null && mAccessPoint.networkId != -1) {
+            if (mAccessPoint != null && mAccessPoint.networkId != INVALID_NETWORK_ID) {
                 mPasswordView.setHint(R.string.wifi_unchanged);
             }
         }
@@ -333,7 +361,7 @@
             loadCertificates(mEapCaCertSpinner, Credentials.CA_CERTIFICATE);
             loadCertificates(mEapUserCertSpinner, Credentials.USER_PRIVATE_KEY);
 
-            if (mAccessPoint != null && mAccessPoint.networkId != -1) {
+            if (mAccessPoint != null && mAccessPoint.networkId != INVALID_NETWORK_ID) {
                 WifiConfiguration config = mAccessPoint.getConfig();
                 setSelection(mEapMethodSpinner, config.eap.value());
                 setSelection(mPhase2Spinner, config.phase2.value());
@@ -347,20 +375,47 @@
         }
     }
 
+    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_PIN) {
+            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_PIN) || (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;
 
-        mView.findViewById(R.id.ipfields).setVisibility(View.VISIBLE);
+        mView.findViewById(R.id.ip_fields).setVisibility(View.VISIBLE);
 
         if (mIpSettingsSpinner == null) {
-            mIpSettingsSpinner = (Spinner) mView.findViewById(R.id.ipsettings);
+            mIpSettingsSpinner = (Spinner) mView.findViewById(R.id.ip_settings);
+            mIpSettingsSpinner.setOnItemSelectedListener(this);
         }
 
-        if (mAccessPoint != null && mAccessPoint.networkId != -1) {
+        if (mAccessPoint != null && mAccessPoint.networkId != INVALID_NETWORK_ID) {
             config = mAccessPoint.getConfig();
         }
 
-        if (mIpSettingsSpinner.getSelectedItem().equals(STATIC_IP)) {
+        if (mIpSettingsSpinner.getSelectedItemPosition() == STATIC_IP) {
             mView.findViewById(R.id.staticip).setVisibility(View.VISIBLE);
             if (mIpAddressView == null) {
                 mIpAddressView = (TextView) mView.findViewById(R.id.ipaddress);
@@ -451,6 +506,8 @@
             mAccessPointSecurity = position;
             showSecurityFields();
             enableSubmitIfAppropriate();
+        } else if (parent == mNetworkSetupSpinner){
+            showNetworkSetupFields();
         } else {
             showIpConfigFields();
         }
@@ -484,4 +541,4 @@
             ((i >> 24 ) & 0xFF);
     }
 
-}
\ No newline at end of file
+}
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index 5f6294f..05aecaf 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -33,6 +33,7 @@
 import android.net.wifi.SupplicantState;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiConfiguration.KeyMgmt;
+import static android.net.wifi.WifiConfiguration.INVALID_NETWORK_ID;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.os.Bundle;
@@ -44,7 +45,6 @@
 import android.provider.Settings.Secure;
 import android.security.Credentials;
 import android.security.KeyStore;
-import android.util.Log;
 import android.view.ContextMenu;
 import android.view.ContextMenu.ContextMenuInfo;
 import android.view.Menu;
@@ -102,7 +102,7 @@
     private DetailedState mLastState;
     private WifiInfo mLastInfo;
 
-    private int mKeyStoreNetworkId = -1;
+    private int mKeyStoreNetworkId = INVALID_NETWORK_ID;
 
     // should Next button only be enabled when we have a connection?
     private boolean mEnableNextOnConnection;
@@ -198,10 +198,11 @@
             mWifiEnabler.resume();
         }
         getActivity().registerReceiver(mReceiver, mFilter);
-        if (mKeyStoreNetworkId != -1 && KeyStore.getInstance().test() == KeyStore.NO_ERROR) {
+        if (mKeyStoreNetworkId != INVALID_NETWORK_ID &&
+                KeyStore.getInstance().test() == KeyStore.NO_ERROR) {
             mWifiManager.connectNetwork(mKeyStoreNetworkId);
         }
-        mKeyStoreNetworkId = -1;
+        mKeyStoreNetworkId = INVALID_NETWORK_ID;
         if (mInXlSetupWizard) {
             // We show "Now scanning"
             final int wifiState = mWifiManager.getWifiState();
@@ -285,7 +286,7 @@
                         && mSelectedAccessPoint.getState() == null) {
                     menu.add(Menu.NONE, MENU_ID_CONNECT, 0, R.string.wifi_menu_connect);
                 }
-                if (mSelectedAccessPoint.networkId != -1) {
+                if (mSelectedAccessPoint.networkId != INVALID_NETWORK_ID) {
                     menu.add(Menu.NONE, MENU_ID_FORGET, 0, R.string.wifi_menu_forget);
                     menu.add(Menu.NONE, MENU_ID_MODIFY, 0, R.string.wifi_menu_modify);
                 }
@@ -300,7 +301,7 @@
         }
         switch (item.getItemId()) {
             case MENU_ID_CONNECT: {
-                if (mSelectedAccessPoint.networkId != -1) {
+                if (mSelectedAccessPoint.networkId != INVALID_NETWORK_ID) {
                     if (!requireKeyStore(mSelectedAccessPoint.getConfig())) {
                         mWifiManager.connectNetwork(mSelectedAccessPoint.networkId);
                     }
@@ -601,23 +602,36 @@
 
     /* package */ void submit() {
         final WifiConfigUiBase uiBase = (mDialog != null ? mDialog : mConfigPreference);
-        final WifiConfiguration config = uiBase.getController().getConfig();
+        final WifiConfigController configController = uiBase.getController();
 
-        if (config == null) {
-            if (mSelectedAccessPoint != null
-                    && !requireKeyStore(mSelectedAccessPoint.getConfig())) {
-                mWifiManager.connectNetwork(mSelectedAccessPoint.networkId);
-            }
-        } else if (config.networkId != -1) {
-            if (mSelectedAccessPoint != null) {
-                mWifiManager.saveNetwork(config);
-            }
-        } else {
-            if (uiBase.isEdit() || requireKeyStore(config)) {
-                mWifiManager.saveNetwork(config);
-            } else {
-                mWifiManager.connectNetwork(config);
-            }
+        switch(configController.chosenNetworkSetupMethod()) {
+            case WifiConfigController.WPS_PBC:
+                mWifiManager.startWpsPbc(mSelectedAccessPoint.bssid);
+                break;
+            case WifiConfigController.WPS_PIN:
+                int apPin = configController.getWpsPin();
+                mWifiManager.startWpsPin(mSelectedAccessPoint.bssid, apPin);
+                break;
+            case WifiConfigController.MANUAL:
+                final WifiConfiguration config = configController.getConfig();
+
+                if (config == null) {
+                    if (mSelectedAccessPoint != null
+                            && !requireKeyStore(mSelectedAccessPoint.getConfig())) {
+                        mWifiManager.connectNetwork(mSelectedAccessPoint.networkId);
+                    }
+                } else if (config.networkId != INVALID_NETWORK_ID) {
+                    if (mSelectedAccessPoint != null) {
+                        mWifiManager.saveNetwork(config);
+                    }
+                } else {
+                    if (uiBase.isEdit() || requireKeyStore(config)) {
+                        mWifiManager.saveNetwork(config);
+                    } else {
+                        mWifiManager.connectNetwork(config);
+                    }
+                }
+                break;
         }
 
         detachConfigPreference();
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index e125128..53bf40f 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -58,4 +58,9 @@
         android:label="Settings Launch Performance">
     </instrumentation>
 
+    <instrumentation android:name="android.test.InstrumentationTestRunner"
+        android:targetPackage="com.android.settings"
+        android:label="Settings Test Cases">
+    </instrumentation>
+
 </manifest>
diff --git a/tests/src/com/android/settings/SettingsLaunchPerformance.java b/tests/src/com/android/settings/tests/SettingsLaunchPerformance.java
similarity index 99%
rename from tests/src/com/android/settings/SettingsLaunchPerformance.java
rename to tests/src/com/android/settings/tests/SettingsLaunchPerformance.java
index 05154e2..225a60b 100644
--- a/tests/src/com/android/settings/SettingsLaunchPerformance.java
+++ b/tests/src/com/android/settings/tests/SettingsLaunchPerformance.java
@@ -26,7 +26,7 @@
  * Instrumentation class for Settings launch performance testing.
  */
 public class SettingsLaunchPerformance extends LaunchPerformanceBase {
- 
+
     public static final String LOG_TAG = "SettingsLaunchPerformance";
 
     public SettingsLaunchPerformance() {
diff --git a/tests/src/com/android/settings/tests/Utf8ByteLengthFilterTest.java b/tests/src/com/android/settings/tests/Utf8ByteLengthFilterTest.java
new file mode 100644
index 0000000..c03f9c0
--- /dev/null
+++ b/tests/src/com/android/settings/tests/Utf8ByteLengthFilterTest.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2010 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.tests;
+
+import android.test.AndroidTestCase;
+import android.text.InputFilter;
+import android.text.SpannableStringBuilder;
+
+import com.android.settings.bluetooth.BluetoothNamePreference;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+
+@TestTargetClass(BluetoothNamePreference.Utf8ByteLengthFilter.class)
+public class Utf8ByteLengthFilterTest extends AndroidTestCase {
+
+    @TestTargets({
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            method = "filter",
+            args = {java.lang.CharSequence.class, int.class, int.class, android.text.Spanned.class,
+                    int.class, int.class}
+        ),
+        @TestTargetNew(
+            level = TestLevel.COMPLETE,
+            method = "BluetoothNamePreference.Utf8ByteLengthFilter",
+            args = {int.class}
+        )
+    })
+    public void testFilter() {
+        // Define the variables
+        CharSequence source;
+        SpannableStringBuilder dest;
+        // Constructor to create a LengthFilter
+        BluetoothNamePreference.Utf8ByteLengthFilter lengthFilter = new BluetoothNamePreference.Utf8ByteLengthFilter(10);
+        InputFilter[] filters = {lengthFilter};
+
+        // filter() implicitly invoked. If the total length > filter length, the filter will
+        // cut off the source CharSequence from beginning to fit the filter length.
+        source = "abc";
+        dest = new SpannableStringBuilder("abcdefgh");
+        dest.setFilters(filters);
+
+        dest.insert(1, source);
+        String expectedString1 = "aabbcdefgh";
+        assertEquals(expectedString1, dest.toString());
+
+        dest.replace(5, 8, source);
+        String expectedString2 = "aabbcabcgh";
+        assertEquals(expectedString2, dest.toString());
+
+        dest.insert(2, source);
+        assertEquals(expectedString2, dest.toString());
+
+        dest.delete(1, 3);
+        String expectedString3 = "abcabcgh";
+        assertEquals(expectedString3, dest.toString());
+
+        dest.append("12345");
+        String expectedString4 = "abcabcgh12";
+        assertEquals(expectedString4, dest.toString());
+
+        source = "\u60a8\u597d";  // 2 Chinese chars == 6 bytes in UTF-8
+        dest.replace(8, 10, source);
+        assertEquals(expectedString3, dest.toString());
+
+        dest.replace(0, 1, source);
+        String expectedString5 = "\u60a8bcabcgh";
+        assertEquals(expectedString5, dest.toString());
+
+        dest.replace(0, 4, source);
+        String expectedString6 = "\u60a8\u597dbcgh";
+        assertEquals(expectedString6, dest.toString());
+
+        source = "\u00a3\u00a5";  // 2 Latin-1 chars == 4 bytes in UTF-8
+        dest.delete(2, 6);
+        dest.insert(0, source);
+        String expectedString7 = "\u00a3\u00a5\u60a8\u597d";
+        assertEquals(expectedString7, dest.toString());
+
+        dest.replace(2, 3, source);
+        String expectedString8 = "\u00a3\u00a5\u00a3\u597d";
+        assertEquals(expectedString8, dest.toString());
+
+        dest.replace(3, 4, source);
+        String expectedString9 = "\u00a3\u00a5\u00a3\u00a3\u00a5";
+        assertEquals(expectedString9, dest.toString());
+
+        // filter() explicitly invoked
+        dest = new SpannableStringBuilder("abcdefgh");
+        CharSequence beforeFilterSource = "TestLengthFilter";
+        String expectedAfterFilter = "TestLength";
+        CharSequence actualAfterFilter = lengthFilter.filter(beforeFilterSource, 0,
+                beforeFilterSource.length(), dest, 0, dest.length());
+        assertEquals(expectedAfterFilter, actualAfterFilter);
+    }
+}