Merge "Use the new isNetworkSupported api for wifi-only"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index bd456e8..96fdcc9 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1148,7 +1148,8 @@
                   android:immersive="true"
                   android:launchMode="singleTop"
                   android:theme="@android:style/Theme.Holo.NoActionBar"
-                  android:windowSoftInputMode="stateAlwaysHidden">
+                  android:configChanges="mcc|mnc|keyboard|keyboardHidden|uiMode"
+                  android:windowSoftInputMode="stateVisible|adjustResize">
             <intent-filter android:priority="10">
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.HOME" />
diff --git a/res/drawable-hdpi/ic_lockscreen_ime.png b/res/drawable-hdpi/ic_lockscreen_ime.png
new file mode 100644
index 0000000..29a7989
--- /dev/null
+++ b/res/drawable-hdpi/ic_lockscreen_ime.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_lockscreen_ime.png b/res/drawable-mdpi/ic_lockscreen_ime.png
new file mode 100644
index 0000000..b27e059
--- /dev/null
+++ b/res/drawable-mdpi/ic_lockscreen_ime.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_lockscreen_ime.png b/res/drawable-xhdpi/ic_lockscreen_ime.png
new file mode 100644
index 0000000..a40ddeb
--- /dev/null
+++ b/res/drawable-xhdpi/ic_lockscreen_ime.png
Binary files differ
diff --git a/res/layout-land/crypt_keeper_password_entry.xml b/res/layout-land/crypt_keeper_password_entry.xml
new file mode 100644
index 0000000..094434e
--- /dev/null
+++ b/res/layout-land/crypt_keeper_password_entry.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2011, 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="match_parent"
+    android:layout_height="match_parent"
+>
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical"
+    >
+        <LinearLayout
+            android:layout_height="wrap_content"
+            android:layout_width="match_parent"
+            android:orientation="horizontal"
+            android:gravity="center_vertical"
+        >
+            <include layout="@layout/crypt_keeper_status" />
+
+            <!-- Emergency call button.
+                 Text and icon are set by CryptKeeper.updateEmergencyCallButtonState() -->
+            <Button android:id="@+id/emergencyCallButton"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center"
+                android:layout_margin="16dip"
+                style="@*android:style/Widget.Button.Transparent"
+                android:textSize="14sp"
+                android:drawablePadding="6dip"
+            />
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_height="wrap_content"
+            android:layout_width="match_parent"
+            android:layout_marginLeft="8dip"
+            android:layout_marginRight="8dip"
+            android:orientation="horizontal"
+        >
+            <include layout="@layout/crypt_keeper_password_field" />
+        </LinearLayout>
+
+
+    </LinearLayout>
+</ScrollView>
diff --git a/res/layout-sw600dp-land/crypt_keeper_password_entry.xml b/res/layout-sw600dp-land/crypt_keeper_password_entry.xml
index 9415fd1..8898b76 100644
--- a/res/layout-sw600dp-land/crypt_keeper_password_entry.xml
+++ b/res/layout-sw600dp-land/crypt_keeper_password_entry.xml
@@ -46,18 +46,15 @@
         />
 
         <!-- Password entry field -->
-        <view
-            class="com.android.settings.CryptKeeper$CryptEditText"
-            android:id="@+id/passwordEntry"
+        <LinearLayout
             android:layout_height="wrap_content"
             android:layout_width="320dip"
             android:layout_toRightOf="@+id/passwordLabel"
             android:layout_centerVertical="true"
-            android:singleLine="true"
-            android:inputType="textPassword"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            android:editable="false"
-        />
+            android:orientation="horizontal"
+        >
+            <include layout="@layout/crypt_keeper_password_field" />
+        </LinearLayout>
 
         <TextView android:id="@+id/status"
             android:layout_height="wrap_content"
diff --git a/res/layout-sw600dp/crypt_keeper_password_entry.xml b/res/layout-sw600dp/crypt_keeper_password_entry.xml
index 0610ec0..bc2b353 100644
--- a/res/layout-sw600dp/crypt_keeper_password_entry.xml
+++ b/res/layout-sw600dp/crypt_keeper_password_entry.xml
@@ -45,18 +45,15 @@
         />
 
         <!-- Password entry field -->
-        <view
-            class="com.android.settings.CryptKeeper$CryptEditText"
-            android:id="@+id/passwordEntry"
+        <LinearLayout
             android:layout_height="wrap_content"
             android:layout_width="320dip"
             android:layout_toRightOf="@+id/passwordLabel"
             android:layout_marginTop="26dip"
-            android:singleLine="true"
-            android:inputType="textPassword"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            android:editable="false"
-        />
+            android:orientation="horizontal"
+        >
+            <include layout="@layout/crypt_keeper_password_field" />
+        </LinearLayout>
 
         <TextView android:id="@+id/status"
             android:layout_height="wrap_content"
@@ -72,13 +69,4 @@
         />
     </RelativeLayout>
 
-    <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_alignParentBottom="true"
-        android:background="#00000000"
-        android:keyBackground="@*android:drawable/btn_keyboard_key_fulltrans"
-        android:visibility="visible"
-    />
-
-</RelativeLayout>
\ No newline at end of file
+</RelativeLayout>
diff --git a/res/layout/crypt_keeper_password_entry.xml b/res/layout/crypt_keeper_password_entry.xml
index a7799fc..1278327 100644
--- a/res/layout/crypt_keeper_password_entry.xml
+++ b/res/layout/crypt_keeper_password_entry.xml
@@ -22,36 +22,28 @@
     android:layout_height="match_parent"
     android:orientation="vertical"
 >
+    <include layout="@layout/crypt_keeper_status" />
+
     <LinearLayout
-           android:layout_height="wrap_content"
-           android:layout_width="match_parent"
-           android:orientation="vertical"
-           android:gravity="center_vertical"
-               >
-       <include layout="@layout/crypt_keeper_status" />
-   </LinearLayout>
+        android:layout_height="wrap_content"
+        android:layout_width="match_parent"
+        android:layout_marginLeft="8dip"
+        android:layout_marginRight="8dip"
+        android:orientation="horizontal"
+    >
+        <include layout="@layout/crypt_keeper_password_field" />
+    </LinearLayout>
 
-   <EditText android:id="@+id/passwordEntry"
-       android:layout_height="wrap_content"
-       android:layout_width="match_parent"
-       android:layout_marginLeft="8dip"
-       android:layout_marginRight="8dip"
-       android:singleLine="true"
-       android:inputType="textPassword"
-       android:textSize="18sp"
-       android:textAppearance="?android:attr/textAppearanceMedium"
+    <!-- Emergency call button.
+         Text and icon are set by CryptKeeper.updateEmergencyCallButtonState() -->
+    <Button android:id="@+id/emergencyCallButton"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:layout_marginTop="16dip"
+        style="@*android:style/Widget.Button.Transparent"
+        android:textSize="14sp"
+        android:drawablePadding="6dip"
     />
 
-   <!-- Emergency call button.
-        Text and icon are set by CryptKeeper.updateEmergencyCallButtonState() -->
-   <Button android:id="@+id/emergencyCallButton"
-       android:layout_width="wrap_content"
-       android:layout_height="wrap_content"
-       android:layout_gravity="center"
-       android:layout_marginTop="16dip"
-       style="@*android:style/Widget.Button.Transparent"
-       android:textSize="14sp"
-       android:drawablePadding="6dip"
-       />
-
 </LinearLayout>
diff --git a/res/layout/crypt_keeper_password_field.xml b/res/layout/crypt_keeper_password_field.xml
new file mode 100644
index 0000000..17968e8
--- /dev/null
+++ b/res/layout/crypt_keeper_password_field.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<!-- Contents of the password entry field for CryptKeeper. Comes with an IME
+     switcher, if necessary. Assumed to be in a horizontal LinearLayout. -->
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+    <EditText android:id="@+id/passwordEntry"
+        android:layout_height="wrap_content"
+        android:layout_width="0dip"
+        android:layout_weight="1"
+        android:singleLine="true"
+        android:inputType="textPassword"
+        android:imeOptions="actionDone"
+        android:privateImeOptions="com.google.android.inputmethod.latin.forceAscii"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+     />
+
+   <ImageView android:id="@+id/switch_ime_button"
+       android:layout_width="wrap_content"
+       android:layout_height="wrap_content"
+       android:src="@drawable/ic_lockscreen_ime"
+       android:clickable="true"
+       android:padding="8dip"
+       android:layout_gravity="center"
+       android:background="?android:attr/selectableItemBackground"
+       android:visibility="gone"
+   />
+</merge>
diff --git a/res/layout/crypt_keeper_status.xml b/res/layout/crypt_keeper_status.xml
index b830b57..59d2365 100644
--- a/res/layout/crypt_keeper_status.xml
+++ b/res/layout/crypt_keeper_status.xml
@@ -32,7 +32,6 @@
         android:layout_alignParentLeft="true"
         android:layout_marginTop="8dip"
         android:layout_marginBottom="8dip"
-        android:layout_marginLeft="-10dip"
         >
 
         <!-- Because we can't have multi-tone fonts, we render two TextViews, one on
diff --git a/res/layout/preference_empty_list.xml b/res/layout/preference_empty_list.xml
new file mode 100644
index 0000000..1c721ac
--- /dev/null
+++ b/res/layout/preference_empty_list.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:minHeight="48dip"
+    android:background="@android:color/transparent">
+
+    <TextView
+        android:id="@+android:id/title"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:padding="@*android:dimen/preference_fragment_padding_side"
+        android:gravity="center" />
+
+</LinearLayout>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 29ba1d3..2079700 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -2491,9 +2491,9 @@
     <!-- On Language & keyboard settings screen, heading. Inside the "Language & keyboard settings" screen, this is the header for settings that relate to language (select the system language, user dictionary for the language). -->
     <string name="language_settings_category">Language settings</string>
     <!-- On Language & keyboard settings screen, heading. Inside the "Language & keyboard settings" screen, this is the header for settings that relate to keyboard (enable/disable each keyboard, settings for each keyboard). -->
-    <string name="keyboard_settings_category">Keyboard settings</string>
+    <string name="keyboard_settings_category">Keyboard &amp; input methods</string>
     <!-- On Text & language settings screen, setting option name. title of the setting to take the user to a screen to select the locale. -->
-    <string name="phone_language">Select language</string>
+    <string name="phone_language">Language</string>
     <!-- On Text & language settings screen, setting option name. summary of the setting to take the user to a screen to select the locale. -->
     <string name="phone_language_summary">""</string>
     <!-- On Text & language settings screen, setting option name. title of the setting to enable autoreplace of entered text. auto replace is a feature that will automatically correct mistyped words. -->
@@ -2522,17 +2522,17 @@
     <xliff:g id="ime_application_name">%1$s</xliff:g>.
     Use this input method?</string>
     <!-- On Language & input settings screen, heading. Inside the "Language & input settings" screen, this is the header for settings that relate to mouse and trackpad devices. [CHAR LIMIT=40] -->
-    <string name="pointer_settings_category">Mouse and trackpad settings</string>
+    <string name="pointer_settings_category">Mouse/trackpad</string>
     <!-- On Language & input settings screen, setting summary.  Setting for mouse pointer speed. [CHAR LIMIT=35] -->
     <string name="pointer_speed">Pointer speed</string>
 
     <!-- User dictionary settings --><skip />
     <!-- User dictionary settings, The titlebar text of the User dictionary settings screen. -->
     <string name="user_dict_settings_titlebar">User dictionary</string>
-    <!-- User dictionary settings, The title of the list item to go into the User dictionary settings screen when there is only one user dictionary. -->
-    <string name="user_dict_single_settings_title">User dictionary</string>
-    <!-- User dictionary settings, The title of the list item to go into the User dictionary list when there are several user dictionaries. -->
-    <string name="user_dict_multiple_settings_title">Manage user dictionaries</string>
+    <!-- User dictionary settings, The title of the list item to go into the User dictionary settings screen when there is only one user dictionary. [CHAR LIMIT=35] -->
+    <string name="user_dict_single_settings_title">Personal dictionary</string>
+    <!-- User dictionary settings, The title of the list item to go into the User dictionary list when there are several user dictionaries. [CHAR LIMIT=35] -->
+    <string name="user_dict_multiple_settings_title">Personal dictionaries</string>
     <!-- User dictionary settings.  The summary of the listem item to go into the User dictionary settings screen. -->
     <string name="user_dict_settings_summary">""</string>
     <!-- User dictionary settings. The title of the menu item to add a new word to the user dictionary. -->
@@ -2590,8 +2590,8 @@
     <string name="input_methods_settings_title">Text input</string>
     <!-- Setting name for Input Method chooser -->
     <string name="input_method">Input method</string>
-    <!-- Title for selecting the current input method [CHAR LIMIT=35] -->
-    <string name="current_input_method">Current input method</string>
+    <!-- Title for the option to press to choose the current input method [CHAR LIMIT=35] -->
+    <string name="current_input_method">Default</string>
     <!-- Title for setting the visibility of input method selector [CHAR LIMIT=35] -->
     <string name="input_method_selector">Input method selector</string>
     <!-- An option to always show input method selector automatically when needed [CHAR LIMIT=25] -->
@@ -2932,22 +2932,20 @@
     <!-- Title of keyboard settings list item within voice input/output settings -->
     <string name="keyboard_settings_title">Android keyboard</string>
     <!-- Title for the 'voice input' category of voice input/output settings -->
-    <string name="voice_input_category">Voice input</string>
-    <!-- Title for the 'voice output' category of voice input/output settings -->
-    <string name="voice_output_category">Voice output</string>
+    <string name="voice_category">Voice</string>
     <!-- Title for the voice recognizer setting in voice input/output settings -->
     <string name="recognizer_title">Voice recognizer</string>
     <!-- Title for the link to settings for the chosen voice recognizer in voice input/output settings -->
-    <string name="recognizer_settings_title">Voice recognizer settings</string>
+    <string name="recognizer_settings_title">Voice input for search</string>
     <!-- Summary for the link to settings for the chosen voice recognizer in voice input/output settings.
          Would say something like, e.g., "Settings for 'Google'". -->
     <string name="recognizer_settings_summary">Settings for \'<xliff:g id="recognizer_name">%s</xliff:g>\'</string>
 
     <!-- Text-To-Speech (TTS) settings --><skip />
-    <!-- Title of setting on main settings screen.  This item will take the user to the screen to tweak settings related to the text-to-speech functionality -->
+    <!-- Name of the TTS package as listed by the package manager. -->
     <string name="tts_settings">Text-to-speech settings</string>
-    <!-- Main TTS Settings screen title -->
-    <string name="tts_settings_title">Text-to-speech settings</string>
+    <!-- TTS option item name in the main settings screen -->
+    <string name="tts_settings_title">Text-to-speech output</string>
     <!-- On main TTS Settings screen, title for toggle used to force use of default TTS settings -->
     <string name="use_default_tts_settings_title">Always use my settings</string>
     <!-- On main TTS Settings screen, summary for toggle used to force use of default TTS settings -->
diff --git a/res/xml/language_settings.xml b/res/xml/language_settings.xml
index 1598939..fbfb3d7 100644
--- a/res/xml/language_settings.xml
+++ b/res/xml/language_settings.xml
@@ -18,23 +18,18 @@
         xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
         android:title="@string/language_keyboard_settings_title">
 
-    <PreferenceCategory android:key="language_settings_category"
-            android:title="@string/language_settings_category">
+    <PreferenceScreen
+            android:fragment="com.android.settings.LocalePicker"
+            android:key="phone_language"
+            android:title="@string/phone_language"/>
 
-        <PreferenceScreen
-                 android:fragment="com.android.settings.LocalePicker"
-                 android:key="phone_language"
-                 android:title="@string/phone_language"/>
+    <com.android.settings.inputmethod.SpellCheckersPreference
+            android:key="spellcheckers_settings"
+            android:title="@string/spellcheckers_settings_title"/>
 
-        <!-- User dictionary preference title and fragment will be set programmatically. -->
-        <PreferenceScreen
-                 android:key="key_user_dictionary_settings" />
-
-        <com.android.settings.inputmethod.SpellCheckersPreference
-                 android:key="spellcheckers_settings"
-                 android:title="@string/spellcheckers_settings_title"/>
-
-    </PreferenceCategory>
+    <!-- User dictionary preference title and fragment will be set programmatically. -->
+    <PreferenceScreen
+            android:key="key_user_dictionary_settings" />
 
     <PreferenceCategory android:key="keyboard_settings_category"
             android:title="@string/keyboard_settings_category">
@@ -65,8 +60,8 @@
                 android:persistent="false"/>
     </PreferenceCategory>
 
-    <PreferenceCategory android:key="voice_input_category"
-            android:title="@string/voice_input_category" >
+    <PreferenceCategory android:key="voice_category"
+            android:title="@string/voice_category" >
 
         <!-- entries, entryValues, and defaultValue will be populated programmatically. -->
         <ListPreference
@@ -77,10 +72,6 @@
         <!-- An intent for this preference will be populated programmatically. -->
         <PreferenceScreen android:key="recognizer_settings"
                 android:title="@string/recognizer_settings_title" />
-    </PreferenceCategory>
-
-    <PreferenceCategory android:key="voice_output_category"
-            android:title="@string/voice_output_category" >
 
         <PreferenceScreen android:key="tts_settings"
                 android:fragment="com.android.settings.tts.TextToSpeechSettings"
diff --git a/res/xml/wireless_settings.xml b/res/xml/wireless_settings.xml
index 81929d0..1e71863 100644
--- a/res/xml/wireless_settings.xml
+++ b/res/xml/wireless_settings.xml
@@ -45,6 +45,11 @@
         android:summary="@string/ndef_push_settings_summary" >
     </PreferenceScreen>
 
+    <CheckBoxPreference
+        android:key="toggle_wifi_p2p"
+        android:title="@string/wifi_p2p_settings_title"
+        android:persistent="false" />
+
     <PreferenceScreen
         android:fragment="com.android.settings.wifi.p2p.WifiP2pSettings"
         android:key="wifi_p2p_settings"
diff --git a/src/com/android/settings/CryptKeeper.java b/src/com/android/settings/CryptKeeper.java
index 0552b68..0c8ce28 100644
--- a/src/com/android/settings/CryptKeeper.java
+++ b/src/com/android/settings/CryptKeeper.java
@@ -22,8 +22,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
-import android.graphics.Rect;
-import android.inputmethodservice.KeyboardView;
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.Handler;
@@ -36,22 +34,22 @@
 import android.os.storage.IMountService;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
-import android.util.AttributeSet;
 import android.util.Log;
 import android.view.KeyEvent;
-import android.view.MotionEvent;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputMethodInfo;
 import android.view.inputmethod.InputMethodManager;
+import android.view.inputmethod.InputMethodSubtype;
 import android.widget.Button;
 import android.widget.EditText;
 import android.widget.ProgressBar;
 import android.widget.TextView;
 
 import com.android.internal.telephony.ITelephony;
-import com.android.internal.widget.PasswordEntryKeyboardHelper;
-import com.android.internal.widget.PasswordEntryKeyboardView;
+
+import java.util.List;
 
 /**
  * Settings screens to show the UI flows for encrypting/decrypting the device.
@@ -112,37 +110,6 @@
         }
     }
 
-    // Use a custom EditText to prevent the input method from showing.
-    public static class CryptEditText extends EditText {
-        InputMethodManager imm;
-
-        public CryptEditText(Context context, AttributeSet attrs) {
-            super(context, attrs);
-            imm = ((InputMethodManager) getContext().
-                    getSystemService(Context.INPUT_METHOD_SERVICE));
-        }
-
-        @Override
-        protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
-            super.onFocusChanged(focused, direction, previouslyFocusedRect);
-
-            if (focused && imm != null && imm.isActive(this)) {
-                imm.hideSoftInputFromWindow(getApplicationWindowToken(), 0);
-            }
-        }
-
-        @Override
-        public boolean onTouchEvent(MotionEvent event) {
-            boolean handled = super.onTouchEvent(event);
-
-            if (imm != null && imm.isActive(this)) {
-                imm.hideSoftInputFromWindow(getApplicationWindowToken(), 0);
-            }
-
-            return handled;
-        }
-    }
-
     private class DecryptTask extends AsyncTask<String, Void, Integer> {
         @Override
         protected Integer doInBackground(String... params) {
@@ -387,18 +354,79 @@
     private void passwordEntryInit() {
         mPasswordEntry = (EditText) findViewById(R.id.passwordEntry);
         mPasswordEntry.setOnEditorActionListener(this);
+        mPasswordEntry.requestFocus();
 
-        KeyboardView keyboardView = (PasswordEntryKeyboardView) findViewById(R.id.keyboard);
-
-        if (keyboardView != null) {
-            PasswordEntryKeyboardHelper keyboardHelper = new PasswordEntryKeyboardHelper(this,
-                    keyboardView, mPasswordEntry, false);
-            keyboardHelper.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA);
+        View imeSwitcher = findViewById(R.id.switch_ime_button);
+        final InputMethodManager imm = (InputMethodManager) getSystemService(
+                Context.INPUT_METHOD_SERVICE);
+        if (imeSwitcher != null && hasMultipleEnabledIMEsOrSubtypes(imm, false)) {
+            imeSwitcher.setVisibility(View.VISIBLE);
+            imeSwitcher.setOnClickListener(new OnClickListener() {
+                public void onClick(View v) {
+                    imm.showInputMethodPicker();
+                }
+            });
         }
 
+        // Asynchronously throw up the IME, since there are issues with requesting it to be shown
+        // immediately.
+        mHandler.postDelayed(new Runnable() {
+            @Override public void run() {
+                imm.showSoftInputUnchecked(0, null);
+            }
+        }, 0);
+
         updateEmergencyCallButtonState();
     }
 
+    /**
+     * Method adapted from com.android.inputmethod.latin.Utils
+     *
+     * @param imm The input method manager
+     * @param shouldIncludeAuxiliarySubtypes
+     * @return true if we have multiple IMEs to choose from
+     */
+    private boolean hasMultipleEnabledIMEsOrSubtypes(InputMethodManager imm,
+            final boolean shouldIncludeAuxiliarySubtypes) {
+        final List<InputMethodInfo> enabledImis = imm.getEnabledInputMethodList();
+
+        // Number of the filtered IMEs
+        int filteredImisCount = 0;
+
+        for (InputMethodInfo imi : enabledImis) {
+            // We can return true immediately after we find two or more filtered IMEs.
+            if (filteredImisCount > 1) return true;
+            final List<InputMethodSubtype> subtypes =
+                    imm.getEnabledInputMethodSubtypeList(imi, true);
+            // IMEs that have no subtypes should be counted.
+            if (subtypes.isEmpty()) {
+                ++filteredImisCount;
+                continue;
+            }
+
+            int auxCount = 0;
+            for (InputMethodSubtype subtype : subtypes) {
+                if (subtype.isAuxiliary()) {
+                    ++auxCount;
+                }
+            }
+            final int nonAuxCount = subtypes.size() - auxCount;
+
+            // IMEs that have one or more non-auxiliary subtypes should be counted.
+            // If shouldIncludeAuxiliarySubtypes is true, IMEs that have two or more auxiliary
+            // subtypes should be counted as well.
+            if (nonAuxCount > 0 || (shouldIncludeAuxiliarySubtypes && auxCount > 1)) {
+                ++filteredImisCount;
+                continue;
+            }
+        }
+
+        return filteredImisCount > 1
+        // imm.getEnabledInputMethodSubtypeList(null, false) will return the current IME's enabled
+        // input method subtype (The current IME should be LatinIME.)
+                || imm.getEnabledInputMethodSubtypeList(null, false).size() > 1;
+    }
+
     private IMountService getMountService() {
         IBinder service = ServiceManager.getService("mount");
         if (service != null) {
diff --git a/src/com/android/settings/ProgressCategory.java b/src/com/android/settings/ProgressCategory.java
index eee19bc..6c74846 100644
--- a/src/com/android/settings/ProgressCategory.java
+++ b/src/com/android/settings/ProgressCategory.java
@@ -26,12 +26,13 @@
 
     private boolean mProgress = false;
     private Preference mNoDeviceFoundPreference;
+    private boolean mNoDeviceFoundAdded;
 
     public ProgressCategory(Context context, AttributeSet attrs) {
         super(context, attrs);
         setLayoutResource(R.layout.preference_progress_category);
     }
-    
+
     @Override
     public void onBindView(View view) {
         super.onBindView(view);
@@ -39,21 +40,26 @@
         final View progressBar = view.findViewById(R.id.scanning_progress);
 
         textView.setText(mProgress ? R.string.progress_scanning : R.string.progress_tap_to_pair);
-        boolean noDeviceFound = getPreferenceCount() == 0;
+        boolean noDeviceFound = (getPreferenceCount() == 0 ||
+                (getPreferenceCount() == 1 && getPreference(0) == mNoDeviceFoundPreference));
         textView.setVisibility(noDeviceFound ? View.INVISIBLE : View.VISIBLE);
         progressBar.setVisibility(mProgress ? View.VISIBLE : View.INVISIBLE);
 
         if (mProgress) {
-            if (mNoDeviceFoundPreference != null) {
+            if (mNoDeviceFoundAdded) {
                 removePreference(mNoDeviceFoundPreference);
+                mNoDeviceFoundAdded = false;
             }
         } else {
-            if (noDeviceFound) {
+            if (noDeviceFound && !mNoDeviceFoundAdded) {
                 if (mNoDeviceFoundPreference == null) {
                     mNoDeviceFoundPreference = new Preference(getContext());
-                    mNoDeviceFoundPreference.setSummary(R.string.bluetooth_no_devices_found);
+                    mNoDeviceFoundPreference.setLayoutResource(R.layout.preference_empty_list);
+                    mNoDeviceFoundPreference.setTitle(R.string.bluetooth_no_devices_found);
+                    mNoDeviceFoundPreference.setSelectable(false);
                 }
                 addPreference(mNoDeviceFoundPreference);
+                mNoDeviceFoundAdded = true;
             }
         }
     }
diff --git a/src/com/android/settings/VoiceInputOutputSettings.java b/src/com/android/settings/VoiceInputOutputSettings.java
index 1e86801..9e3add4 100644
--- a/src/com/android/settings/VoiceInputOutputSettings.java
+++ b/src/com/android/settings/VoiceInputOutputSettings.java
@@ -51,12 +51,12 @@
 
     private static final String TAG = "VoiceInputOutputSettings";
 
-    private static final String KEY_VOICE_INPUT_CATEGORY = "voice_input_category";
+    private static final String KEY_VOICE_CATEGORY = "voice_category";
     private static final String KEY_RECOGNIZER = "recognizer";
     private static final String KEY_RECOGNIZER_SETTINGS = "recognizer_settings";
     
     private PreferenceGroup mParent;
-    private PreferenceCategory mVoiceInputCategory;
+    private PreferenceCategory mVoiceCategory;
     private ListPreference mRecognizerPref;
     private PreferenceScreen mSettingsPref;
     private SettingsPreferenceFragment mFragment;
@@ -70,11 +70,11 @@
     public void onCreate() {
 
         mParent = (PreferenceGroup) mFragment.getPreferenceScreen();
-        mVoiceInputCategory = (PreferenceCategory) mParent.findPreference(KEY_VOICE_INPUT_CATEGORY);
-        mRecognizerPref = (ListPreference) mVoiceInputCategory.findPreference(KEY_RECOGNIZER);
+        mVoiceCategory = (PreferenceCategory) mParent.findPreference(KEY_VOICE_CATEGORY);
+        mRecognizerPref = (ListPreference) mVoiceCategory.findPreference(KEY_RECOGNIZER);
         mRecognizerPref.setOnPreferenceChangeListener(this);
         mSettingsPref = (PreferenceScreen)
-                mVoiceInputCategory.findPreference(KEY_RECOGNIZER_SETTINGS);
+                mVoiceCategory.findPreference(KEY_RECOGNIZER_SETTINGS);
 
         mAvailableRecognizersMap = new HashMap<String, ResolveInfo>();
 
@@ -89,11 +89,11 @@
         
         if (numAvailable == 0) {
             // No recognizer available - remove all related preferences.
-            mFragment.getPreferenceScreen().removePreference(mVoiceInputCategory);
+            mFragment.getPreferenceScreen().removePreference(mVoiceCategory);
         } else if (numAvailable == 1) {
             // Only one recognizer available, so don't show the list of choices, but do
             // set up the link to settings for the available recognizer.
-            mVoiceInputCategory.removePreference(mRecognizerPref);
+            mVoiceCategory.removePreference(mRecognizerPref);
 
             // But first set up the available recognizers map with just the one recognizer.
             ResolveInfo resolveInfo = availableRecognitionServices.get(0);
@@ -193,7 +193,7 @@
             // No settings preference available - hide the preference.
             Log.w(TAG, "no recognizer settings available for " + si.packageName);
             mSettingsPref.setIntent(null);
-            mVoiceInputCategory.removePreference(mSettingsPref);
+            mVoiceCategory.removePreference(mSettingsPref);
         } else {
             Intent i = new Intent(Intent.ACTION_MAIN);
             i.setComponent(new ComponentName(si.packageName, settingsActivity));
diff --git a/src/com/android/settings/WirelessSettings.java b/src/com/android/settings/WirelessSettings.java
index b10b93fb..c6f14a1 100644
--- a/src/com/android/settings/WirelessSettings.java
+++ b/src/com/android/settings/WirelessSettings.java
@@ -36,6 +36,7 @@
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.telephony.TelephonyProperties;
 import com.android.settings.nfc.NfcEnabler;
+import com.android.settings.wifi.p2p.WifiP2pEnabler;
 
 public class WirelessSettings extends SettingsPreferenceFragment {
 
@@ -43,6 +44,7 @@
     private static final String KEY_TOGGLE_NFC = "toggle_nfc";
     private static final String KEY_NDEF_PUSH_SETTINGS = "ndef_push_settings";
     private static final String KEY_VPN_SETTINGS = "vpn_settings";
+    private static final String KEY_TOGGLE_WIFI_P2P = "toggle_wifi_p2p";
     private static final String KEY_WIFI_P2P_SETTINGS = "wifi_p2p_settings";
     private static final String KEY_TETHER_SETTINGS = "tether_settings";
     private static final String KEY_PROXY_SETTINGS = "proxy_settings";
@@ -58,6 +60,8 @@
     private NfcEnabler mNfcEnabler;
     private NfcAdapter mNfcAdapter;
 
+    private WifiP2pEnabler mWifiP2pEnabler;
+
     /**
      * Invoked on each preference click in this hierarchy, overrides
      * PreferenceActivity's implementation.  Used to make sure we track the
@@ -98,6 +102,8 @@
         CheckBoxPreference nfc = (CheckBoxPreference) findPreference(KEY_TOGGLE_NFC);
         PreferenceScreen ndefPush = (PreferenceScreen) findPreference(KEY_NDEF_PUSH_SETTINGS);
 
+        CheckBoxPreference wifiP2p = (CheckBoxPreference) findPreference(KEY_TOGGLE_WIFI_P2P);
+
         mAirplaneModeEnabler = new AirplaneModeEnabler(activity, mAirplaneModePreference);
         mNfcEnabler = new NfcEnabler(activity, nfc, ndefPush);
 
@@ -133,6 +139,15 @@
             getPreferenceScreen().removePreference(findPreference(KEY_MOBILE_NETWORK_SETTINGS));
         }
 
+        WifiP2pManager p2p = (WifiP2pManager) activity.getSystemService(Context.WIFI_P2P_SERVICE);
+
+        if (!p2p.isP2pSupported()) {
+            getPreferenceScreen().removePreference(wifiP2p);
+        } else {
+            mWifiP2pEnabler = new WifiP2pEnabler(activity, wifiP2p);
+        }
+
+        //Settings is used for debug alone
         if (!WIFI_P2P_DEBUG) {
             getPreferenceScreen().removePreference(findPreference(KEY_WIFI_P2P_SETTINGS));
         }
@@ -186,6 +201,10 @@
         if (mNfcEnabler != null) {
             mNfcEnabler.resume();
         }
+
+        if (mWifiP2pEnabler != null) {
+            mWifiP2pEnabler.resume();
+        }
     }
 
     @Override
@@ -196,6 +215,10 @@
         if (mNfcEnabler != null) {
             mNfcEnabler.pause();
         }
+
+        if (mWifiP2pEnabler != null) {
+            mWifiP2pEnabler.pause();
+        }
     }
 
     @Override
diff --git a/src/com/android/settings/bluetooth/BluetoothSettings.java b/src/com/android/settings/bluetooth/BluetoothSettings.java
index e18e48a..6899bc3 100755
--- a/src/com/android/settings/bluetooth/BluetoothSettings.java
+++ b/src/com/android/settings/bluetooth/BluetoothSettings.java
@@ -99,8 +99,8 @@
 
     @Override
     public void onActivityCreated(Bundle savedInstanceState) {
-        mActivityStarted = true;
         super.onActivityCreated(savedInstanceState);
+        mActivityStarted = (savedInstanceState == null);    // don't auto start scan after rotation
 
         mEmptyView = (TextView) getView().findViewById(android.R.id.empty);
         getListView().setEmptyView(mEmptyView);
diff --git a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
index 45621e5..5c85374 100644
--- a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
+++ b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
@@ -139,8 +139,7 @@
         if (null == localeList) {
             // The locale list is null if and only if the user dictionary service is
             // not present or disabled. In this case we need to remove the preference.
-            ((PreferenceGroup)findPreference("language_settings_category")).removePreference(
-                    userDictionaryPreference);
+            getPreferenceScreen().removePreference(userDictionaryPreference);
         } else if (localeList.size() <= 1) {
             userDictionaryPreference.setTitle(R.string.user_dict_single_settings_title);
             userDictionaryPreference.setFragment(UserDictionarySettings.class.getName());
diff --git a/src/com/android/settings/wifi/p2p/WifiP2pEnabler.java b/src/com/android/settings/wifi/p2p/WifiP2pEnabler.java
index 608aa02..b812d97 100644
--- a/src/com/android/settings/wifi/p2p/WifiP2pEnabler.java
+++ b/src/com/android/settings/wifi/p2p/WifiP2pEnabler.java
@@ -25,21 +25,19 @@
 import android.net.wifi.p2p.WifiP2pManager;
 import android.os.Handler;
 import android.os.Message;
+import android.preference.CheckBoxPreference;
 import android.preference.Preference;
 import android.provider.Settings;
 import android.util.Log;
-import android.widget.CompoundButton;
-import android.widget.Switch;
 
 /**
  * WifiP2pEnabler is a helper to manage the Wifi p2p on/off
  */
-public class WifiP2pEnabler implements CompoundButton.OnCheckedChangeListener {
+public class WifiP2pEnabler implements Preference.OnPreferenceChangeListener {
     private static final String TAG = "WifiP2pEnabler";
 
     private final Context mContext;
-    private Switch mSwitch;
-    private int mWifiP2pState;
+    private final CheckBoxPreference mCheckBox;
     private final IntentFilter mIntentFilter;
     private final Handler mHandler = new WifiP2pHandler();
     private WifiP2pManager mWifiP2pManager;
@@ -57,9 +55,9 @@
         }
     };
 
-    public WifiP2pEnabler(Context context, Switch switch_) {
+    public WifiP2pEnabler(Context context, CheckBoxPreference checkBox) {
         mContext = context;
-        mSwitch = switch_;
+        mCheckBox = checkBox;
 
         mWifiP2pManager = (WifiP2pManager) context.getSystemService(Context.WIFI_P2P_SERVICE);
         if (mWifiP2pManager != null) {
@@ -68,7 +66,7 @@
                 //Failure to set up connection
                 Log.e(TAG, "Failed to set up connection with wifi p2p service");
                 mWifiP2pManager = null;
-                mSwitch.setEnabled(false);
+                mCheckBox.setEnabled(false);
             }
         } else {
             Log.e(TAG, "mWifiP2pManager is null!");
@@ -80,48 +78,39 @@
     public void resume() {
         if (mWifiP2pManager == null) return;
         mContext.registerReceiver(mReceiver, mIntentFilter);
-        mSwitch.setOnCheckedChangeListener(this);
+        mCheckBox.setOnPreferenceChangeListener(this);
     }
 
     public void pause() {
         if (mWifiP2pManager == null) return;
         mContext.unregisterReceiver(mReceiver);
-        mSwitch.setOnCheckedChangeListener(null);
+        mCheckBox.setOnPreferenceChangeListener(null);
     }
 
-    public void setSwitch(Switch switch_) {
-        if (mSwitch == switch_) return;
-        mSwitch.setOnCheckedChangeListener(null);
-        mSwitch = switch_;
-        mSwitch.setOnCheckedChangeListener(this);
+    public boolean onPreferenceChange(Preference preference, Object value) {
 
-        mSwitch.setChecked(mWifiP2pState == WifiP2pManager.WIFI_P2P_STATE_ENABLED);
-    }
+        if (mWifiP2pManager == null) return false;
 
-    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
-
-        if (mWifiP2pManager == null) return;
-
-        if (isChecked) {
+        mCheckBox.setEnabled(false);
+        final boolean enable = (Boolean) value;
+        if (enable) {
             mWifiP2pManager.enableP2p(mChannel);
         } else {
             mWifiP2pManager.disableP2p(mChannel);
         }
+        return false;
     }
 
     private void handleP2pStateChanged(int state) {
-        mSwitch.setEnabled(true);
+        mCheckBox.setEnabled(true);
         switch (state) {
             case WifiP2pManager.WIFI_P2P_STATE_ENABLED:
-                mWifiP2pState = WifiP2pManager.WIFI_P2P_STATE_ENABLED;
-                mSwitch.setChecked(true);
+                mCheckBox.setChecked(true);
                 break;
             case WifiP2pManager.WIFI_P2P_STATE_DISABLED:
-                mWifiP2pState = WifiP2pManager.WIFI_P2P_STATE_DISABLED;
-                mSwitch.setChecked(false);
+                mCheckBox.setChecked(false);
                 break;
             default:
-                mWifiP2pState = WifiP2pManager.WIFI_P2P_STATE_DISABLED;
                 Log.e(TAG,"Unhandled wifi state " + state);
                 break;
         }
@@ -135,10 +124,10 @@
                     //Failure to set up connection
                     Log.e(TAG, "Lost connection with wifi p2p service");
                     mWifiP2pManager = null;
-                    mSwitch.setEnabled(false);
+                    mCheckBox.setEnabled(false);
                     break;
                 case WifiP2pManager.ENABLE_P2P_FAILED:
-                    mSwitch.setEnabled(true);
+                    mCheckBox.setEnabled(true);
                     break;
                 default:
                     //Ignore
diff --git a/src/com/android/settings/wifi/p2p/WifiP2pSettings.java b/src/com/android/settings/wifi/p2p/WifiP2pSettings.java
index 0656689..d832012 100644
--- a/src/com/android/settings/wifi/p2p/WifiP2pSettings.java
+++ b/src/com/android/settings/wifi/p2p/WifiP2pSettings.java
@@ -42,7 +42,6 @@
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
-import android.widget.Switch;
 
 import com.android.settings.R;
 import com.android.settings.SettingsPreferenceFragment;
@@ -66,7 +65,6 @@
     private final Handler mHandler = new WifiP2pHandler();
     private WifiP2pManager mWifiP2pManager;
     private WifiP2pManager.Channel mChannel;
-    private WifiP2pEnabler mWifiP2pEnabler;
     private WifiP2pDialog mConnectDialog;
     private OnClickListener mConnectListener;
     private OnClickListener mDisconnectListener;
@@ -121,25 +119,6 @@
             Log.e(TAG, "mWifiP2pManager is null !");
         }
 
-        Switch actionBarSwitch = new Switch(activity);
-
-        if (activity instanceof PreferenceActivity) {
-            PreferenceActivity preferenceActivity = (PreferenceActivity) activity;
-            if (preferenceActivity.onIsHidingHeaders() || !preferenceActivity.onIsMultiPane()) {
-                final int padding = activity.getResources().getDimensionPixelSize(
-                        R.dimen.action_bar_switch_padding);
-                actionBarSwitch.setPadding(0, 0, padding, 0);
-                activity.getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM,
-                        ActionBar.DISPLAY_SHOW_CUSTOM);
-                activity.getActionBar().setCustomView(actionBarSwitch, new ActionBar.LayoutParams(
-                            ActionBar.LayoutParams.WRAP_CONTENT,
-                            ActionBar.LayoutParams.WRAP_CONTENT,
-                            Gravity.CENTER_VERTICAL | Gravity.RIGHT));
-            }
-        }
-
-        mWifiP2pEnabler = new WifiP2pEnabler(activity, actionBarSwitch);
-
         //connect dialog listener
         mConnectListener = new OnClickListener() {
             @Override
@@ -171,9 +150,6 @@
     public void onResume() {
         super.onResume();
         getActivity().registerReceiver(mReceiver, mIntentFilter);
-        if (mWifiP2pEnabler != null) {
-            mWifiP2pEnabler.resume();
-        }
 
         if (mWifiP2pManager != null) mWifiP2pManager.discoverPeers(mChannel);
     }
@@ -181,9 +157,6 @@
     @Override
     public void onPause() {
         super.onPause();
-        if (mWifiP2pEnabler != null) {
-            mWifiP2pEnabler.pause();
-        }
         getActivity().unregisterReceiver(mReceiver);
     }