Merge "Fix 3395616: Show IME by default when seting/changing password" into honeycomb
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 67eed06..1ef8a46 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1064,6 +1064,7 @@
 
         <activity android:name="com.android.settings.accounts.AddAccountSettings"
             android:theme="@android:style/Theme.Translucent.NoTitleBar"
+            android:configChanges="orientation|keyboardHidden"
             android:label="@string/header_add_an_account">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
diff --git a/assets/html/en_us/tethering_bluetooth_help.html b/assets/html/en_us/tethering_bluetooth_help.html
new file mode 100644
index 0000000..eb181f8
--- /dev/null
+++ b/assets/html/en_us/tethering_bluetooth_help.html
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<html>
+<head>
+<style>
+P {
+    font-size: 14 px;
+    }
+B {
+	font-size: 16px;
+}
+A {
+	color: #OOC;
+}
+.style1 {
+	font-size: 16px;
+}
+</style>
+</head>
+<body>
+<p><b>Bluetooth tethering</b></p>
+<span class="style1">You can tether your Android device to your computer via a Bluetooth connection, to share your device's Internet connection with your computer</span>
+<ul>
+<li>Bluetooth tethering works with any computer or other device that can obtain an Internet connection via Bluetooth</li><br>
+<li>For more information, see <a href="http://www.android.com/tether#bluetooth">http://www.android.com/tether#bluetooth</a></li><br>
+</ul>
+</body>
+</html>
diff --git a/assets/html/en_us/tethering_help.html b/assets/html/en_us/tethering_help.html
index dfff700..e980b20 100644
--- a/assets/html/en_us/tethering_help.html
+++ b/assets/html/en_us/tethering_help.html
@@ -18,16 +18,24 @@
 </head>
 <body>
 <p><b>USB tethering</b></p>
-<span class="style1">You can tether your phone to your computer with a USB cable, to share your phone's internet connection with your computer</span>
+<span class="style1">You can tether your Android device to your computer with a USB cable, to share your device's Internet connection with your computer</span>
 <ul>
-<li>Tethering works with Windows Vista, Windows 7, and Linux</li><br>
-<li>You can't mount your phone's SD card on your computer when USB tethered</li><br>
+<li>USB tethering works with Windows Vista, Windows 7, and Linux</li><br>
+<li>If your device has an SD card or USB storage, you can't mount it on your computer when USB tethered</li><br>
 <li>For more information, including using USB tethering with other OSs, see <a href="http://www.android.com/tether#usb">http://www.android.com/tether#usb</a></li><br>
 </ul>
-<p><b>Portable Wi-Fi hotspot</b></p>
-<span class="style1">You can turn your phone into a portable Wi-Fi hotspot, to share your phone's internet connection with one or more computers or other devices</span>
+
+<p><b>Bluetooth tethering</b></p>
+<span class="style1">You can tether your Android device to your computer via a Bluetooth connection, to share your device's Internet connection with your computer</span>
 <ul>
-<li>When your phone is serving as a Wi-Fi hotspot, you can't use your phone's applications to access the internet via its Wi-Fi connection</li><br>
+<li>Bluetooth tethering works with any computer or other device that can obtain an Internet connection via Bluetooth</li><br>
+<li>For more information, see <a href="http://www.android.com/tether#bluetooth">http://www.android.com/tether#bluetooth</a></li><br>
+</ul>
+
+<p><b>Portable Wi-Fi hotspot</b></p>
+<span class="style1">You can turn your Android device into a portable Wi-Fi hotspot, to share your Android device's Internet connection with one or more computers or other devices</span>
+<ul>
+<li>When your device is serving as a Wi-Fi hotspot, you can't use your phone's applications to access the Internet via its Wi-Fi connection (but of course you remain connected to the Internet via your mobile data network)</li><br>
 <li>You configure the hotspot with the Wi-Fi hotspot settings</li><br>
 <li>For more information, visit <a href="http://www.android.com/tether#wifi">http://www.android.com/tether#wifi</a></li><br>
 </ul>
diff --git a/assets/html/en_us/tethering_usb_help.html b/assets/html/en_us/tethering_usb_help.html
index 23f39e5..b3dbf58 100644
--- a/assets/html/en_us/tethering_usb_help.html
+++ b/assets/html/en_us/tethering_usb_help.html
@@ -18,10 +18,10 @@
 </head>
 <body>
 <p><b>USB tethering</b></p>
-<span class="style1">You can tether your phone to your computer with a USB cable, to share your phone's internet connection with your computer</span>
+<span class="style1">You can tether your Android device to your computer with a USB cable, to share your device's Internet connection with your computer</span>
 <ul>
-<li>Tethering works with Windows Vista, Windows 7, and Linux</li><br>
-<li>You can't mount your phone's SD card on your computer when USB tethered</li><br>
+<li>USB tethering works with Windows Vista, Windows 7, and Linux</li><br>
+<li>If your device has an SD card or USB storage, you can't mount it on your computer when USB tethered</li><br>
 <li>For more information, including using USB tethering with other OSs, see <a href="http://www.android.com/tether#usb">http://www.android.com/tether#usb</a></li><br>
 </ul>
 </body>
diff --git a/assets/html/en_us/tethering_wifi_help.html b/assets/html/en_us/tethering_wifi_help.html
index fac231b..621f869 100644
--- a/assets/html/en_us/tethering_wifi_help.html
+++ b/assets/html/en_us/tethering_wifi_help.html
@@ -18,9 +18,9 @@
 </head>
 <body>
 <p><b>Portable Wi-Fi hotspot</b></p>
-<span class="style1">You can turn your phone into a portable Wi-Fi hotspot, to share your phone's internet connection with one or more computers or other devices</span>
+<span class="style1">You can turn your Android device into a portable Wi-Fi hotspot, to share your Android device's Internet connection with one or more computers or other devices</span>
 <ul>
-<li>When your phone is serving as a Wi-Fi hotspot, you can't use your phone's applications to access the internet via its Wi-Fi connection</li><br>
+<li>When your device is serving as a Wi-Fi hotspot, you can't use your phone's applications to access the Internet via its Wi-Fi connection (but of course you remain connected to the Internet via your mobile data network)</li><br>
 <li>You configure the hotspot with the Wi-Fi hotspot settings</li><br>
 <li>For more information, visit <a href="http://www.android.com/tether#wifi">http://www.android.com/tether#wifi</a></li><br>
 </ul>
diff --git a/res/layout/preference_bluetooth.xml b/res/layout/preference_bluetooth.xml
index d363dc9..bd437a9 100644
--- a/res/layout/preference_bluetooth.xml
+++ b/res/layout/preference_bluetooth.xml
@@ -31,7 +31,6 @@
         android:id="@+id/divider"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_marginRight="8dip"
         android:layout_gravity="center_vertical"
         android:src="@drawable/nav_divider"
          />
@@ -42,6 +41,8 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_gravity="center_vertical"
+        android:padding="8dip"
+        android:background="?android:attr/selectableItemBackground"
         android:src="@drawable/ic_bt_config" />
 
 </LinearLayout>
diff --git a/res/layout/preference_bluetooth_profile.xml b/res/layout/preference_bluetooth_profile.xml
index 03f598a..4b6f1dd 100644
--- a/res/layout/preference_bluetooth_profile.xml
+++ b/res/layout/preference_bluetooth_profile.xml
@@ -24,7 +24,6 @@
         android:id="@+id/divider"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_marginRight="8dip"
         android:layout_gravity="center_vertical"
         android:src="@drawable/nav_divider"
          />
@@ -35,6 +34,8 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_gravity="center_vertical"
+        android:padding="8dip"
+        android:background="?android:attr/selectableItemBackground"
         android:src="@drawable/icon" />
 
 </LinearLayout>
diff --git a/res/layout/user_dictionary_item.xml b/res/layout/user_dictionary_item.xml
index 926068f..3cdeb08 100644
--- a/res/layout/user_dictionary_item.xml
+++ b/res/layout/user_dictionary_item.xml
@@ -41,13 +41,10 @@
     <ImageView
             android:id="@+id/delete_button"
             android:layout_width="wrap_content"
-            android:layout_height="match_parent"
+            android:layout_height="wrap_content"
             android:layout_gravity="center"
-            android:paddingLeft="16dip"
-            android:paddingRight="16dip"
-            android:paddingTop="8dip"
-            android:paddingBottom="8dip"
+            android:padding="8dip"
             android:src="@drawable/ic_item_delete"
-            android:background="@android:drawable/list_selector_background"
+            android:background="?android:attr/selectableItemBackground"
         />
 </LinearLayout>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index eed510b..55c2be5 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -582,23 +582,51 @@
     <!-- In the security screen, the header title for settings related to  Passwords-->
     <string name="security_passwords_title">Passwords</string>
 
-    <string name="crypt_keeper_settings_title">Device encryption</string>
+    <string name="crypt_keeper_settings_title">Encryption</string>
 
-    <string name="crypt_keeper_encrypt_title">Encrypt data on device</string>
-    <string name="crypt_keeper_encrypt_summary">Requires you to set a device unlock pin or password</string>
+    <string name="crypt_keeper_encrypt_title" product="tablet">Encrypt tablet</string>
+    <string name="crypt_keeper_encrypt_title" product="default">Encrypt phone</string>
+
+    <string name="crypt_keeper_encrypt_summary" product="tablet">
+    Require a numeric PIN or password to decrypt your tablet each time you
+    power it on</string>
+    <string name="crypt_keeper_encrypt_summary" product="default">
+    Require a numeric PIN or password to decrypt your phone each time you
+    power it on</string>
     <string name="crypt_keeper_encrypted_summary">Encrypted</string>
 
     <string name="crypt_keeper_confirm_title">Confirm encryption</string>
 
     
-    <string name="crypt_keeper_desc" product="tablet">You can encrypt your accounts, settings, downloaded applications and their data, media, and other files. Once you encrypt your tablet, you can\'t unencrypt it except by performing a factory data reset, erasing all the data on your tablet.\n\nEncryption takes up to an hour. You must start with a charged battery and keep your tablet plugged in until encryption is complete. If you interrupt the encryption process, you will lose some or all of your data.</string>
-    <string name="crypt_keeper_desc" product="default">You can encrypt your accounts, settings, downloaded applications and their data, media, and other files. Once you encrypt your phone, you can\'t unencrypt it except by performing a factory data reset, erasing all the data on your phone.\n\nEncryption takes up to an hour. You must start with a charged battery and keep your phone plugged in until encryption is complete. If you interrupt the encryption process, you will lose some or all of your data.</string>
-
+    <string name="crypt_keeper_desc" product="tablet">
+    You can encrypt your accounts, settings, downloaded applications and their data,
+    media, and other files. Once you encrypt your tablet, you must enter a numeric PIN
+    or password to decrypt it each time you power it on: you can\'t unencrypt your tablet
+    except by performing a factory data reset, erasing all your data.\n\nEncryption takes
+    an hour or more. You must start with a charged battery and keep your tablet plugged in
+    until encryption is complete. If you interrupt the encryption process, you will lose
+    some or all of your data.</string>
+    <string name="crypt_keeper_desc" product="default">
+    You can encrypt your accounts, settings, downloaded applications and their data,
+    media, and other files. Once you encrypt your phone, you must enter a numeric PIN or
+    password to decrypt it each time you power it on: you can\'t unencrypt your phone
+    except by performing a factory data reset, erasing all your data.\n\nEncryption takes
+    an hour or more. You must start with a charged battery and keep your phone plugged in
+    until encryption is complete. If you interrupt the encryption process, you will lose
+    some or all of your data.</string>
     
     <string name="crypt_keeper_button_text" product="tablet">Encrypt tablet</string>
     <string name="crypt_keeper_button_text" product="default">Encrypt phone</string>
-    
-    <string name="crypt_keeper_final_desc">Encrypt user data? This operation is not reversible and may not be interrupted without loss of data! Encryption may take up to an hour.</string>
+
+    <string name="crypt_keeper_low_charge_text">Please charge your battery and try again.</string>
+    <string name="crypt_keeper_unplugged_text">Please plug in your charger and try again.</string>
+
+    <string name="crypt_keeper_final_desc" product="tablet">
+    Encrypt tablet? This operation is irreversible and if you interrupt it,
+    you will lose data! Encryption takes an hour or more.</string>
+    <string name="crypt_keeper_final_desc" product="phone">
+    Encrypt phone? This operation is irreversible and if you interrupt it,
+    you will lose data! Encryption takes an hour or more.</string>
     
     <string name="crypt_keeper_setup_title">Encrypting</string>
 
diff --git a/res/xml/application_settings.xml b/res/xml/application_settings.xml
index a06377d..4e77a93 100644
--- a/res/xml/application_settings.xml
+++ b/res/xml/application_settings.xml
@@ -19,32 +19,6 @@
         android:summary="@string/applications_settings_summary"
         android:key="applications_settings">
 
-    <CheckBoxPreference
-            android:key="toggle_install_applications"
-            android:title="@string/install_applications"
-            android:summaryOff="@string/install_unknown_applications"
-            android:summaryOn="@string/install_unknown_applications"
-            android:persistent="false" />
-
-    <ListPreference
-        android:key="app_install_location"
-        android:title="@string/app_install_location_title"
-        android:summary="@string/app_install_location_summary"
-        android:persistent="false"
-        android:entries="@array/app_install_location_entries"
-        android:entryValues="@array/app_install_location_values"/>
-
-    <!-- Disabled quick launch settings pending UI redesign.
-    <PreferenceScreen
-            android:key="quick_launch"
-            android:title="@string/quick_launch_title"
-            android:summary="@string/quick_launch_summary">
-        <intent android:action="android.intent.action.MAIN"
-                android:targetPackage="com.android.settings"
-                android:targetClass="com.android.settings.quicklaunch.QuickLaunchSettings" />
-    </PreferenceScreen>
-    -->
-
     <PreferenceScreen
             android:fragment="com.android.settings.applications.ManageApplications"
             android:title="@string/manageapplications_settings_title"
@@ -73,11 +47,38 @@
             android:summary="@string/power_usage_summary">
     </PreferenceScreen>
 
+    <CheckBoxPreference
+            android:key="toggle_install_applications"
+            android:title="@string/install_applications"
+            android:summaryOff="@string/install_unknown_applications"
+            android:summaryOn="@string/install_unknown_applications"
+            android:persistent="false" />
+
+    <ListPreference
+        android:key="app_install_location"
+        android:title="@string/app_install_location_title"
+        android:summary="@string/app_install_location_summary"
+        android:persistent="false"
+        android:entries="@array/app_install_location_entries"
+        android:entryValues="@array/app_install_location_values"/>
+
+    <!-- Disabled quick launch settings pending UI redesign.
+    <PreferenceScreen
+            android:key="quick_launch"
+            android:title="@string/quick_launch_title"
+            android:summary="@string/quick_launch_summary">
+        <intent android:action="android.intent.action.MAIN"
+                android:targetPackage="com.android.settings"
+                android:targetClass="com.android.settings.quicklaunch.QuickLaunchSettings" />
+    </PreferenceScreen>
+    -->
+
+
     <PreferenceScreen 
             android:title="@string/development_settings_title" 
             android:summary="@string/development_settings_summary"
             android:fragment="com.android.settings.DevelopmentSettings">
     </PreferenceScreen>
-    
+
 </PreferenceScreen>
 
diff --git a/res/xml/bluetooth_device_advanced.xml b/res/xml/bluetooth_device_advanced.xml
index b4a0978..6610a69 100644
--- a/res/xml/bluetooth_device_advanced.xml
+++ b/res/xml/bluetooth_device_advanced.xml
@@ -28,12 +28,6 @@
             android:order="20"
             android:persistent="false" />
 
-    <CheckBoxPreference
-            android:key="allow_incoming"
-            android:title="@string/bluetooth_device_advanced_enable_opp_title"
-            android:order="30"
-            android:persistent="false" />
-
     <Preference
             android:key="unpair"
             android:title="@string/bluetooth_device_context_unpair"
diff --git a/src/com/android/settings/AirplaneModeEnabler.java b/src/com/android/settings/AirplaneModeEnabler.java
index ccfe541..00c416f 100644
--- a/src/com/android/settings/AirplaneModeEnabler.java
+++ b/src/com/android/settings/AirplaneModeEnabler.java
@@ -20,6 +20,7 @@
 
 import android.content.Context;
 import android.content.Intent;
+import android.database.ContentObserver;
 import android.os.Handler;
 import android.os.Message;
 import android.os.SystemProperties;
@@ -51,6 +52,13 @@
         }
     };
 
+    private ContentObserver mAirplaneModeObserver = new ContentObserver(new Handler()) {
+        @Override
+        public void onChange(boolean selfChange) {
+            onAirplaneModeChanged();
+        }
+    };
+
     public AirplaneModeEnabler(Context context, CheckBoxPreference airplaneModeCheckBoxPreference) {
         
         mContext = context;
@@ -68,13 +76,17 @@
 
         mPhoneStateReceiver.registerIntent();
         mCheckBoxPref.setOnPreferenceChangeListener(this);
+        mContext.getContentResolver().registerContentObserver(
+                Settings.System.getUriFor(Settings.System.AIRPLANE_MODE_ON), true,
+                mAirplaneModeObserver);
     }
     
     public void pause() {
         mPhoneStateReceiver.unregisterIntent();
         mCheckBoxPref.setOnPreferenceChangeListener(null);
+        mContext.getContentResolver().unregisterContentObserver(mAirplaneModeObserver);
     }
-    
+
     public static boolean isAirplaneModeOn(Context context) {
         return Settings.System.getInt(context.getContentResolver(),
                 Settings.System.AIRPLANE_MODE_ON, 0) != 0;
@@ -84,7 +96,7 @@
         
         mCheckBoxPref.setSummary(enabling ? R.string.airplane_mode_turning_on
                 : R.string.airplane_mode_turning_off);
-        
+
         // Change the system setting
         Settings.System.putInt(mContext.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 
                                 enabling ? 1 : 0);
@@ -106,8 +118,8 @@
      * - mobile does not send failure notification, fail on timeout.
      */
     private void onAirplaneModeChanged() {
-        ServiceState serviceState = mPhoneStateReceiver.getServiceState();
-        boolean airplaneModeEnabled = serviceState.getState() == ServiceState.STATE_POWER_OFF;
+        boolean airplaneModeEnabled = isAirplaneModeOn(mContext);
+        mCheckBoxPref.setChecked(isAirplaneModeOn(mContext));
         mCheckBoxPref.setSummary(airplaneModeEnabled ? null : 
                 mContext.getString(R.string.airplane_mode_summary));            
     }
diff --git a/src/com/android/settings/SettingsPreferenceFragment.java b/src/com/android/settings/SettingsPreferenceFragment.java
index 09faf41..dd078ba 100644
--- a/src/com/android/settings/SettingsPreferenceFragment.java
+++ b/src/com/android/settings/SettingsPreferenceFragment.java
@@ -21,6 +21,7 @@
 import android.app.DialogFragment;
 import android.app.Fragment;
 import android.content.ContentResolver;
+import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.os.Bundle;
@@ -104,13 +105,37 @@
     }
 
     protected void removeDialog(int dialogId) {
-        if (mDialogFragment != null && mDialogFragment.getDialogId() == dialogId
-                && mDialogFragment.isVisible()) {
+        // mDialogFragment may not be visible yet in parent fragment's onResume().
+        // To be able to dismiss dialog at that time, don't check
+        // mDialogFragment.isVisible().
+        if (mDialogFragment != null && mDialogFragment.getDialogId() == dialogId) {
             mDialogFragment.dismiss();
         }
         mDialogFragment = null;
     }
 
+    /**
+     * Sets the OnCancelListener of the dialog shown. This method can only be
+     * called after showDialog(int) and before removeDialog(int). The method
+     * does nothing otherwise.
+     */
+    protected void setOnCancelListener(DialogInterface.OnCancelListener listener) {
+        if (mDialogFragment != null) {
+            mDialogFragment.mOnCancelListener = listener;
+        }
+    }
+
+    /**
+     * Sets the OnDismissListener of the dialog shown. This method can only be
+     * called after showDialog(int) and before removeDialog(int). The method
+     * does nothing otherwise.
+     */
+    protected void setOnDismissListener(DialogInterface.OnDismissListener listener) {
+        if (mDialogFragment != null) {
+            mDialogFragment.mOnDismissListener = listener;
+        }
+    }
+
     public static class SettingsDialogFragment extends DialogFragment {
         private static final String KEY_DIALOG_ID = "key_dialog_id";
         private static final String KEY_PARENT_FRAGMENT_ID = "key_parent_fragment_id";
@@ -119,6 +144,9 @@
 
         private Fragment mParentFragment;
 
+        private DialogInterface.OnCancelListener mOnCancelListener;
+        private DialogInterface.OnDismissListener mOnDismissListener;
+
         public SettingsDialogFragment() {
             /* do nothing */
         }
@@ -163,6 +191,21 @@
             return ((DialogCreatable) mParentFragment).onCreateDialog(mDialogId);
         }
 
+        @Override
+        public void onCancel(DialogInterface dialog) {
+            super.onCancel(dialog);
+            if (mOnCancelListener != null) {
+                mOnCancelListener.onCancel(dialog);
+            }
+        }
+
+        @Override
+        public void onDismiss(DialogInterface dialog) {
+            super.onDismiss(dialog);
+            if (mOnDismissListener != null) {
+                mOnDismissListener.onDismiss(dialog);
+            }
+        }
         public int getDialogId() {
             return mDialogId;
         }
diff --git a/src/com/android/settings/applications/RunningServiceDetails.java b/src/com/android/settings/applications/RunningServiceDetails.java
index eccff93..631e747 100644
--- a/src/com/android/settings/applications/RunningServiceDetails.java
+++ b/src/com/android/settings/applications/RunningServiceDetails.java
@@ -2,6 +2,7 @@
 
 import com.android.settings.R;
 
+import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.AlertDialog;
 import android.app.ApplicationErrorReport;
@@ -23,6 +24,7 @@
 import android.content.res.Resources;
 import android.os.Bundle;
 import android.os.Debug;
+import android.os.Handler;
 import android.os.SystemClock;
 import android.provider.Settings;
 import android.util.Log;
@@ -406,7 +408,15 @@
     }
     
     private void finish() {
-        getActivity().onBackPressed();
+        (new Handler()).post(new Runnable() {
+            @Override
+            public void run() {
+                Activity a = getActivity();
+                if (a != null) {
+                    a.onBackPressed();
+                }
+            }
+        });
     }
     
     @Override
diff --git a/src/com/android/settings/bluetooth/BluetoothProfilePreference.java b/src/com/android/settings/bluetooth/BluetoothProfilePreference.java
index 6be1480..c74012a 100644
--- a/src/com/android/settings/bluetooth/BluetoothProfilePreference.java
+++ b/src/com/android/settings/bluetooth/BluetoothProfilePreference.java
@@ -80,9 +80,9 @@
         } else {
             mProfileExpandView.setOnClickListener(this);
             mProfileExpandView.setTag(mProfile);
-
-            mProfileExpandView.setImageResource(mExpanded ? R.drawable.ic_preferences_expanded
-                : R.drawable.ic_preferences_collapsed);
+            mProfileExpandView.setImageResource(mExpanded
+                    ? com.android.internal.R.drawable.expander_open_holo_dark
+                    : com.android.internal.R.drawable.expander_close_holo_dark);
         }
     }
 
diff --git a/src/com/android/settings/bluetooth/BluetoothSettings.java b/src/com/android/settings/bluetooth/BluetoothSettings.java
index 2893ce3..c1fda6b 100644
--- a/src/com/android/settings/bluetooth/BluetoothSettings.java
+++ b/src/com/android/settings/bluetooth/BluetoothSettings.java
@@ -18,7 +18,10 @@
 
 import android.app.Activity;
 import android.bluetooth.BluetoothDevice;
+import android.content.Intent;
 import android.preference.CheckBoxPreference;
+import android.preference.Preference;
+import android.preference.PreferenceScreen;
 import android.util.Log;
 import android.view.View;
 
@@ -36,11 +39,16 @@
     private static final String KEY_BT_CHECKBOX = "bt_checkbox";
     private static final String KEY_BT_DISCOVERABLE = "bt_discoverable";
     private static final String KEY_BT_NAME = "bt_name";
+    private static final String KEY_BT_SHOW_RECEIVED = "bt_show_received_files";
 
     private BluetoothEnabler mEnabler;
     private BluetoothDiscoverableEnabler mDiscoverableEnabler;
     private BluetoothNamePreference mNamePreference;
 
+    /* Private intent to show the list of received files */
+    private static final String BTOPP_ACTION_OPEN_RECEIVED_FILES =
+            "android.btopp.intent.action.OPEN_RECEIVED_FILES";
+
     void addPreferencesForActivity(Activity activity) {
         addPreferencesFromResource(R.xml.bluetooth_settings);
 
@@ -75,6 +83,18 @@
         mEnabler.pause();
     }
 
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
+            Preference preference) {
+        if (KEY_BT_SHOW_RECEIVED.equals(preference.getKey())) {
+            Intent intent = new Intent(BTOPP_ACTION_OPEN_RECEIVED_FILES);
+            getActivity().sendBroadcast(intent);
+            return true;
+        }
+
+        return super.onPreferenceTreeClick(preferenceScreen, preference);
+    }
+
     public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice,
             int bondState) {
         if (bondState == BluetoothDevice.BOND_BONDED) {
diff --git a/src/com/android/settings/bluetooth/CachedBluetoothDevice.java b/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
index 8ddeef5..db20411 100644
--- a/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
+++ b/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
@@ -111,8 +111,10 @@
                     " newProfileState " + newProfileState);
         }
 
-        int newState = LocalBluetoothProfileManager.getProfileManager(mLocalManager,
-                profile).convertState(newProfileState);
+        final LocalBluetoothProfileManager pm =
+                LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
+        if (pm == null) return;
+        int newState = pm.convertState(newProfileState);
 
         if (newState == SettingsBtStatus.CONNECTION_STATUS_CONNECTED) {
             if (!mProfiles.contains(profile)) {
diff --git a/src/com/android/settings/bluetooth/DeviceProfilesSettings.java b/src/com/android/settings/bluetooth/DeviceProfilesSettings.java
index 479cbe0..f39eabd 100644
--- a/src/com/android/settings/bluetooth/DeviceProfilesSettings.java
+++ b/src/com/android/settings/bluetooth/DeviceProfilesSettings.java
@@ -58,7 +58,6 @@
     private CachedBluetoothDevice mCachedDevice;
 
     private PreferenceGroup mProfileContainer;
-    private CheckBoxPreference mAllowIncomingPref;
     private EditTextPreference mDeviceNamePref;
     private final HashMap<String,CheckBoxPreference> mAutoConnectPrefs
             = new HashMap<String,CheckBoxPreference>();
@@ -93,17 +92,6 @@
         getPreferenceScreen().setOrderingAsAdded(false);
 
         mProfileContainer = (PreferenceGroup) findPreference(KEY_PROFILE_CONTAINER);
-        mAllowIncomingPref = (CheckBoxPreference) findPreference(KEY_ALLOW_INCOMING);
-
-        // Configure incoming file transfer preference if device supports OPP
-        // or else remove the preference item
-        if (isObjectPushSupported(device)) {
-            mAllowIncomingPref.setChecked(isIncomingFileTransfersAllowed());
-            mAllowIncomingPref.setOnPreferenceChangeListener(this);
-        } else {
-            getPreferenceScreen().removePreference(mAllowIncomingPref);
-            mAllowIncomingPref = null;
-        }
 
         mDeviceNamePref = (EditTextPreference) findPreference(KEY_RENAME_DEVICE);
         mDeviceNamePref.setSummary(mCachedDevice.getName());
@@ -210,9 +198,7 @@
     }
 
     public boolean onPreferenceChange(Preference preference, Object newValue) {
-        if (preference == mAllowIncomingPref) {
-            setIncomingFileTransfersAllowed((Boolean) newValue);
-        } else if (preference == mDeviceNamePref) {
+        if (preference == mDeviceNamePref) {
             mCachedDevice.setName((String) newValue);
         } else if (preference instanceof CheckBoxPreference) {
             boolean autoConnect = (Boolean) newValue;
diff --git a/src/com/android/settings/deviceinfo/Memory.java b/src/com/android/settings/deviceinfo/Memory.java
index c3df2d5..3e0f0a2 100644
--- a/src/com/android/settings/deviceinfo/Memory.java
+++ b/src/com/android/settings/deviceinfo/Memory.java
@@ -311,19 +311,29 @@
                         }})
                     .setNegativeButton(R.string.cancel, null)
                     .setMessage(R.string.dlg_confirm_unmount_text)
-                    .setOnCancelListener(this)
                     .create();
         case DLG_ERROR_UNMOUNT:
                 return new AlertDialog.Builder(getActivity())
             .setTitle(R.string.dlg_error_unmount_title)
             .setNeutralButton(R.string.dlg_ok, null)
             .setMessage(R.string.dlg_error_unmount_text)
-            .setOnCancelListener(this)
             .create();
         }
         return null;
     }
 
+    @Override
+    protected void showDialog(int id) {
+        super.showDialog(id);
+
+        switch (id) {
+        case DLG_CONFIRM_UNMOUNT:
+        case DLG_ERROR_UNMOUNT:
+            setOnCancelListener(this);
+            break;
+        }
+    }
+
     private void doUnmount(boolean force) {
         // Present a toast here
         Toast.makeText(getActivity(), R.string.unmount_inform_text, Toast.LENGTH_SHORT).show();
diff --git a/src/com/android/settings/vpn/VpnEditor.java b/src/com/android/settings/vpn/VpnEditor.java
index 161d34b..f4f5828 100644
--- a/src/com/android/settings/vpn/VpnEditor.java
+++ b/src/com/android/settings/vpn/VpnEditor.java
@@ -78,14 +78,16 @@
             }
         }
 
-        mProfileEditor = getEditor(p);
-        mAddingProfile = TextUtils.isEmpty(p.getName());
-
-        initViewFor(p);
-
         Parcel parcel = Parcel.obtain();
         p.writeToParcel(parcel, 0);
         mOriginalProfileData = parcel.marshall();
+        parcel.setDataPosition(0);
+        VpnProfile profile = (VpnProfile) VpnProfile.CREATOR.createFromParcel(parcel);
+
+        mProfileEditor = getEditor(profile);
+        mAddingProfile = TextUtils.isEmpty(profile.getName());
+
+        initViewFor(profile);
 
         registerForContextMenu(getListView());
         setHasOptionsMenu(true);
diff --git a/src/com/android/settings/vpn/VpnSettings.java b/src/com/android/settings/vpn/VpnSettings.java
index 03687f2..318a5bf 100644
--- a/src/com/android/settings/vpn/VpnSettings.java
+++ b/src/com/android/settings/vpn/VpnSettings.java
@@ -106,12 +106,13 @@
     private static final String KEY_PREFIX_IPSEC_PSK = Credentials.VPN + 'i';
     private static final String KEY_PREFIX_L2TP_SECRET = Credentials.VPN + 'l';
 
+    private static List<VpnProfile> sVpnProfileList = new ArrayList<VpnProfile>();
+
     private PreferenceScreen mAddVpn;
     private PreferenceCategory mVpnListContainer;
 
     // profile name --> VpnPreference
     private Map<String, VpnPreference> mVpnPreferenceMap;
-    private List<VpnProfile> mVpnProfileList;
 
     // profile engaged in a connection
     private VpnProfile mActiveProfile;
@@ -131,7 +132,9 @@
 
     private int mConnectingErrorCode = NO_ERROR;
 
-    private Dialog mShowingDialog, mConnectDialog;
+    private Dialog mShowingDialog;
+
+    private boolean mConnectDialogShowing = false;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
@@ -190,12 +193,18 @@
     public void onPause() {
         // ignore vpn connectivity event
         mVpnManager.unregisterConnectivityReceiver(mConnectivityReceiver);
+        if ((mShowingDialog != null) && mShowingDialog.isShowing()) {
+            mShowingDialog.dismiss();
+            mShowingDialog = null;
+        }
         super.onPause();
     }
 
     @Override
     public void onResume() {
         super.onResume();
+        updatePreferenceMap();
+
         if (DEBUG)
             Log.d(TAG, "onResume");
 
@@ -207,21 +216,22 @@
             mUnlockAction = null;
             getActivity().runOnUiThread(action);
         }
-        if (mConnectDialog == null || !mConnectDialog.isShowing()) {
+
+        if (!mConnectDialogShowing) {
             checkVpnConnectionStatus();
         } else {
             // Dismiss the connect dialog in case there is another instance
             // trying to operate a vpn connection.
-            if (!mVpnManager.isIdle()) removeConnectDialog();
+            if (!mVpnManager.isIdle() || (mActiveProfile == null)) {
+                removeDialog(DIALOG_CONNECT);
+                checkVpnConnectionStatus();
+            }
         }
     }
 
     @Override
     public void onDestroyView() {
         unregisterForContextMenu(getListView());
-        if ((mShowingDialog != null) && mShowingDialog.isShowing()) {
-            mShowingDialog.dismiss();
-        }
         // This should be called after the procedure above as ListView inside this Fragment
         // will be deleted here.
         super.onDestroyView();
@@ -239,11 +249,36 @@
     }
 
     @Override
+    protected void showDialog(int dialogId) {
+        super.showDialog(dialogId);
+
+        if (dialogId == DIALOG_CONNECT) {
+            mConnectDialogShowing = true;
+            setOnDismissListener(new DialogInterface.OnDismissListener() {
+                public void onDismiss(DialogInterface dialog) {
+                    mConnectDialogShowing = false;
+                }
+            });
+        }
+        setOnCancelListener(new DialogInterface.OnCancelListener() {
+            public void onCancel(DialogInterface dialog) {
+                if (mActiveProfile != null) {
+                    changeState(mActiveProfile, VpnState.IDLE);
+                }
+                // Make sure onIdle() is called as the above changeState()
+                // may not be effective if the state is already IDLE.
+                // XXX: VpnService should broadcast non-IDLE state, say UNUSABLE,
+                // when an error occurs.
+                onIdle();
+            }
+        });
+    }
+
+    @Override
     public Dialog onCreateDialog (int id) {
         switch (id) {
             case DIALOG_CONNECT:
-                mConnectDialog = createConnectDialog();
-                return mConnectDialog;
+                return createConnectDialog();
 
             case DIALOG_SECRET_NOT_SET:
                 return createSecretNotSetDialog();
@@ -259,35 +294,17 @@
         }
     }
 
-    private void removeConnectDialog() {
-        if (mConnectDialog != null) {
-            mConnectDialog.dismiss();
-            mConnectDialog = null;
-            checkVpnConnectionStatus();
-        }
-    }
-
-    private class ConnectDialog extends AlertDialog {
-        public ConnectDialog(Context context) {
-            super(context);
-            setTitle(String.format(getString(R.string.vpn_connect_to),
-                    mConnectingActor.getProfile().getName()));
-            setButton(DialogInterface.BUTTON_POSITIVE,
-                    getString(R.string.vpn_connect_button),
-                    VpnSettings.this);
-            setButton(DialogInterface.BUTTON_NEGATIVE,
-                    getString(android.R.string.cancel),
-                    VpnSettings.this);
-            setView(mConnectingActor.createConnectView());
-        }
-        public void onBackPressed() {
-            changeState(mActiveProfile, VpnState.IDLE);
-            super.onBackPressed();
-        }
-    }
-
     private Dialog createConnectDialog() {
-        return new ConnectDialog(getActivity());
+        final Activity activity = getActivity();
+        return new AlertDialog.Builder(activity)
+                .setView(mConnectingActor.createConnectView())
+                .setTitle(String.format(activity.getString(R.string.vpn_connect_to),
+                        mConnectingActor.getProfile().getName()))
+                .setPositiveButton(activity.getString(R.string.vpn_connect_button),
+                        this)
+                .setNegativeButton(activity.getString(android.R.string.cancel),
+                        this)
+                .create();
     }
 
     private Dialog createReconnectDialog(int id) {
@@ -375,11 +392,6 @@
                             public void onClick(DialogInterface dialog, int w) {
                                 onIdle();
                             }
-                        })
-                .setOnCancelListener(new DialogInterface.OnCancelListener() {
-                            public void onCancel(DialogInterface dialog) {
-                                onIdle();
-                            }
                         });
     }
 
@@ -512,14 +524,10 @@
             String error = mConnectingActor.validateInputs(d);
             if (error == null) {
                 mConnectingActor.connect(d);
-                removeConnectDialog();
                 return;
             } else {
-                // dismissDialog(DIALOG_CONNECT);
-                removeConnectDialog();
-
-                final Activity activity = getActivity();
                 // show error dialog
+                final Activity activity = getActivity();
                 mShowingDialog = new AlertDialog.Builder(activity)
                         .setTitle(android.R.string.dialog_alert_title)
                         .setIcon(android.R.drawable.ic_dialog_alert)
@@ -533,16 +541,20 @@
                                     }
                                 })
                         .create();
+                // The profile state is "connecting". If we allow the dialog to
+                // be cancelable, then we need to clear the state in the
+                // onCancel handler.
+                mShowingDialog.setCancelable(false);
                 mShowingDialog.show();
             }
         } else {
-            removeConnectDialog();
+            changeState(mActiveProfile, VpnState.IDLE);
         }
     }
 
     private int getProfileIndexFromId(String id) {
         int index = 0;
-        for (VpnProfile p : mVpnProfileList) {
+        for (VpnProfile p : sVpnProfileList) {
             if (p.getId().equals(id)) {
                 return index;
             } else {
@@ -552,10 +564,10 @@
         return -1;
     }
 
-    // Replaces the profile at index in mVpnProfileList with p.
+    // Replaces the profile at index in sVpnProfileList with p.
     // Returns true if p's name is a duplicate.
     private boolean checkDuplicateName(VpnProfile p, int index) {
-        List<VpnProfile> list = mVpnProfileList;
+        List<VpnProfile> list = sVpnProfileList;
         VpnPreference pref = mVpnPreferenceMap.get(p.getName());
         if ((pref != null) && (index >= 0) && (index < list.size())) {
             // not a duplicate if p is to replace the profile at index
@@ -569,20 +581,24 @@
         return menuInfo.position - mVpnListContainer.getOrder() - 1;
     }
 
-    // position: position in mVpnProfileList
+    // position: position in sVpnProfileList
     private VpnProfile getProfile(int position) {
-        return ((position >= 0) ? mVpnProfileList.get(position) : null);
+        return ((position >= 0) ? sVpnProfileList.get(position) : null);
     }
 
-    // position: position in mVpnProfileList
+    // position: position in sVpnProfileList
     private void deleteProfile(final int position) {
-        if ((position < 0) || (position >= mVpnProfileList.size())) return;
+        if ((position < 0) || (position >= sVpnProfileList.size())) return;
+        final VpnProfile target = sVpnProfileList.get(position);
         DialogInterface.OnClickListener onClickListener =
                 new DialogInterface.OnClickListener() {
                     public void onClick(DialogInterface dialog, int which) {
-                        dialog.dismiss();
+                        // Double check if the target is still the one we want
+                        // to remove.
+                        VpnProfile p = sVpnProfileList.get(position);
+                        if (p != target) return;
                         if (which == OK_BUTTON) {
-                            VpnProfile p = mVpnProfileList.remove(position);
+                            sVpnProfileList.remove(position);
                             VpnPreference pref =
                                     mVpnPreferenceMap.remove(p.getName());
                             mVpnListContainer.removePreference(pref);
@@ -610,7 +626,7 @@
                     Double.doubleToLongBits(Math.random())));
             if (id.length() >= 8) break;
         }
-        for (VpnProfile p : mVpnProfileList) {
+        for (VpnProfile p : sVpnProfileList) {
             if (p.getId().equals(id)) {
                 setProfileId(profile);
                 return;
@@ -624,7 +640,7 @@
         processSecrets(p);
         saveProfileToStorage(p);
 
-        mVpnProfileList.add(p);
+        sVpnProfileList.add(p);
         addPreferenceFor(p, true);
         disableProfilePreferencesIfOneActive();
     }
@@ -646,10 +662,10 @@
         return pref;
     }
 
-    // index: index to mVpnProfileList
+    // index: index to sVpnProfileList
     private void replaceProfile(int index, VpnProfile p) throws IOException {
         Map<String, VpnPreference> map = mVpnPreferenceMap;
-        VpnProfile oldProfile = mVpnProfileList.set(index, p);
+        VpnProfile oldProfile = sVpnProfileList.set(index, p);
         VpnPreference pref = map.remove(oldProfile.getName());
         if (pref.mProfile != oldProfile) {
             throw new RuntimeException("inconsistent state!");
@@ -672,7 +688,9 @@
     }
 
     private void startVpnTypeSelection() {
-        ((PreferenceActivity)getActivity()).startPreferencePanel(
+        if (getActivity() == null) return;
+
+        ((PreferenceActivity) getActivity()).startPreferencePanel(
                 VpnTypeSelection.class.getCanonicalName(), null, R.string.vpn_type_title, null,
                 this, REQUEST_SELECT_VPN_TYPE);
     }
@@ -778,7 +796,6 @@
     private void changeState(VpnProfile p, VpnState state) {
         VpnState oldState = p.getState();
         if (oldState == state) return;
-
         p.setState(state);
         mVpnPreferenceMap.get(p.getName()).setSummary(
                 getProfileSummaryString(p));
@@ -816,7 +833,7 @@
     }
 
     private void onIdle() {
-        Log.d(TAG, "   onIdle()");
+        if (DEBUG) Log.d(TAG, "   onIdle()");
         mActiveProfile = null;
         mConnectingActor = null;
         enableProfilePreferences();
@@ -825,7 +842,7 @@
     private void disableProfilePreferencesIfOneActive() {
         if (mActiveProfile == null) return;
 
-        for (VpnProfile p : mVpnProfileList) {
+        for (VpnProfile p : sVpnProfileList) {
             switch (p.getState()) {
                 case CONNECTING:
                 case DISCONNECTING:
@@ -840,7 +857,7 @@
     }
 
     private void enableProfilePreferences() {
-        for (VpnProfile p : mVpnProfileList) {
+        for (VpnProfile p : sVpnProfileList) {
             mVpnPreferenceMap.get(p.getName()).setEnabled(true);
         }
     }
@@ -862,12 +879,23 @@
         Util.deleteFile(getProfileDir(p));
     }
 
-    private void retrieveVpnListFromStorage() {
+    private void updatePreferenceMap() {
         mVpnPreferenceMap = new LinkedHashMap<String, VpnPreference>();
-        mVpnProfileList = Collections.synchronizedList(
-                new ArrayList<VpnProfile>());
         mVpnListContainer.removeAll();
+        for (VpnProfile p : sVpnProfileList) {
+            addPreferenceFor(p, false);
+        }
+        // reset the mActiveProfile if the profile has been removed from the
+        // other instance.
+        if ((mActiveProfile != null)
+                && mVpnPreferenceMap.containsKey(mActiveProfile.getName())) {
+            onIdle();
+        }
+    }
 
+    private void retrieveVpnListFromStorage() {
+        // skip the loop if the profile is loaded already.
+        if (sVpnProfileList.size() > 0) return;
         File root = new File(PROFILES_ROOT);
         String[] dirs = root.list();
         if (dirs == null) return;
@@ -879,30 +907,25 @@
                 if (p == null) continue;
                 if (!checkIdConsistency(dir, p)) continue;
 
-                mVpnProfileList.add(p);
+                sVpnProfileList.add(p);
             } catch (IOException e) {
                 Log.e(TAG, "retrieveVpnListFromStorage()", e);
             }
         }
-        Collections.sort(mVpnProfileList, new Comparator<VpnProfile>() {
+        Collections.sort(sVpnProfileList, new Comparator<VpnProfile>() {
             public int compare(VpnProfile p1, VpnProfile p2) {
                 return p1.getName().compareTo(p2.getName());
             }
         });
-        // Delay adding preferences to mVpnListContainer until states are
-        // obtained so that the user won't see initial state transition.
-        for (VpnProfile p : mVpnProfileList) {
-            Preference pref = addPreferenceFor(p, false);
-        }
         disableProfilePreferencesIfOneActive();
     }
 
     private void checkVpnConnectionStatus() {
-        for (VpnProfile p : mVpnProfileList) {
+        for (VpnProfile p : sVpnProfileList) {
             changeState(p, mVpnManager.getState(p));
         }
         // make preferences appear
-        for (VpnProfile p : mVpnProfileList) {
+        for (VpnProfile p : sVpnProfileList) {
             VpnPreference pref = mVpnPreferenceMap.get(p.getName());
             mVpnListContainer.addPreference(pref);
         }
@@ -1074,6 +1097,8 @@
                 Log.d(TAG, "received connectivity: " + profileName
                         + ": connected? " + s
                         + "   err=" + mConnectingErrorCode);
+                // XXX: VpnService should broadcast non-IDLE state, say UNUSABLE,
+                // when an error occurs.
                 changeState(pref.mProfile, s);
             } else {
                 Log.e(TAG, "received connectivity: " + profileName
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index ccc40fb..2e26eba 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -265,7 +265,15 @@
                 }
                 return true;
             case MENU_ID_ADVANCED:
-                startFragment(this, AdvancedSettings.class.getCanonicalName(), -1, null);
+                if (getActivity() instanceof PreferenceActivity) {
+                    ((PreferenceActivity) getActivity()).startPreferencePanel(
+                            AdvancedSettings.class.getCanonicalName(),
+                            null,
+                            R.string.wifi_advanced_titlebar, null,
+                            this, 0);
+                } else {
+                    startFragment(this, AdvancedSettings.class.getCanonicalName(), -1, null);
+                }
                 return true;
         }
         return super.onOptionsItemSelected(item);