Merge "Add Settings item to select sound effects control panel."
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 77fd94e..4ce4fb9 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -227,21 +227,6 @@
                 android:resource="@id/bluetooth_settings" />
         </activity>
 
-        <activity android:name="Settings$AdvancedBluetoothSettingsActivity"
-                android:label="@string/bluetooth_advanced_settings_label"
-                android:targetActivity="Settings">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <action android:name="android.settings.ADVANCED_BLUETOOTH_SETTINGS" />
-                <category android:name="android.intent.category.VOICE_LAUNCH" />
-                <category android:name="android.intent.category.DEFAULT" />
-            </intent-filter>
-            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
-                android:value="com.android.settings.bluetooth.AdvancedBluetoothSettings" />
-            <meta-data android:name="com.android.settings.TOP_LEVEL_HEADER_ID"
-                android:resource="@id/bluetooth_settings" />
-        </activity>
-
         <activity android:name=".bluetooth.DevicePickerActivity"
                 android:theme="@android:style/Theme.Holo.DialogWhenLarge"
                 android:label="@string/device_picker"
@@ -775,6 +760,7 @@
                 android:label="@string/quick_launch_title">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
+                <action android:name="android.settings.QUICK_LAUNCH_SETTINGS" />
                 <action android:name="com.android.settings.QUICK_LAUNCH_SETTINGS" />
                 <category android:name="android.intent.category.VOICE_LAUNCH" />
                 <category android:name="android.intent.category.DEFAULT" />
@@ -948,7 +934,7 @@
                 android:label="@string/accessibility_tutorial_title"
                 android:configChanges="orientation"
                 android:immersive="true"
-                android:theme="@android:style/Theme.Holo">
+                android:theme="@android:style/Theme.Holo.NoActionBar">
             <intent-filter>
                 <action android:name="android.settings.ACCESSIBILITY_TUTORIAL" />
                 <category android:name="android.intent.category.DEFAULT" />
diff --git a/res/layout-sw600dp/accessibility_tutorial_container.xml b/res/layout-sw600dp/accessibility_tutorial_container.xml
index 2895a29..d649354 100644
--- a/res/layout-sw600dp/accessibility_tutorial_container.xml
+++ b/res/layout-sw600dp/accessibility_tutorial_container.xml
@@ -74,6 +74,7 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:orientation="vertical">
+
         <View
             android:layout_marginBottom="16dip"
             style="@style/AccessibilityTutorialDivider" />
@@ -81,25 +82,40 @@
         <LinearLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:orientation="horizontal"
-            android:gravity="right">
+            android:orientation="horizontal">
 
             <Button
-                android:id="@+id/back_button"
+                android:id="@+id/skip_button"
                 style="@style/AccessibilityTutorialButton"
-                android:text="@string/accessibility_tutorial_back" />
-
-            <Button
-                android:id="@+id/next_button"
-                style="@style/AccessibilityTutorialButton"
-                android:text="@string/accessibility_tutorial_next" />
-
-            <Button
-                android:id="@+id/finish_button"
-                style="@style/AccessibilityTutorialButton"
-                android:text="@string/accessibility_tutorial_finish"
+                android:text="@string/accessibility_tutorial_skip"
                 android:visibility="gone" />
 
+            <LinearLayout
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal"
+                android:gravity="right">
+
+                <Button
+                    android:id="@+id/back_button"
+                    style="@style/AccessibilityTutorialButton"
+                    android:text="@string/accessibility_tutorial_back"
+                    android:visibility="gone" />
+
+                <Button
+                    android:id="@+id/next_button"
+                    style="@style/AccessibilityTutorialButton"
+                    android:text="@string/accessibility_tutorial_next"
+                    android:visibility="gone" />
+
+                <Button
+                    android:id="@id/finish_button"
+                    style="@style/AccessibilityTutorialButton"
+                    android:text="@string/accessibility_tutorial_finish"
+                    android:visibility="gone" />
+
+            </LinearLayout>
+
         </LinearLayout>
 
     </LinearLayout>
diff --git a/res/layout/accessibility_tutorial_1.xml b/res/layout/accessibility_tutorial_1.xml
index 710e327..b2bb40d 100644
--- a/res/layout/accessibility_tutorial_1.xml
+++ b/res/layout/accessibility_tutorial_1.xml
@@ -19,8 +19,8 @@
     android:id="@+id/all_apps"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
-    android:columnWidth="72dip"
+    android:columnWidth="96dip"
     android:numColumns="auto_fit"
     android:verticalSpacing="10dip"
-    android:horizontalSpacing="10dip"
+    android:horizontalSpacing="20dip"
     android:stretchMode="columnWidth" />
\ No newline at end of file
diff --git a/res/layout/accessibility_tutorial_container.xml b/res/layout/accessibility_tutorial_container.xml
index e949d2a..4ee72f5 100644
--- a/res/layout/accessibility_tutorial_container.xml
+++ b/res/layout/accessibility_tutorial_container.xml
@@ -21,32 +21,6 @@
     android:layout_width="fill_parent">
 
     <LinearLayout
-        android:orientation="vertical"
-        android:layout_height="wrap_content"
-        android:layout_width="wrap_content"
-        android:paddingLeft="15dip"
-        android:paddingRight="15dip">
-
-        <TextView
-            android:id="@+id/title"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:textAppearance="@style/AccessibilityTutorialTitle"
-            android:layout_marginTop="11dip" />
-
-        <View
-            android:layout_width="fill_parent"
-            android:layout_height="1dip"
-            android:layout_gravity="center"
-            android:background="@color/divider_color"
-            android:layout_marginTop="14dip"
-            android:layout_marginBottom="13dip"
-            android:focusable="false"
-            android:clickable="false" />
-
-    </LinearLayout>
-
-    <LinearLayout
         android:id="@+id/content"
         android:orientation="vertical"
         android:layout_height="0dip"
@@ -88,28 +62,29 @@
         android:background="@android:drawable/bottom_bar">
 
         <Button
-            android:id="@+id/back_button"
-            android:layout_width="150dip"
-            android:layout_height="wrap_content"
-            android:layout_margin="5dip"
+            android:id="@+id/skip_button"
+            style="@style/AccessibilityTutorialButton"
             android:layout_alignParentLeft="true"
-            android:drawablePadding="3dip"
-            android:text="@string/accessibility_tutorial_back" />
+            android:text="@string/accessibility_tutorial_skip"
+            android:visibility="gone" />
+
+        <Button
+            android:id="@+id/back_button"
+            style="@style/AccessibilityTutorialButton"
+            android:layout_alignParentLeft="true"
+            android:text="@string/accessibility_tutorial_back"
+            android:visibility="gone" />
 
         <Button
             android:id="@+id/next_button"
-            android:layout_width="150dip"
-            android:layout_height="wrap_content"
-            android:layout_margin="5dip"
+            style="@style/AccessibilityTutorialButton"
             android:layout_alignParentRight="true"
-            android:drawablePadding="3dip"
-            android:text="@string/accessibility_tutorial_next" />
+            android:text="@string/accessibility_tutorial_next"
+            android:visibility="gone" />
 
         <Button
             android:id="@+id/finish_button"
-            android:layout_width="150dip"
-            android:layout_height="wrap_content"
-            android:layout_margin="5dip"
+            style="@style/AccessibilityTutorialButton"
             android:layout_alignParentRight="true"
             android:text="@string/accessibility_tutorial_finish"
             android:visibility="gone" />
diff --git a/res/layout/bluetooth_pin_confirm.xml b/res/layout/bluetooth_pin_confirm.xml
new file mode 100644
index 0000000..5a1b41b
--- /dev/null
+++ b/res/layout/bluetooth_pin_confirm.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.
+*/
+-->
+
+<ScrollView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_height="match_parent"
+    android:layout_width="match_parent">
+
+    <LinearLayout
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_height="match_parent"
+        android:layout_width="match_parent"
+        android:orientation="vertical">
+
+        <TextView
+            android:id="@+id/message"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="20dip"
+            android:layout_marginRight="20dip"
+            android:layout_marginTop="20dip"
+            android:layout_marginBottom="20dip"
+            android:gravity="center_vertical"
+            android:textAppearance="?android:attr/textAppearanceMedium" />
+
+    </LinearLayout>
+
+</ScrollView>
diff --git a/res/layout/bluetooth_pin_entry.xml b/res/layout/bluetooth_pin_entry.xml
index b0c1216..ef73a79 100644
--- a/res/layout/bluetooth_pin_entry.xml
+++ b/res/layout/bluetooth_pin_entry.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 /* 
-** Copyright 2008, The Android Open Source Project
+** 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.
@@ -30,23 +30,53 @@
 
         <TextView
             android:id="@+id/message"
-            android:layout_width="match_parent"
+            android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginLeft="20dip"
             android:layout_marginRight="20dip"
-            android:gravity="center_horizontal"
+            android:layout_marginTop="20dip"
+            android:layout_marginBottom="20dip"
+            android:gravity="center_vertical"
             android:textAppearance="?android:attr/textAppearanceMedium" />
 
         <EditText
             android:id="@+id/text"
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
-            android:layout_marginTop="20dip"
             android:layout_marginLeft="20dip"
             android:layout_marginRight="20dip"
             android:inputType="textPassword"
             android:singleLine="true" />
 
+        <TextView
+            android:id="@+id/pin_values_hint"
+            android:text="@string/bluetooth_pin_values_hint"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="20dip"
+            android:layout_marginRight="20dip"
+            android:gravity="center_vertical"
+            android:textAppearance="?android:attr/textAppearanceSmall" />
+
+        <CheckBox
+            android:id="@+id/alphanumeric_pin"
+            android:text="@string/bluetooth_enable_alphanumeric_pin"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="20dip"
+            android:layout_marginRight="20dip"
+            android:gravity="center"
+            android:textAppearance="?android:attr/textAppearanceSmall" />
+
+        <TextView
+            android:id="@+id/message_below_pin"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="20dip"
+            android:layout_marginRight="20dip"
+            android:gravity="center_vertical"
+            android:textAppearance="?android:attr/textAppearanceMedium" />
+
     </LinearLayout>
 
 </ScrollView>
diff --git a/res/menu/data_usage.xml b/res/menu/data_usage.xml
index ae18231..24b0de4 100644
--- a/res/menu/data_usage.xml
+++ b/res/menu/data_usage.xml
@@ -36,6 +36,10 @@
                 android:id="@+id/data_usage_menu_show_wifi"
                 android:title="@string/data_usage_menu_show_wifi"
                 android:checkable="true" />
+            <item
+                android:id="@+id/data_usage_menu_show_ethernet"
+                android:title="@string/data_usage_menu_show_ethernet"
+                android:checkable="true" />
         </menu>
     </item>
 </menu>
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 157a6c4..f2b939d 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -334,14 +334,6 @@
         <item>Never</item>
     </string-array>
 
-    <!-- Values for visibility_duration_entries matching constants in BluetoothSettings. Do not translate. -->
-    <string-array name="bluetooth_visibility_timeout_values" translatable="false">
-        <item>twomin</item>
-        <item>fivemin</item>
-        <item>onehour</item>
-        <item>never</item>
-    </string-array>
-
     <!-- Match this with drawable.wifi_signal. --> <skip />
     <!-- Wi-Fi settings. The signal strength a Wi-Fi network has. -->
     <string-array name="wifi_signal">
@@ -635,18 +627,22 @@
 
     <!-- Titles for app process limit preference. [CHAR LIMIT=35] -->
     <string-array name="app_process_limit_entries">
-        <item>No app process limit</item>
-        <item>Max 1 app process</item>
-        <item>Max 2 app processes</item>
-        <item>Max 3 app processes</item>
+        <item>Standard limit</item>
+        <item>No background processes</item>
+        <item>At most 1 process</item>
+        <item>At most 2 processes</item>
+        <item>At most 3 processes</item>
+        <item>At most 4 processes</item>
     </string-array>
 
     <!-- Values for app process limit preference. -->
     <string-array name="app_process_limit_values" translatable="false" >
+        <item>-1</item>
         <item>0</item>
         <item>1</item>
         <item>2</item>
         <item>3</item>
+        <item>4</item>
     </string-array>
 
     <!-- Match this with the constants in VpnProfile. --> <skip />
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 8e73839..b72dbae 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -191,14 +191,18 @@
     <string name="bluetooth">Bluetooth</string>
     <!-- Bluetooth settings screen, check box label when the Bluetooth device can be seen by others -->
     <string name="bluetooth_visibility">Discoverable</string>
-    <!-- Bluetooth settings screen, summary after selecting Discoverable check box -->
-    <string name="bluetooth_is_discoverable">Discoverable for <xliff:g id="discoverable_time_period">%1$s</xliff:g> seconds\u2026</string>
-    <!-- Bluetooth settings screen, Discoverable checkbox summary text when Discoverable duration is set to "forever" -->
-    <string name="bluetooth_is_discoverable_always">Discoverable</string>
+    <!-- Bluetooth settings screen, summary after selecting Discoverable check box [CHAR LIMIT=50] -->
+    <string name="bluetooth_is_discoverable">Visible to all nearby Bluetooth devices (<xliff:g id="discoverable_time_period">%1$s</xliff:g>)</string>
+    <!-- Bluetooth settings screen, summary when Discoverable duration is set to "forever" [CHAR LIMIT=50] -->
+    <string name="bluetooth_is_discoverable_always">Visible to all nearby Bluetooth devices</string>
+    <!-- Bluetooth settings screen, summary text when not discoverable and no paired devices [CHAR LIMIT=50] -->
+    <string name="bluetooth_not_visible_to_other_devices">Not visible to other Bluetooth devices</string>
+    <!-- Bluetooth settings screen, summary text when not discoverable with paired devices [CHAR LIMIT=50] -->
+    <string name="bluetooth_only_visible_to_paired_devices">Only visible to paired devices</string>
     <!-- Bluetooth settings screen, Discoverable checkbox summary text -->
     <string name="bluetooth_not_discoverable">Make device discoverable</string>
     <!-- Bluetooth settings screen, option name to pick discoverability timeout duration (a list dialog comes up) -->
-    <string name="bluetooth_visibility_timeout">Discoverable timeout</string>
+    <string name="bluetooth_visibility_timeout">Visibility timeout</string>
     <!-- Bluetooth settings screen, Discoverable timout list dialog summary text -->
     <string name="bluetooth_visibility_timeout_summary">Set how long device will be discoverable</string>
     <!-- Bluetooth settings screen, check box label whether or not to allow
@@ -216,8 +220,16 @@
     <string name="bluetooth_name_not_set">No name set, using account name</string>
     <!-- Bluetooth settings screen, menu item to scan for nearby bluetooth devices -->
     <string name="bluetooth_scan_for_devices">Scan for devices</string>
-    <!-- Bluetooth settings.  Message for disconnecting from a bluetooth device -->
-    <string name="bluetooth_disconnect_blank"><xliff:g id="device_name">%1$s</xliff:g> will be disconnected.</string>
+    <!-- Bluetooth settings screen, menu item to change this device's Bluetooth name. [CHAR LIMIT=30] -->
+    <string name="bluetooth_rename_device" product="tablet">Rename tablet</string>
+    <!-- Bluetooth settings screen, menu item to change this device's Bluetooth name. [CHAR LIMIT=30] -->
+    <string name="bluetooth_rename_device" product="default">Rename phone</string>
+    <!-- Bluetooth settings screen, confirmation button for rename device dialog. [CHAR LIMIT=20] -->
+    <string name="bluetooth_rename_button">Rename</string>
+    <!-- Bluetooth settings.  Dialog title to confirm disconnecting from all profiles of a device. [CHAR LIMIT=30] -->
+    <string name="bluetooth_disconnect_title">Disconnect?</string>
+    <!-- Bluetooth settings.  Message for disconnecting from all profiles of a bluetooth device. [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_disconnect_all_profiles">This will end your connection with:&lt;br>&lt;b><xliff:g id="device_name">%1$s</xliff:g>&lt;/b></string>
     <!-- Bluetooth settings.  Message when connected to a device -->
     <string name="bluetooth_connected">Connected</string>
     <!-- Bluetooth settings.  Message when a device is disconnected -->
@@ -234,8 +246,8 @@
     <string name="bluetooth_pairing">Pairing\u2026</string>
     <!--Bluetooth settings screen, summary text under individual Bluetooth devices when paired with one -->
     <string name="bluetooth_paired">Paired but not connected</string>
-    <!--Bluetooth settings screen, summary text under individual Bluetooth devices that are hands free or a headset -->
-    <string name="bluetooth_device">handsfree/headset</string>
+    <!--Bluetooth settings screen, summary text for Bluetooth device with no name -->
+    <string name="bluetooth_device">Unnamed Bluetooth device</string>
     <!--Bluetooth settings screen, text that appears in heading bar when scanning for devices -->
     <string name="progress_scanning">Searching</string>
     <!--Bluetooth settings screen, text that appears in heading bar when scanning for devices is finished, indicating that user can tap on a device to pair with it [CHAR LIMIT=20]-->
@@ -248,10 +260,8 @@
     <string name="bluetooth_notif_title">Pairing request</string>
     <!-- Notification message when a Bluetooth device wants to pair with us -->
     <string name="bluetooth_notif_message">Select to pair with <xliff:g id="device_name">%1$s</xliff:g></string>
-    <!-- Bluetooth settings screen, title of the item to show the list of received files [CHAR LIMIT=30] -->
-    <string name="bluetooth_show_received_files_title">Show received files</string>
-    <!-- Bluetooth settings screen, summary of the item to show the list of received files [CHAR LIMIT=50] -->
-    <string name="bluetooth_show_received_files_summary">Show the list of files received via Bluetooth</string>
+    <!-- Bluetooth settings screen, menu to show the list of received files [CHAR LIMIT=30] -->
+    <string name="bluetooth_show_received_files">Show received files</string>
 
     <!-- Strings for BluetoothDevicePicker -->
     <string name="device_picker">Bluetooth device picker</string>
@@ -913,24 +923,45 @@
     <!--Wireless controls screen, settings summary for the item tot ake you to the bluetooth settings screen -->
     <string name="bluetooth_settings_summary">Manage connections, set device name &amp; discoverability</string>
 
-    <!-- Title for the dialog to enter PIN.  -->
+    <!-- ======================================================================================= -->
+    <!-- Note: The opening brackets of HTML style tags are escaped (e.g. "<b>" is "&lt;b>") in   -->
+    <!--   the following resources to enable formatting followed by HTML styling, as described   -->
+    <!--   here:  http://developer.android.com/guide/topics/resources/string-resource.html       -->
+    <!-- ======================================================================================= -->
+
+    <!-- Title for the dialog to enter PIN. [CHAR LIMIT=40] -->
     <string name="bluetooth_pairing_request">Bluetooth pairing request</string>
-    <!-- Message when bluetooth dialog for pin entry is showing -->
-    <string name="bluetooth_enter_pin_msg">\nEnter PIN to pair with \u0022<xliff:g id="device_name">%1$s</xliff:g>\u0022. (Try 0000 or 1234.) You may need to enter the same PIN on the Bluetooth device.</string>
-    <!-- Message when bluetooth dialog for passkey entry is showing -->
-    <string name="bluetooth_enter_passkey_msg">\nEnter passkey to pair with \u0022<xliff:g id="device_name">%1$s</xliff:g>\u0022.</string>
-    <!-- Message when bluetooth dialog for confirmation of passkey is showing -->
-    <string name="bluetooth_confirm_passkey_msg">To pair with \u0022<xliff:g id="device_name">%1$s</xliff:g>\u0022, confirm that it is showing the passkey: <xliff:g id="passkey">%2$s</xliff:g>.</string>
+
+    <!-- Message when bluetooth dialog for pin entry is showing. [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_enter_pin_msg">To pair with:&lt;br>&lt;b><xliff:g id="device_name">%1$s</xliff:g>&lt;/b>&lt;br>&lt;br>Enter the device\'s required PIN:</string>
+
+    <!-- Message when bluetooth dialog for passkey entry is showing. [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_enter_passkey_msg">To pair with:&lt;br>&lt;b><xliff:g id="device_name">%1$s</xliff:g>&lt;/b>&lt;br>&lt;br>Enter the device\'s required passkey:</string>
+
+    <!-- Checkbox label for alphanumeric PIN entry (default is numeric PIN). [CHAR LIMIT=50] -->
+    <string name="bluetooth_enable_alphanumeric_pin">PIN contains letters or symbols</string>
+
+    <!-- Bluetooth PIN hint text (below the text entry box). [CHAR LIMIT=30] -->
+    <string name="bluetooth_pin_values_hint">Usually 0000 or 1234</string>
+
+    <!-- Pairing dialog text to remind user to enter the PIN on the other device. [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_enter_pin_other_device">You may also need to enter this PIN on the other device.</string>
+    <!-- Pairing dialog text to remind user to enter the passkey on the other device. [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_enter_passkey_other_device">You may also need to enter this passkey on the other device.</string>
+
+    <!-- Message for confirmation of passkey to complete pairing. [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_confirm_passkey_msg">To pair with:&lt;br>&lt;b><xliff:g id="device_name">%1$s</xliff:g>&lt;/b>&lt;br>&lt;br>Make sure it is showing this passkey:&lt;br>&lt;b><xliff:g id="passkey">%2$s</xliff:g>&lt;/b></string>
+
     <!-- Message when bluetooth incoming pairing request for (2.1 devices) dialog is showing -->
-    <string name="bluetooth_incoming_pairing_msg"><xliff:g id="device_name">%1$s</xliff:g>\nwants to pair.</string>
+    <string name="bluetooth_incoming_pairing_msg">From:&lt;br>&lt;b><xliff:g id="device_name">%1$s</xliff:g>&lt;/b>&lt;br>&lt;br>Pair with this device?</string>
+
     <!-- Message when bluetooth dialog when passkey or pin needs to be displayed. -->
-    <string name="bluetooth_display_passkey_pin_msg">Enter \u0022<xliff:g id="passkey">%2$s</xliff:g>\u0022 on \u0022<xliff:g id="device_name">%1$s</xliff:g>\u0022 to pair followed by return or enter. </string>
-    <!-- Button text for accepting an incoming pairing request -->
+    <string name="bluetooth_display_passkey_pin_msg">To pair with:&lt;br>&lt;b><xliff:g id="device_name">%1$s</xliff:g>&lt;/b>&lt;br>&lt;br>Type on it:&lt;br>&lt;b><xliff:g id="passkey">%2$s</xliff:g>&lt;/b>, then Return or Enter.</string>
+
+    <!-- Button text for accepting an incoming pairing request. [CHAR LIMIT=20] -->
     <string name="bluetooth_pairing_accept">Pair</string>
-    <!-- Button text for declining an incoming pairing request -->
-    <string name="bluetooth_pairing_decline">Don\u0027t Pair</string>
-    <!-- Generic string for remote Bluetooth device  -->
-    <string name="bluetooth_remote_device">bluetooth device</string>
+    <!-- Button text for declining an incoming pairing request. [CHAR LIMIT=20] -->
+    <string name="bluetooth_pairing_decline">Cancel</string>
 
     <!-- Title for BT error dialogs. -->
     <string name="bluetooth_error_title">Attention</string>
@@ -975,8 +1006,6 @@
     <string name="bluetooth_menu_advanced">Advanced</string>
     <!-- Bluetooth settings. Title of the advanced bluetooth settings screen [CHAR LIMIT=30]-->
     <string name="bluetooth_advanced_titlebar">Advanced Bluetooth</string>
-    <!-- Bluetooth Advanced settings.  Used as a label under the shortcut icon that goes to Bluetooth advanced settings. [CHAR LIMIT=20]-->
-    <string name="bluetooth_advanced_settings_label">Advanced Bluetooth</string>
     <!-- Bluetooth settings. Text displayed when Bluetooth is off and device list is empty [CHAR LIMIT=50]-->
     <string name="bluetooth_empty_list_bluetooth_off">To see devices, turn Bluetooth on.</string>
 
@@ -1620,8 +1649,10 @@
     <string name="status_msid_number">MSID</string>
     <!-- About phone, status item title.  The phone PRL Version of the current device.-->
     <string name="status_prl_version">PRL Version</string>
-    <!-- About phone, status item title.  The phone IMEI/MEID number of the current LTE/CDMA device.-->
-    <string name="status_meid_number">IMEI / MEID</string>
+    <!-- About phone, status item title.  The phone MEID number of the current LTE/CDMA device. [CHAR LIMIT=30] -->
+    <string name="status_meid_number">MEID</string>
+    <!-- About phone, status item title.  The ICCID of the current LTE device. [CHAR LIMIT=30] -->
+    <string name="status_icc_id">ICCID</string>
     <!-- About phone, status item title for the type of data phone network we're connected to, for example 3G or Edge or GPRS -->
     <string name="status_network_type">Mobile network type</string>
     <!-- About phone, status item title. The status of data access.  For example, the value may be "Connected" -->
@@ -3342,13 +3373,13 @@
     <string name="debug_applications_category">Applications</string>
 
     <!-- UI debug setting: immediately destroy activities? [CHAR LIMIT=25] -->
-    <string name="immediately_destroy_activities">Immediately destroy activities</string>
+    <string name="immediately_destroy_activities">Don\'t keep activities</string>
     <!-- UI debug setting: immediately destroy activities summary [CHAR LIMIT=50] -->
     <string name="immediately_destroy_activities_summary">Destroy every activity as soon as
             the user leaves it</string>
 
-    <!-- UI debug setting: limit number of running application processes [CHAR LIMIT=25] -->
-    <string name="app_process_limit_title">Application process limit</string>
+    <!-- UI debug setting: limit number of running background processes [CHAR LIMIT=25] -->
+    <string name="app_process_limit_title">Background process limit</string>
 
     <!-- Activity title for network data usage summary. [CHAR LIMIT=25] -->
     <string name="data_usage_summary_title">Data usage</string>
@@ -3362,6 +3393,8 @@
     <string name="data_usage_menu_split_4g">Split 4G usage</string>
     <!-- Title for checkbox menu option to show Wi-Fi data usage. [CHAR LIMIT=32] -->
     <string name="data_usage_menu_show_wifi">Show Wi-Fi usage</string>
+    <!-- Title for checkbox menu option to show Ethernet data usage. [CHAR LIMIT=32] -->
+    <string name="data_usage_menu_show_ethernet">Show Ethernet usage</string>
     <!-- Title for option to change data usage cycle day. [CHAR LIMIT=32] -->
     <string name="data_usage_change_cycle">Change cycle\u2026</string>
     <!-- Body of dialog prompting user to change numerical day of month that data usage cycle should reset. [CHAR LIMIT=64] -->
@@ -3376,6 +3409,8 @@
 
     <!-- Tab title for showing Wi-Fi data usage. [CHAR LIMIT=10] -->
     <string name="data_usage_tab_wifi">Wi-Fi</string>
+    <!-- Tab title for showing Ethernet data usage. [CHAR LIMIT=10] -->
+    <string name="data_usage_tab_ethernet">Ethernet</string>
     <!-- Tab title for showing combined mobile data usage. [CHAR LIMIT=10] -->
     <string name="data_usage_tab_mobile">Mobile</string>
     <!-- Tab title for showing 4G data usage. [CHAR LIMIT=10] -->
@@ -3526,7 +3561,7 @@
     <!-- Button label to exit the touch explorationtutorial. [CHAR LIMIT=10] -->
     <string name="accessibility_tutorial_finish">Finish</string>
     <!-- Button label to skip the touch exploration tutorial. [CHAR LIMIT=10] -->
-    <string name="accessibility_tutorial_skip">Skip</string>
+    <string name="accessibility_tutorial_skip">Skip tutorial</string>
 
     <!-- Title for touch exploration tutorial lesson 1. -->
     <string name="accessibility_tutorial_lesson_1_title">Exploring the screen</string>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index d214d48..e9405fb 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -158,6 +158,13 @@
         <item name="android:layout">@layout/preference_inputmethod</item>
         <item name="android:widgetLayout">@layout/preference_inputmethod_widget</item>
     </style>
+    
+    <style name="AcessibilityTutorialButton">
+        <item name="android:layout_width">150dip</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_margin">5dip</item>
+        <item name="android:drawablePadding">3dip</item>
+    </style>
 
     <style name="AccessibilityTutorialDivider">
         <item name="android:layout_width">match_parent</item>
diff --git a/res/xml/bluetooth_advanced_settings.xml b/res/xml/bluetooth_advanced_settings.xml
deleted file mode 100644
index 345b3bf..0000000
--- a/res/xml/bluetooth_advanced_settings.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
-        android:title="@string/bluetooth_advanced_titlebar">
-
-    <com.android.settings.bluetooth.BluetoothNamePreference
-        android:key="bt_name"
-        android:title="@string/bluetooth_device_name"
-        android:summary="@string/bluetooth_name_not_set"
-        android:dialogTitle="@string/bluetooth_device_name"
-        android:persistent="false"
-        android:singleLine="true" />
-
-    <CheckBoxPreference
-        android:key="bt_discoverable"
-        android:title="@string/bluetooth_visibility"
-        android:summaryOn="@string/bluetooth_is_discoverable"
-        android:summaryOff="@string/bluetooth_not_discoverable"
-        android:persistent="false" />
-
-    <ListPreference
-        android:key="bt_discoverable_timeout"
-        android:title="@string/bluetooth_visibility_timeout"
-        android:summary="@string/bluetooth_visibility_timeout_summary"
-        android:entries="@array/bluetooth_visibility_timeout_entries"
-        android:entryValues="@array/bluetooth_visibility_timeout_values" />
-
-    <Preference
-        android:key="bt_show_received_files"
-        android:title="@string/bluetooth_show_received_files_title"
-        android:summary="@string/bluetooth_show_received_files_summary" />
-
-</PreferenceScreen>
diff --git a/res/xml/device_info_status.xml b/res/xml/device_info_status.xml
index 369c565..19e22f4 100644
--- a/res/xml/device_info_status.xml
+++ b/res/xml/device_info_status.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,18 +17,48 @@
 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
         android:title="@string/device_status_activity_title">
 
-    <Preference android:key="battery_status" 
-        style="?android:attr/preferenceInformationStyle" 
+    <Preference android:key="battery_status"
+        style="?android:attr/preferenceInformationStyle"
         android:title="@string/battery_status_title"
         android:summary="@string/device_info_not_available"
         android:persistent="false" />
-    <Preference android:key="battery_level" 
-        style="?android:attr/preferenceInformationStyle" 
+    <Preference android:key="battery_level"
+        style="?android:attr/preferenceInformationStyle"
         android:title="@string/battery_level_title"
         android:summary="@string/device_info_not_available"
         android:persistent="false" />
-    <Preference android:key="number" 
-        style="?android:attr/preferenceInformationStyle" 
+    <Preference android:key="operator_name"
+        style="?android:attr/preferenceInformationStyle"
+        android:title="@string/status_operator"
+        android:summary="@string/device_info_not_available"
+        android:persistent="false" />
+    <Preference android:key="signal_strength"
+        style="?android:attr/preferenceInformationStyle"
+        android:title="@string/status_signal_strength"
+        android:summary="@string/device_info_not_available"
+        android:persistent="false" />
+    <Preference android:key="network_type"
+        style="?android:attr/preferenceInformationStyle"
+        android:title="@string/status_network_type"
+        android:summary="@string/device_info_not_available"
+        android:persistent="false" />
+    <Preference android:key="service_state"
+        style="?android:attr/preferenceInformationStyle"
+        android:title="@string/status_service_state"
+        android:summary="@string/device_info_not_available"
+        android:persistent="false" />
+    <Preference android:key="roaming_state"
+        style="?android:attr/preferenceInformationStyle"
+        android:title="@string/status_roaming"
+        android:summary="@string/device_info_not_available"
+        android:persistent="false" />
+    <Preference android:key="data_state"
+        style="?android:attr/preferenceInformationStyle"
+        android:title="@string/status_data_state"
+        android:summary="@string/device_info_not_available"
+        android:persistent="false" />
+    <Preference android:key="number"
+        style="?android:attr/preferenceInformationStyle"
         android:title="@string/status_number"
         android:summary="@string/device_info_not_available"
         android:persistent="false" />
@@ -50,58 +80,33 @@
         android:title="@string/status_meid_number"
         android:summary="@string/device_info_not_available"
         android:persistent="false" />
-    <Preference android:key="operator_name" 
-        style="?android:attr/preferenceInformationStyle" 
-        android:title="@string/status_operator"
-        android:summary="@string/device_info_not_available"
-        android:persistent="false" />
-    <Preference android:key="signal_strength"
-        style="?android:attr/preferenceInformationStyle" 
-        android:title="@string/status_signal_strength"
-        android:summary="@string/device_info_not_available"
-        android:persistent="false" />
-    <Preference android:key="network_type"
-        style="?android:attr/preferenceInformationStyle" 
-        android:title="@string/status_network_type"
-        android:summary="@string/device_info_not_available"
-        android:persistent="false" />
-    <Preference android:key="service_state" 
-        style="?android:attr/preferenceInformationStyle" 
-        android:title="@string/status_service_state"
-        android:summary="@string/device_info_not_available"
-        android:persistent="false" />
-    <Preference android:key="roaming_state" 
-        style="?android:attr/preferenceInformationStyle" 
-        android:title="@string/status_roaming"
-        android:summary="@string/device_info_not_available"
-        android:persistent="false" />
-    <Preference android:key="data_state"
-        style="?android:attr/preferenceInformationStyle" 
-        android:title="@string/status_data_state"
-        android:summary="@string/device_info_not_available"
-        android:persistent="false" />
-    <Preference android:key="imei" 
-        style="?android:attr/preferenceInformationStyle" 
+    <Preference android:key="imei"
+        style="?android:attr/preferenceInformationStyle"
         android:title="@string/status_imei"
         android:summary="@string/device_info_not_available"
         android:persistent="false" />
-    <Preference android:key="imei_sv" 
-        style="?android:attr/preferenceInformationStyle" 
+    <Preference android:key="imei_sv"
+        style="?android:attr/preferenceInformationStyle"
         android:title="@string/status_imei_sv"
         android:summary="@string/device_info_not_available"
         android:persistent="false" />
+    <Preference android:key="icc_id"
+        style="?android:attr/preferenceInformationStyle"
+        android:title="@string/status_icc_id"
+        android:summary="@string/device_info_not_available"
+        android:persistent="false" />
     <Preference android:key="wifi_ip_address"
         style="?android:attr/preferenceInformationStyle"
         android:title="@string/wifi_advanced_ip_address_title"
         android:summary="@string/device_info_not_available"
         android:persistent="false" />
     <Preference android:key="wifi_mac_address"
-        style="?android:attr/preferenceInformationStyle" 
+        style="?android:attr/preferenceInformationStyle"
         android:title="@string/status_wifi_mac_address"
         android:summary="@string/device_info_not_available"
         android:persistent="false" />
     <Preference android:key="bt_address"
-        style="?android:attr/preferenceInformationStyle" 
+        style="?android:attr/preferenceInformationStyle"
         android:title="@string/status_bt_address"
         android:summary="@string/device_info_not_available"
         android:persistent="false" />
@@ -111,7 +116,7 @@
         android:summary="@string/device_info_not_available"
         android:persistent="false" />
     <Preference android:key="up_time"
-        style="?android:attr/preferenceInformationStyle" 
+        style="?android:attr/preferenceInformationStyle"
         android:title="@string/status_up_time"
         android:summary="@string/device_info_not_available"
         android:persistent="false" />
diff --git a/src/com/android/settings/AccessibilityTutorialActivity.java b/src/com/android/settings/AccessibilityTutorialActivity.java
index be9b90d..5e65dcd 100644
--- a/src/com/android/settings/AccessibilityTutorialActivity.java
+++ b/src/com/android/settings/AccessibilityTutorialActivity.java
@@ -306,7 +306,7 @@
 
             findViewById(R.id.next_button).setOnHoverListener(this);
 
-            setPreviousVisible(false);
+            setSkipVisible(true);
         }
 
         @Override
@@ -350,6 +350,7 @@
                 final CharSequence nextText = getContext().getText(
                         R.string.accessibility_tutorial_next);
                 addInstruction(R.string.accessibility_tutorial_lesson_1_text_5, nextText);
+                setNextVisible(true);
             }
         }
 
@@ -403,8 +404,7 @@
             ((ListView) findViewById(R.id.list_view)).setAdapter(mAppsAdapter);
             ((ListView) findViewById(R.id.list_view)).setOnScrollListener(this);
 
-            setNextVisible(false);
-            setFinishVisible(true);
+            setBackVisible(true);
         }
 
         @Override
@@ -452,6 +452,7 @@
                             R.string.accessibility_tutorial_finish);
                     addInstruction(R.string.accessibility_tutorial_lesson_2_text_4, finishText);
                     setFlag(FLAG_COMPLETED_TUTORIAL, true);
+                    setFinishVisible(true);
                 } else if (mScrollCount == MORE_SCROLL_COUNT) {
                     addInstruction(R.string.accessibility_tutorial_lesson_2_text_3_more);
                 }
@@ -476,8 +477,8 @@
     private static abstract class TutorialModule extends FrameLayout implements OnClickListener {
         private final AccessibilityTutorialActivity mController;
         private final TextView mInstructions;
-        private final TextView mTitle;
-        private final Button mPrevious;
+        private final Button mSkip;
+        private final Button mBack;
         private final Button mNext;
         private final Button mFinish;
 
@@ -505,15 +506,23 @@
                     R.layout.accessibility_tutorial_container, this, true);
 
             mInstructions = (TextView) container.findViewById(R.id.instructions);
-            mTitle = (TextView) container.findViewById(R.id.title);
-            mTitle.setText(titleResId);
-            mPrevious = (Button) container.findViewById(R.id.back_button);
-            mPrevious.setOnClickListener(this);
+            mSkip = (Button) container.findViewById(R.id.skip_button);
+            mSkip.setOnClickListener(this);
+            mBack = (Button) container.findViewById(R.id.back_button);
+            mBack.setOnClickListener(this);
             mNext = (Button) container.findViewById(R.id.next_button);
             mNext.setOnClickListener(this);
             mFinish = (Button) container.findViewById(R.id.finish_button);
             mFinish.setOnClickListener(this);
 
+            final TextView title = (TextView) container.findViewById(R.id.title);
+
+            if (title != null) {
+                title.setText(titleResId);
+            }
+
+            controller.setTitle(titleResId);
+
             final ViewGroup contentHolder = (ViewGroup) container.findViewById(R.id.content);
             LayoutInflater.from(context).inflate(layoutResId, contentHolder, true);
         }
@@ -526,7 +535,6 @@
 
             mFlags = 0;
             mInstructions.setVisibility(View.GONE);
-            mTitle.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
 
             onShown();
         }
@@ -572,6 +580,9 @@
         @Override
         public void onClick(View v) {
             switch (v.getId()) {
+                case R.id.skip_button:
+                    mController.finish();
+                    break;
                 case R.id.back_button:
                     mController.previous();
                     break;
@@ -586,10 +597,6 @@
 
         public abstract void onShown();
 
-        protected void setFinishVisible(boolean visible) {
-            mFinish.setVisibility(visible ? VISIBLE : GONE);
-        }
-
         /**
          * Sets or removes the flag with the specified id.
          *
@@ -605,12 +612,20 @@
             }
         }
 
+        protected void setSkipVisible(boolean visible) {
+            mSkip.setVisibility(visible ? VISIBLE : GONE);
+        }
+
+        protected void setBackVisible(boolean visible) {
+            mBack.setVisibility(visible ? VISIBLE : GONE);
+        }
+
         protected void setNextVisible(boolean visible) {
             mNext.setVisibility(visible ? VISIBLE : GONE);
         }
 
-        protected void setPreviousVisible(boolean visible) {
-            mPrevious.setVisibility(visible ? VISIBLE : GONE);
+        protected void setFinishVisible(boolean visible) {
+            mFinish.setVisibility(visible ? VISIBLE : GONE);
         }
     }
 }
diff --git a/src/com/android/settings/BatteryInfo.java b/src/com/android/settings/BatteryInfo.java
index 2f9d50e..3e037cf 100644
--- a/src/com/android/settings/BatteryInfo.java
+++ b/src/com/android/settings/BatteryInfo.java
@@ -26,7 +26,6 @@
 import android.os.Handler;
 import android.os.IPowerManager;
 import android.os.Message;
-import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.text.format.DateUtils;
@@ -198,7 +197,6 @@
     private void updateBatteryStats() {
         long uptime = SystemClock.elapsedRealtime();
         mUptime.setText(DateUtils.formatElapsedTime(uptime / 1000));
-        
     }
     
 }
diff --git a/src/com/android/settings/DataUsageSummary.java b/src/com/android/settings/DataUsageSummary.java
index 739ed58..f7bb32f 100644
--- a/src/com/android/settings/DataUsageSummary.java
+++ b/src/com/android/settings/DataUsageSummary.java
@@ -16,6 +16,7 @@
 
 package com.android.settings;
 
+import static android.net.ConnectivityManager.TYPE_ETHERNET;
 import static android.net.ConnectivityManager.TYPE_MOBILE;
 import static android.net.ConnectivityManager.TYPE_WIMAX;
 import static android.net.NetworkPolicy.LIMIT_DISABLED;
@@ -29,6 +30,11 @@
 import static android.net.NetworkTemplate.MATCH_MOBILE_4G;
 import static android.net.NetworkTemplate.MATCH_MOBILE_ALL;
 import static android.net.NetworkTemplate.MATCH_WIFI;
+import static android.net.NetworkTemplate.buildTemplateEthernet;
+import static android.net.NetworkTemplate.buildTemplateMobile3gLower;
+import static android.net.NetworkTemplate.buildTemplateMobile4g;
+import static android.net.NetworkTemplate.buildTemplateMobileAll;
+import static android.net.NetworkTemplate.buildTemplateWifi;
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
 
 import android.animation.LayoutTransition;
@@ -62,6 +68,7 @@
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.SystemProperties;
 import android.preference.Preference;
 import android.provider.Settings;
 import android.telephony.TelephonyManager;
@@ -110,6 +117,8 @@
 import java.util.Collections;
 import java.util.Locale;
 
+import libcore.util.Objects;
+
 /**
  * Panel show data usage history across various networks, including options to
  * inspect based on usage cycle and control through {@link NetworkPolicy}.
@@ -118,10 +127,15 @@
     private static final String TAG = "DataUsage";
     private static final boolean LOGD = true;
 
+    // TODO: remove this testing code
+    private static final boolean TEST_RADIOS = false;
+    private static final String TEST_RADIOS_PROP = "test.radios";
+
     private static final String TAB_3G = "3g";
     private static final String TAB_4G = "4g";
     private static final String TAB_MOBILE = "mobile";
     private static final String TAB_WIFI = "wifi";
+    private static final String TAB_ETHERNET = "ethernet";
 
     private static final String TAG_CONFIRM_ROAMING = "confirmRoaming";
     private static final String TAG_CONFIRM_LIMIT = "confirmLimit";
@@ -143,6 +157,7 @@
 
     private static final String PREF_FILE = "data_usage";
     private static final String PREF_SHOW_WIFI = "show_wifi";
+    private static final String PREF_SHOW_ETHERNET = "show_ethernet";
 
     private SharedPreferences mPrefs;
 
@@ -176,6 +191,7 @@
     private View mAppRestrictView;
 
     private boolean mShowWifi = false;
+    private boolean mShowEthernet = false;
 
     private NetworkTemplate mTemplate = null;
 
@@ -215,6 +231,7 @@
         mPolicyEditor.read();
 
         mShowWifi = mPrefs.getBoolean(PREF_SHOW_WIFI, false);
+        mShowEthernet = mPrefs.getBoolean(PREF_SHOW_ETHERNET, false);
 
         setHasOptionsMenu(true);
     }
@@ -325,7 +342,9 @@
 
             @Override
             protected void onPostExecute(Void result) {
-                updateBody();
+                if (isAdded()) {
+                    updateBody();
+                }
             }
         }.execute();
     }
@@ -351,9 +370,22 @@
         split4g.setChecked(isMobilePolicySplit());
 
         final MenuItem showWifi = menu.findItem(R.id.data_usage_menu_show_wifi);
-        showWifi.setVisible(hasMobileRadio(context) && hasWifiRadio(context));
-        showWifi.setChecked(mShowWifi);
+        if (hasWifiRadio(context) && hasMobileRadio(context)) {
+            showWifi.setVisible(true);
+            showWifi.setChecked(mShowWifi);
+        } else {
+            showWifi.setVisible(false);
+            mShowWifi = true;
+        }
 
+        final MenuItem showEthernet = menu.findItem(R.id.data_usage_menu_show_ethernet);
+        if (hasEthernet(context) && hasMobileRadio(context)) {
+            showEthernet.setVisible(true);
+            showEthernet.setChecked(mShowEthernet);
+        } else {
+            showEthernet.setVisible(false);
+            mShowEthernet = true;
+        }
     }
 
     @Override
@@ -393,6 +425,13 @@
                 updateTabs();
                 return true;
             }
+            case R.id.data_usage_menu_show_ethernet: {
+                mShowEthernet = !item.isChecked();
+                mPrefs.edit().putBoolean(PREF_SHOW_ETHERNET, mShowEthernet).apply();
+                item.setChecked(mShowEthernet);
+                updateTabs();
+                return true;
+            }
         }
         return false;
     }
@@ -437,28 +476,31 @@
         if (mobileSplit && hasMobile4gRadio(context)) {
             mTabHost.addTab(buildTabSpec(TAB_3G, R.string.data_usage_tab_3g));
             mTabHost.addTab(buildTabSpec(TAB_4G, R.string.data_usage_tab_4g));
+        } else if (hasMobileRadio(context)) {
+            mTabHost.addTab(buildTabSpec(TAB_MOBILE, R.string.data_usage_tab_mobile));
         }
-
-        if (mShowWifi && hasWifiRadio(context) && hasMobileRadio(context)) {
-            if (!mobileSplit) {
-                mTabHost.addTab(buildTabSpec(TAB_MOBILE, R.string.data_usage_tab_mobile));
-            }
+        if (mShowWifi && hasWifiRadio(context)) {
             mTabHost.addTab(buildTabSpec(TAB_WIFI, R.string.data_usage_tab_wifi));
         }
+        if (mShowEthernet && hasEthernet(context)) {
+            mTabHost.addTab(buildTabSpec(TAB_ETHERNET, R.string.data_usage_tab_ethernet));
+        }
 
-        final boolean hasTabs = mTabWidget.getTabCount() > 0;
-        mTabWidget.setVisibility(hasTabs ? View.VISIBLE : View.GONE);
-        if (hasTabs) {
-            if (mIntentTab != null) {
-                // select default tab, which will kick off updateBody()
-                mTabHost.setCurrentTabByTag(mIntentTab);
+        final boolean multipleTabs = mTabWidget.getTabCount() > 1;
+        mTabWidget.setVisibility(multipleTabs ? View.VISIBLE : View.GONE);
+        if (mIntentTab != null) {
+            if (Objects.equal(mIntentTab, mTabHost.getCurrentTabTag())) {
+                updateBody();
             } else {
-                // select first tab, which will kick off updateBody()
+                mTabHost.setCurrentTabByTag(mIntentTab);
+            }
+            mIntentTab = null;
+        } else {
+            if (mTabHost.getCurrentTab() == 0) {
+                updateBody();
+            } else {
                 mTabHost.setCurrentTab(0);
             }
-        } else {
-            // no tabs visible; update body manually
-            updateBody();
         }
     }
 
@@ -501,17 +543,14 @@
         mBinding = true;
 
         final Context context = getActivity();
-        final String tabTag = mTabHost.getCurrentTabTag();
+        final String currentTab = mTabHost.getCurrentTabTag();
 
-        final String currentTab;
-        if (tabTag != null) {
-            currentTab = tabTag;
-        } else if (hasMobileRadio(context)) {
-            currentTab = TAB_MOBILE;
-        } else if (hasWifiRadio(context)) {
-            currentTab = TAB_WIFI;
+        if (currentTab == null) {
+            Log.w(TAG, "no tab selected; hiding body");
+            mListView.setVisibility(View.GONE);
+            return;
         } else {
-            throw new IllegalStateException("no mobile or wifi radios");
+            mListView.setVisibility(View.VISIBLE);
         }
 
         final boolean tabChanged = !currentTab.equals(mCurrentTab);
@@ -523,32 +562,36 @@
             // wifi doesn't have any controls
             mDataEnabledView.setVisibility(View.GONE);
             mDisableAtLimitView.setVisibility(View.GONE);
-            mTemplate = new NetworkTemplate(MATCH_WIFI, null);
+            mTemplate = buildTemplateWifi();
+
+        } else if (TAB_ETHERNET.equals(currentTab)) {
+            // ethernet doesn't have any controls
+            mDataEnabledView.setVisibility(View.GONE);
+            mDisableAtLimitView.setVisibility(View.GONE);
+            mTemplate = buildTemplateEthernet();
 
         } else {
-            // make sure we show for non-wifi
             mDataEnabledView.setVisibility(View.VISIBLE);
             mDisableAtLimitView.setVisibility(View.VISIBLE);
         }
 
-        final String subscriberId = getActiveSubscriberId(context);
         if (TAB_MOBILE.equals(currentTab)) {
             setPreferenceTitle(mDataEnabledView, R.string.data_usage_enable_mobile);
             setPreferenceTitle(mDisableAtLimitView, R.string.data_usage_disable_mobile_limit);
             mDataEnabled.setChecked(mConnService.getMobileDataEnabled());
-            mTemplate = new NetworkTemplate(MATCH_MOBILE_ALL, subscriberId);
+            mTemplate = buildTemplateMobileAll(getActiveSubscriberId(context));
 
         } else if (TAB_3G.equals(currentTab)) {
             setPreferenceTitle(mDataEnabledView, R.string.data_usage_enable_3g);
             setPreferenceTitle(mDisableAtLimitView, R.string.data_usage_disable_3g_limit);
             // TODO: bind mDataEnabled to 3G radio state
-            mTemplate = new NetworkTemplate(MATCH_MOBILE_3G_LOWER, subscriberId);
+            mTemplate = buildTemplateMobile3gLower(getActiveSubscriberId(context));
 
         } else if (TAB_4G.equals(currentTab)) {
             setPreferenceTitle(mDataEnabledView, R.string.data_usage_enable_4g);
             setPreferenceTitle(mDisableAtLimitView, R.string.data_usage_disable_4g_limit);
             // TODO: bind mDataEnabled to 4G radio state
-            mTemplate = new NetworkTemplate(MATCH_MOBILE_4G, subscriberId);
+            mTemplate = buildTemplateMobile4g(getActiveSubscriberId(context));
         }
 
         try {
@@ -801,10 +844,9 @@
             final boolean dataEnabled = isChecked;
             mDataEnabled.setChecked(dataEnabled);
 
-            switch (mTemplate.getMatchRule()) {
-                case MATCH_MOBILE_ALL: {
-                    mConnService.setMobileDataEnabled(dataEnabled);
-                }
+            final String currentTab = mCurrentTab;
+            if (TAB_MOBILE.equals(currentTab)) {
+                mConnService.setMobileDataEnabled(dataEnabled);
             }
         }
     };
@@ -937,8 +979,13 @@
     };
 
     private boolean isMobilePolicySplit() {
-        final String subscriberId = getActiveSubscriberId(getActivity());
-        return mPolicyEditor.isMobilePolicySplit(subscriberId);
+        final Context context = getActivity();
+        if (hasMobileRadio(context)) {
+            final String subscriberId = getActiveSubscriberId(context);
+            return mPolicyEditor.isMobilePolicySplit(subscriberId);
+        } else {
+            return false;
+        }
     }
 
     private void setMobilePolicySplit(boolean split) {
@@ -1185,22 +1232,16 @@
             final Bundle args = new Bundle();
 
             // TODO: customize default limits based on network template
-            switch (parent.mTemplate.getMatchRule()) {
-                case MATCH_MOBILE_3G_LOWER: {
-                    args.putInt(EXTRA_MESSAGE_ID, R.string.data_usage_limit_dialog_3g);
-                    args.putLong(EXTRA_LIMIT_BYTES, 5 * GB_IN_BYTES);
-                    break;
-                }
-                case MATCH_MOBILE_4G: {
-                    args.putInt(EXTRA_MESSAGE_ID, R.string.data_usage_limit_dialog_4g);
-                    args.putLong(EXTRA_LIMIT_BYTES, 5 * GB_IN_BYTES);
-                    break;
-                }
-                case MATCH_MOBILE_ALL: {
-                    args.putInt(EXTRA_MESSAGE_ID, R.string.data_usage_limit_dialog_mobile);
-                    args.putLong(EXTRA_LIMIT_BYTES, 5 * GB_IN_BYTES);
-                    break;
-                }
+            final String currentTab = parent.mCurrentTab;
+            if (TAB_3G.equals(currentTab)) {
+                args.putInt(EXTRA_MESSAGE_ID, R.string.data_usage_limit_dialog_3g);
+                args.putLong(EXTRA_LIMIT_BYTES, 5 * GB_IN_BYTES);
+            } else if (TAB_4G.equals(currentTab)) {
+                args.putInt(EXTRA_MESSAGE_ID, R.string.data_usage_limit_dialog_4g);
+                args.putLong(EXTRA_LIMIT_BYTES, 5 * GB_IN_BYTES);
+            } else if (TAB_MOBILE.equals(currentTab)) {
+                args.putInt(EXTRA_MESSAGE_ID, R.string.data_usage_limit_dialog_mobile);
+                args.putLong(EXTRA_LIMIT_BYTES, 5 * GB_IN_BYTES);
             }
 
             final ConfirmLimitFragment dialog = new ConfirmLimitFragment();
@@ -1295,19 +1336,13 @@
         public static void show(DataUsageSummary parent) {
             final Bundle args = new Bundle();
 
-            switch (parent.mTemplate.getMatchRule()) {
-                case MATCH_MOBILE_3G_LOWER: {
-                    args.putInt(EXTRA_TITLE_ID, R.string.data_usage_disabled_dialog_3g_title);
-                    break;
-                }
-                case MATCH_MOBILE_4G: {
-                    args.putInt(EXTRA_TITLE_ID, R.string.data_usage_disabled_dialog_4g_title);
-                    break;
-                }
-                case MATCH_MOBILE_ALL: {
-                    args.putInt(EXTRA_TITLE_ID, R.string.data_usage_disabled_dialog_mobile_title);
-                    break;
-                }
+            final String currentTab = parent.mCurrentTab;
+            if (TAB_3G.equals(currentTab)) {
+                args.putInt(EXTRA_TITLE_ID, R.string.data_usage_disabled_dialog_3g_title);
+            } else if (TAB_4G.equals(currentTab)) {
+                args.putInt(EXTRA_TITLE_ID, R.string.data_usage_disabled_dialog_4g_title);
+            } else if (TAB_MOBILE.equals(currentTab)) {
+                args.putInt(EXTRA_TITLE_ID, R.string.data_usage_disabled_dialog_mobile_title);
             }
 
             final PolicyLimitFragment dialog = new PolicyLimitFragment();
@@ -1514,6 +1549,10 @@
      * Test if device has a mobile data radio.
      */
     private static boolean hasMobileRadio(Context context) {
+        if (TEST_RADIOS) {
+            return SystemProperties.get(TEST_RADIOS_PROP).contains("mobile");
+        }
+
         final ConnectivityManager conn = (ConnectivityManager) context.getSystemService(
                 Context.CONNECTIVITY_SERVICE);
 
@@ -1526,6 +1565,10 @@
      * Test if device has a mobile 4G data radio.
      */
     private static boolean hasMobile4gRadio(Context context) {
+        if (TEST_RADIOS) {
+            return SystemProperties.get(TEST_RADIOS_PROP).contains("4g");
+        }
+
         final ConnectivityManager conn = (ConnectivityManager) context.getSystemService(
                 Context.CONNECTIVITY_SERVICE);
         final TelephonyManager telephony = (TelephonyManager) context.getSystemService(
@@ -1542,10 +1585,27 @@
      * Test if device has a Wi-Fi data radio.
      */
     private static boolean hasWifiRadio(Context context) {
+        if (TEST_RADIOS) {
+            return SystemProperties.get(TEST_RADIOS_PROP).contains("wifi");
+        }
+
         return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI);
     }
 
     /**
+     * Test if device has an ethernet network connection.
+     */
+    private static boolean hasEthernet(Context context) {
+        if (TEST_RADIOS) {
+            return SystemProperties.get(TEST_RADIOS_PROP).contains("ethernet");
+        }
+
+        final ConnectivityManager conn = (ConnectivityManager) context.getSystemService(
+                Context.CONNECTIVITY_SERVICE);
+        return conn.getNetworkInfo(TYPE_ETHERNET) != null;
+    }
+
+    /**
      * Inflate a {@link Preference} style layout, adding the given {@link View}
      * widget into {@link android.R.id#widget_frame}.
      */
diff --git a/src/com/android/settings/DevelopmentSettings.java b/src/com/android/settings/DevelopmentSettings.java
index 9692dd5..380af3c 100644
--- a/src/com/android/settings/DevelopmentSettings.java
+++ b/src/com/android/settings/DevelopmentSettings.java
@@ -103,11 +103,14 @@
         mShowScreenUpdates = (CheckBoxPreference) findPreference(SHOW_SCREEN_UPDATES_KEY);
         mShowCpuUsage = (CheckBoxPreference) findPreference(SHOW_CPU_USAGE_KEY);
         mWindowAnimationScale = (ListPreference) findPreference(WINDOW_ANIMATION_SCALE_KEY);
+        mWindowAnimationScale.setOnPreferenceChangeListener(this);
         mTransitionAnimationScale = (ListPreference) findPreference(TRANSITION_ANIMATION_SCALE_KEY);
+        mTransitionAnimationScale.setOnPreferenceChangeListener(this);
 
         mImmediatelyDestroyActivities = (CheckBoxPreference) findPreference(
                 IMMEDIATELY_DESTROY_ACTIVITIES_KEY);
         mAppProcessLimit = (ListPreference) findPreference(APP_PROCESS_LIMIT_KEY);
+        mAppProcessLimit.setOnPreferenceChangeListener(this);
 
         removeHdcpOptionsForProduction();
     }
@@ -247,7 +250,7 @@
         Settings.System.putInt(getActivity().getContentResolver(),
                 Settings.System.SHOW_PROCESSES, value ? 1 : 0);
         Intent service = (new Intent())
-                .setClassName("android", "com.android.server.LoadAverageService");
+                .setClassName("com.android.systemui", "com.android.systemui.LoadAverageService");
         if (value) {
             getActivity().startService(service);
         } else {
@@ -276,10 +279,12 @@
                 float val = Float.parseFloat(values[i].toString());
                 if (scale <= val) {
                     pref.setValueIndex(i);
+                    pref.setSummary(pref.getEntries()[i]);
                     return;
                 }
             }
             pref.setValueIndex(values.length-1);
+            pref.setSummary(pref.getEntries()[0]);
         } catch (RemoteException e) {
         }
     }
@@ -289,10 +294,11 @@
         updateAnimationScaleValue(1, mTransitionAnimationScale);
     }
 
-    private void writeAnimationScaleOption(int which, ListPreference pref) {
+    private void writeAnimationScaleOption(int which, ListPreference pref, Object newValue) {
         try {
-            float scale = Float.parseFloat(pref.getValue().toString());
+            float scale = Float.parseFloat(newValue.toString());
             mWindowManager.setAnimationScale(which, scale);
+            updateAnimationScaleValue(which, pref);
         } catch (RemoteException e) {
         }
     }
@@ -305,18 +311,21 @@
                 int val = Integer.parseInt(values[i].toString());
                 if (val >= limit) {
                     mAppProcessLimit.setValueIndex(i);
+                    mAppProcessLimit.setSummary(mAppProcessLimit.getEntries()[i]);
                     return;
                 }
             }
             mAppProcessLimit.setValueIndex(0);
+            mAppProcessLimit.setSummary(mAppProcessLimit.getEntries()[0]);
         } catch (RemoteException e) {
         }
     }
 
-    private void writeAppProcessLimitOptions() {
+    private void writeAppProcessLimitOptions(Object newValue) {
         try {
-            int limit = Integer.parseInt(mAppProcessLimit.getValue().toString());
+            int limit = Integer.parseInt(newValue.toString());
             ActivityManagerNative.getDefault().setProcessLimit(limit);
+            updateAppProcessLimitOptions();
         } catch (RemoteException e) {
         }
     }
@@ -361,19 +370,32 @@
             writeFlingerOptions();
         } else if (preference == mShowCpuUsage) {
             writeCpuUsageOptions();
-        } else if (preference == mWindowAnimationScale) {
-            writeAnimationScaleOption(0, mWindowAnimationScale);
-        } else if (preference == mTransitionAnimationScale) {
-            writeAnimationScaleOption(1, mTransitionAnimationScale);
         } else if (preference == mImmediatelyDestroyActivities) {
             writeImmediatelyDestroyActivitiesOptions();
-        } else if (preference == mAppProcessLimit) {
-            writeAppProcessLimitOptions();
         }
 
         return false;
     }
 
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        if (HDCP_CHECKING_KEY.equals(preference.getKey())) {
+            SystemProperties.set(HDCP_CHECKING_PROPERTY, newValue.toString());
+            updateHdcpValues();
+            return true;
+        } else if (preference == mWindowAnimationScale) {
+            writeAnimationScaleOption(0, mWindowAnimationScale, newValue);
+            return true;
+        } else if (preference == mTransitionAnimationScale) {
+            writeAnimationScaleOption(1, mTransitionAnimationScale, newValue);
+            return true;
+        } else if (preference == mAppProcessLimit) {
+            writeAppProcessLimitOptions(newValue);
+            return true;
+        }
+        return false;
+    }
+
     private void dismissDialog() {
         if (mOkDialog == null) return;
         mOkDialog.dismiss();
@@ -403,14 +425,4 @@
         dismissDialog();
         super.onDestroy();
     }
-
-    @Override
-    public boolean onPreferenceChange(Preference preference, Object newValue) {
-        if (HDCP_CHECKING_KEY.equals(preference.getKey())) {
-            SystemProperties.set(HDCP_CHECKING_PROPERTY, newValue.toString());
-            updateHdcpValues();
-            return true;
-        }
-        return false;
-    }
 }
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 15366e8..eb0b40c 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -37,7 +37,9 @@
 import android.widget.Switch;
 import android.widget.TextView;
 
+import com.android.settings.accounts.ManageAccountsSettings;
 import com.android.settings.bluetooth.BluetoothEnabler;
+import com.android.settings.fuelgauge.PowerUsageSummary;
 import com.android.settings.wifi.WifiEnabler;
 
 import java.util.ArrayList;
@@ -285,7 +287,10 @@
                 titleRes, shortTitleRes);
 
         // some fragments would like a custom activity theme
-        if (DataUsageSummary.class.getName().equals(fragmentName)) {
+        if (DataUsageSummary.class.getName().equals(fragmentName) ||
+                PowerUsageSummary.class.getName().equals(fragmentName) ||
+                UserDictionarySettings.class.getName().equals(fragmentName) ||
+                ManageAccountsSettings.class.getName().equals(fragmentName)) {
             intent.putExtra(EXTRA_THEME, android.R.style.Theme_Holo_SolidActionBar);
         }
 
@@ -579,6 +584,5 @@
     public static class DeviceAdminSettingsActivity extends Settings { /* empty */ }
     public static class DataUsageSummaryActivity extends Settings { /* empty */ }
     public static class AdvancedWifiSettingsActivity extends Settings { /* empty */ }
-    public static class AdvancedBluetoothSettingsActivity extends Settings { /* empty */ }
     public static class TextToSpeechSettingsActivity extends Settings { /* empty */ }
 }
diff --git a/src/com/android/settings/UserDictionarySettings.java b/src/com/android/settings/UserDictionarySettings.java
index ea89a1b..e5002c9 100644
--- a/src/com/android/settings/UserDictionarySettings.java
+++ b/src/com/android/settings/UserDictionarySettings.java
@@ -207,7 +207,8 @@
         MenuItem actionItem =
                 menu.add(0, OPTIONS_MENU_ADD, 0, R.string.user_dict_settings_add_menu_title)
                 .setIcon(R.drawable.ic_menu_add);
-        actionItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+        actionItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM |
+                MenuItem.SHOW_AS_ACTION_WITH_TEXT);
     }
 
     @Override
diff --git a/src/com/android/settings/applications/RunningState.java b/src/com/android/settings/applications/RunningState.java
index e7e3af4..8ca17a5 100644
--- a/src/com/android/settings/applications/RunningState.java
+++ b/src/com/android/settings/applications/RunningState.java
@@ -776,6 +776,7 @@
         }
         
         // Look for services and their primary processes that no longer exist...
+        ArrayList<Integer> uidToDelete = null;
         for (int i=0; i<mServiceProcessesByName.size(); i++) {
             HashMap<String, ProcessItem> procs = mServiceProcessesByName.valueAt(i);
             Iterator<ProcessItem> pit = procs.values().iterator();
@@ -792,7 +793,10 @@
                     changed = true;
                     pit.remove();
                     if (procs.size() == 0) {
-                        mServiceProcessesByName.remove(mServiceProcessesByName.keyAt(i));
+                        if (uidToDelete == null) {
+                            uidToDelete = new ArrayList<Integer>();
+                        }
+                        uidToDelete.add(mServiceProcessesByName.keyAt(i));
                     }
                     if (pi.mPid != 0) {
                         mServiceProcessesByPid.remove(pi.mPid);
@@ -810,6 +814,13 @@
             }
         }
         
+        if (uidToDelete != null) {
+            for (int i = 0; i < uidToDelete.size(); i++) {
+                int uid = uidToDelete.get(i);
+                mServiceProcessesByName.remove(uid);
+            }
+        }
+
         if (changed) {
             // First determine an order for the services.
             ArrayList<ProcessItem> sortedProcesses = new ArrayList<ProcessItem>();
diff --git a/src/com/android/settings/bluetooth/AdvancedBluetoothSettings.java b/src/com/android/settings/bluetooth/AdvancedBluetoothSettings.java
deleted file mode 100644
index 83371cd..0000000
--- a/src/com/android/settings/bluetooth/AdvancedBluetoothSettings.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.settings.bluetooth;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.preference.CheckBoxPreference;
-import android.preference.ListPreference;
-import android.preference.Preference;
-import android.preference.PreferenceScreen;
-
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-
-public class AdvancedBluetoothSettings extends SettingsPreferenceFragment
-        implements Preference.OnPreferenceChangeListener {
-
-    private static final String KEY_BT_DISCOVERABLE = "bt_discoverable";
-    private static final String KEY_BT_DISCOVERABLE_TIMEOUT = "bt_discoverable_timeout";
-    private static final String KEY_BT_NAME = "bt_name";
-    private static final String KEY_BT_SHOW_RECEIVED = "bt_show_received_files";
-
-    /* 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";
-
-    private BluetoothDiscoverableEnabler mDiscoverableEnabler;
-    private BluetoothNamePreference mNamePreference;
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        addPreferencesFromResource(R.xml.bluetooth_advanced_settings);
-
-        LocalBluetoothManager localManager = LocalBluetoothManager.getInstance(getActivity());
-        if (localManager != null) {
-            LocalBluetoothAdapter localAdapter = localManager.getBluetoothAdapter();
-            mDiscoverableEnabler = new BluetoothDiscoverableEnabler(getActivity(),
-                    localAdapter,
-                    (CheckBoxPreference) findPreference(KEY_BT_DISCOVERABLE),
-                    (ListPreference) findPreference(KEY_BT_DISCOVERABLE_TIMEOUT));
-        }
-
-        mNamePreference = (BluetoothNamePreference) findPreference(KEY_BT_NAME);
-    }
-
-    @Override
-    public void onActivityCreated(Bundle savedInstanceState) {
-        super.onActivityCreated(savedInstanceState);
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        mDiscoverableEnabler.resume();
-        mNamePreference.resume();
-    }
-
-    @Override
-    public void onPause() {
-        super.onPause();
-
-        mNamePreference.pause();
-        mDiscoverableEnabler.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);
-    }
-
-    @Override
-    public boolean onPreferenceChange(Preference preference, Object newValue) {
-        return true;
-    }
-}
diff --git a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
index 06c708b..68180c6 100644
--- a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
+++ b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
@@ -24,6 +24,7 @@
 import android.content.DialogInterface;
 import android.graphics.drawable.Drawable;
 import android.preference.Preference;
+import android.text.Html;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.TypedValue;
@@ -200,7 +201,8 @@
         if (TextUtils.isEmpty(name)) {
             name = context.getString(R.string.bluetooth_device);
         }
-        String message = context.getString(R.string.bluetooth_disconnect_blank, name);
+        String message = context.getString(R.string.bluetooth_disconnect_all_profiles, name);
+        String title = context.getString(R.string.bluetooth_disconnect_title);
 
         DialogInterface.OnClickListener disconnectListener = new DialogInterface.OnClickListener() {
             public void onClick(DialogInterface dialog, int which) {
@@ -209,7 +211,7 @@
         };
 
         mDisconnectDialog = Utils.showDisconnectDialog(context,
-                mDisconnectDialog, disconnectListener, name, message);
+                mDisconnectDialog, disconnectListener, title, Html.fromHtml(message));
     }
 
     private void pair() {
@@ -221,7 +223,6 @@
 
     private int getConnectionSummary() {
         final CachedBluetoothDevice cachedDevice = mCachedDevice;
-        final BluetoothDevice device = cachedDevice.getDevice();
 
         // if any profiles are connected or busy, return that status
         for (LocalBluetoothProfile profile : cachedDevice.getProfiles()) {
diff --git a/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java b/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java
index 40bf5bc..0ad8948 100644
--- a/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java
+++ b/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java
@@ -21,11 +21,11 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.SharedPreferences;
 import android.os.Handler;
 import android.os.SystemProperties;
-import android.preference.CheckBoxPreference;
-import android.preference.ListPreference;
 import android.preference.Preference;
+import android.text.format.DateUtils;
 
 import com.android.settings.R;
 
@@ -34,7 +34,7 @@
  * checkbox. It sets/unsets discoverability and keeps track of how much time
  * until the the discoverability is automatically turned off.
  */
-final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceChangeListener {
+final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceClickListener {
 
     private static final String SYSTEM_PROPERTY_DISCOVERABLE_TIMEOUT =
             "debug.bt.discoverable_time";
@@ -44,6 +44,10 @@
     private static final int DISCOVERABLE_TIMEOUT_ONE_HOUR = 3600;
     static final int DISCOVERABLE_TIMEOUT_NEVER = 0;
 
+    // Bluetooth advanced settings screen was replaced with action bar items.
+    // Use the same preference key for discoverable timeout as the old ListPreference.
+    private static final String KEY_DISCOVERABLE_TIMEOUT = "bt_discoverable_timeout";
+
     private static final String VALUE_DISCOVERABLE_TIMEOUT_TWO_MINUTES = "twomin";
     private static final String VALUE_DISCOVERABLE_TIMEOUT_FIVE_MINUTES = "fivemin";
     private static final String VALUE_DISCOVERABLE_TIMEOUT_ONE_HOUR = "onehour";
@@ -53,11 +57,17 @@
 
     private final Context mContext;
     private final Handler mUiHandler;
-    private final CheckBoxPreference mCheckBoxPreference;
-    private final ListPreference mTimeoutListPreference;
+    private final Preference mDiscoveryPreference;
 
     private final LocalBluetoothAdapter mLocalAdapter;
 
+    private final SharedPreferences mSharedPreferences;
+
+    private boolean mDiscoverable;
+    private int mNumberOfPairedDevices;
+
+    private int mTimeoutSecs = -1;
+
     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -78,21 +88,13 @@
     };
 
     BluetoothDiscoverableEnabler(Context context, LocalBluetoothAdapter adapter,
-            CheckBoxPreference checkBoxPreference, ListPreference timeoutListPreference) {
+            Preference discoveryPreference) {
         mContext = context;
         mUiHandler = new Handler();
-        mCheckBoxPreference = checkBoxPreference;
-        mTimeoutListPreference = timeoutListPreference;
-
-        checkBoxPreference.setPersistent(false);
-        // we actually want to persist this since can't infer from BT device state
-        mTimeoutListPreference.setPersistent(true);
-
         mLocalAdapter = adapter;
-        if (adapter == null) {
-            // Bluetooth not supported
-            checkBoxPreference.setEnabled(false);
-        }
+        mDiscoveryPreference = discoveryPreference;
+        mSharedPreferences = discoveryPreference.getSharedPreferences();
+        discoveryPreference.setPersistent(false);
     }
 
     public void resume() {
@@ -102,8 +104,7 @@
 
         IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
         mContext.registerReceiver(mReceiver, filter);
-        mCheckBoxPreference.setOnPreferenceChangeListener(this);
-        mTimeoutListPreference.setOnPreferenceChangeListener(this);
+        mDiscoveryPreference.setOnPreferenceClickListener(this);
         handleModeChanged(mLocalAdapter.getScanMode());
     }
 
@@ -113,20 +114,14 @@
         }
 
         mUiHandler.removeCallbacks(mUpdateCountdownSummaryRunnable);
-        mCheckBoxPreference.setOnPreferenceChangeListener(null);
-        mTimeoutListPreference.setOnPreferenceChangeListener(null);
         mContext.unregisterReceiver(mReceiver);
+        mDiscoveryPreference.setOnPreferenceClickListener(null);
     }
 
-    public boolean onPreferenceChange(Preference preference, Object value) {
-        if (preference == mCheckBoxPreference) {
-            // Turn on/off BT discoverability
-            setEnabled((Boolean) value);
-        } else if (preference == mTimeoutListPreference) {
-            mTimeoutListPreference.setValue((String) value);
-            setEnabled(true);
-        }
-
+    public boolean onPreferenceClick(Preference preference) {
+        // toggle discoverability
+        mDiscoverable = !mDiscoverable;
+        setEnabled(mDiscoverable);
         return true;
     }
 
@@ -138,9 +133,8 @@
             long endTimestamp = System.currentTimeMillis() + timeout * 1000L;
             LocalBluetoothPreferences.persistDiscoverableEndTimestamp(mContext, endTimestamp);
 
-            updateCountdownSummary();
-
             mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, timeout);
+            updateCountdownSummary();
         } else {
             mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE);
         }
@@ -148,22 +142,51 @@
 
     private void updateTimerDisplay(int timeout) {
         if (getDiscoverableTimeout() == DISCOVERABLE_TIMEOUT_NEVER) {
-            mCheckBoxPreference.setSummaryOn(
-                mContext.getString(R.string.bluetooth_is_discoverable_always));
+            mDiscoveryPreference.setSummary(R.string.bluetooth_is_discoverable_always);
         } else {
-            mCheckBoxPreference.setSummaryOn(
-                mContext.getString(R.string.bluetooth_is_discoverable, timeout));
+            String textTimeout = DateUtils.formatElapsedTime(timeout);
+            mDiscoveryPreference.setSummary(mContext.getString(R.string.bluetooth_is_discoverable,
+                    textTimeout));
         }
     }
 
+    void setDiscoverableTimeout(int index) {
+        String timeoutValue;
+        switch (index) {
+            case 0:
+            default:
+                mTimeoutSecs = DISCOVERABLE_TIMEOUT_TWO_MINUTES;
+                timeoutValue = VALUE_DISCOVERABLE_TIMEOUT_TWO_MINUTES;
+                break;
+
+            case 1:
+                mTimeoutSecs = DISCOVERABLE_TIMEOUT_FIVE_MINUTES;
+                timeoutValue = VALUE_DISCOVERABLE_TIMEOUT_FIVE_MINUTES;
+                break;
+
+            case 2:
+                mTimeoutSecs = DISCOVERABLE_TIMEOUT_ONE_HOUR;
+                timeoutValue = VALUE_DISCOVERABLE_TIMEOUT_ONE_HOUR;
+                break;
+
+            case 3:
+                mTimeoutSecs = DISCOVERABLE_TIMEOUT_NEVER;
+                timeoutValue = VALUE_DISCOVERABLE_TIMEOUT_NEVER;
+                break;
+        }
+        mSharedPreferences.edit().putString(KEY_DISCOVERABLE_TIMEOUT, timeoutValue).apply();
+        setEnabled(true);   // enable discovery and reset timer
+    }
+
     private int getDiscoverableTimeout() {
+        if (mTimeoutSecs != -1) {
+            return mTimeoutSecs;
+        }
+
         int timeout = SystemProperties.getInt(SYSTEM_PROPERTY_DISCOVERABLE_TIMEOUT, -1);
         if (timeout < 0) {
-            String timeoutValue = mTimeoutListPreference.getValue();
-            if (timeoutValue == null) {
-                mTimeoutListPreference.setValue(VALUE_DISCOVERABLE_TIMEOUT_TWO_MINUTES);
-                return DISCOVERABLE_TIMEOUT_TWO_MINUTES;
-            }
+            String timeoutValue = mSharedPreferences.getString(KEY_DISCOVERABLE_TIMEOUT,
+                    VALUE_DISCOVERABLE_TIMEOUT_TWO_MINUTES);
 
             if (timeoutValue.equals(VALUE_DISCOVERABLE_TIMEOUT_NEVER)) {
                 timeout = DISCOVERABLE_TIMEOUT_NEVER;
@@ -175,16 +198,48 @@
                 timeout = DISCOVERABLE_TIMEOUT_TWO_MINUTES;
             }
         }
-
+        mTimeoutSecs = timeout;
         return timeout;
     }
 
-    private void handleModeChanged(int mode) {
+    int getDiscoverableTimeoutIndex() {
+        int timeout = getDiscoverableTimeout();
+        switch (timeout) {
+            case DISCOVERABLE_TIMEOUT_TWO_MINUTES:
+            default:
+                return 0;
+
+            case DISCOVERABLE_TIMEOUT_FIVE_MINUTES:
+                return 1;
+
+            case DISCOVERABLE_TIMEOUT_ONE_HOUR:
+                return 2;
+
+            case DISCOVERABLE_TIMEOUT_NEVER:
+                return 3;
+        }
+    }
+
+    void setNumberOfPairedDevices(int pairedDevices) {
+        mNumberOfPairedDevices = pairedDevices;
+        setSummaryNotDiscoverable();
+    }
+
+    void handleModeChanged(int mode) {
         if (mode == BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
-            mCheckBoxPreference.setChecked(true);
+            mDiscoverable = true;
             updateCountdownSummary();
         } else {
-            mCheckBoxPreference.setChecked(false);
+            mDiscoverable = false;
+            setSummaryNotDiscoverable();
+        }
+    }
+
+    private void setSummaryNotDiscoverable() {
+        if (mNumberOfPairedDevices != 0) {
+            mDiscoveryPreference.setSummary(R.string.bluetooth_only_visible_to_paired_devices);
+        } else {
+            mDiscoveryPreference.setSummary(R.string.bluetooth_not_visible_to_other_devices);
         }
     }
 
@@ -199,7 +254,7 @@
 
         if (currentTimestamp > endTimestamp) {
             // We're still in discoverable mode, but maybe there isn't a timeout.
-            mCheckBoxPreference.setSummaryOn(null);
+            updateTimerDisplay(0);
             return;
         }
 
diff --git a/src/com/android/settings/bluetooth/BluetoothNameDialogFragment.java b/src/com/android/settings/bluetooth/BluetoothNameDialogFragment.java
new file mode 100644
index 0000000..c00aff3
--- /dev/null
+++ b/src/com/android/settings/bluetooth/BluetoothNameDialogFragment.java
@@ -0,0 +1,161 @@
+/*
+ * 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.
+ */
+
+package com.android.settings.bluetooth;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.bluetooth.BluetoothAdapter;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.InputFilter;
+import android.text.TextWatcher;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+
+import com.android.settings.R;
+
+/**
+ * Dialog fragment for renaming the local Bluetooth device.
+ */
+final class BluetoothNameDialogFragment extends DialogFragment implements TextWatcher {
+    private static final int BLUETOOTH_NAME_MAX_LENGTH_BYTES = 248;
+
+    private AlertDialog mAlertDialog;
+    private Button mOkButton;
+
+    // accessed from inner class (not private to avoid thunks)
+    static final String TAG = "BluetoothNameDialogFragment";
+    final LocalBluetoothAdapter mLocalAdapter;
+    EditText mDeviceNameView;
+
+    // This flag is set when the name is updated by code, to distinguish from user changes
+    private boolean mDeviceNameUpdated;
+
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (action.equals(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED)) {
+                updateDeviceName();
+            } else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED) &&
+                    (intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR) ==
+                            BluetoothAdapter.STATE_ON)) {
+                updateDeviceName();
+            }
+        }
+    };
+
+    public BluetoothNameDialogFragment(LocalBluetoothAdapter adapter) {
+        mLocalAdapter = adapter;
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        mAlertDialog = new AlertDialog.Builder(getActivity())
+                .setIcon(android.R.drawable.ic_dialog_info)
+                .setTitle(R.string.bluetooth_rename_device)
+                .setView(createDialogView())
+                .setPositiveButton(R.string.bluetooth_rename_button,
+                        new DialogInterface.OnClickListener() {
+                            public void onClick(DialogInterface dialog, int which) {
+                                if (mLocalAdapter != null) {
+                                    String deviceName = mDeviceNameView.getText().toString();
+                                    Log.d(TAG, "Setting device name to " + deviceName);
+                                    mLocalAdapter.setName(deviceName);
+                                }
+                            }
+                        })
+                .setNegativeButton(android.R.string.cancel, null)
+                .create();
+
+        return mAlertDialog;
+    }
+
+    private View createDialogView() {
+        final LayoutInflater layoutInflater = (LayoutInflater)getActivity()
+            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        View view = layoutInflater.inflate(R.layout.dialog_edittext, null);
+        mDeviceNameView = (EditText) view.findViewById(R.id.edittext);
+        mDeviceNameView.setFilters(new InputFilter[] {
+                new Utf8ByteLengthFilter(BLUETOOTH_NAME_MAX_LENGTH_BYTES)
+        });
+        mDeviceNameView.addTextChangedListener(this);
+        return view;
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        mAlertDialog = null;
+        mDeviceNameView = null;
+        mOkButton = null;
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        if (mOkButton == null) {
+            mOkButton = mAlertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
+            mOkButton.setEnabled(false);    // Ok button is enabled when the user edits the name
+        }
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
+        filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
+        getActivity().registerReceiver(mReceiver, filter);
+        updateDeviceName();
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        getActivity().unregisterReceiver(mReceiver);
+    }
+
+    void updateDeviceName() {
+        if (mLocalAdapter != null && mLocalAdapter.isEnabled()) {
+            mDeviceNameUpdated = true;
+            mDeviceNameView.setText(mLocalAdapter.getName());
+        }
+    }
+
+    public void afterTextChanged(Editable s) {
+        if (mDeviceNameUpdated) {
+            // Device name changed by code; disable Ok button until edited by user
+            mDeviceNameUpdated = false;
+            mOkButton.setEnabled(false);
+        } else {
+            mOkButton.setEnabled(s.length() != 0);
+        }
+    }
+
+    /* Not used */
+    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+    }
+
+    /* Not used */
+    public void onTextChanged(CharSequence s, int start, int before, int count) {
+    }
+}
diff --git a/src/com/android/settings/bluetooth/BluetoothNamePreference.java b/src/com/android/settings/bluetooth/BluetoothNamePreference.java
deleted file mode 100644
index f41689e..0000000
--- a/src/com/android/settings/bluetooth/BluetoothNamePreference.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.bluetooth;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-
-import android.bluetooth.BluetoothAdapter;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.preference.EditTextPreference;
-import android.text.Editable;
-import android.text.InputFilter;
-import android.text.TextWatcher;
-import android.util.AttributeSet;
-import android.widget.Button;
-import android.widget.EditText;
-
-/**
- * BluetoothNamePreference is the preference type for editing the device's
- * Bluetooth name. It asks the user for a name, and persists it via the
- * Bluetooth API.
- */
-public final class BluetoothNamePreference extends EditTextPreference implements TextWatcher {
-//    private static final String TAG = "BluetoothNamePreference";
-    private static final int BLUETOOTH_NAME_MAX_LENGTH_BYTES = 248;
-
-    private final LocalBluetoothAdapter mLocalAdapter;
-
-    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            if (action.equals(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED)) {
-                setSummaryToName();
-            } else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED) &&
-                    (intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR) ==
-                            BluetoothAdapter.STATE_ON)) {
-                setSummaryToName();
-            }
-        }
-    };
-
-    public BluetoothNamePreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-
-        mLocalAdapter = LocalBluetoothManager.getInstance(context).getBluetoothAdapter();
-
-        setSummaryToName();
-    }
-
-    public void resume() {
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
-        filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
-        getContext().registerReceiver(mReceiver, filter);
-
-        // Make sure the OK button is disabled (if necessary) after rotation
-        EditText et = getEditText();
-        if (et != null) {
-            et.setFilters(new InputFilter[] {
-                    new Utf8ByteLengthFilter(BLUETOOTH_NAME_MAX_LENGTH_BYTES)
-            });
-
-            et.addTextChangedListener(this);
-            Dialog d = getDialog();
-            if (d instanceof AlertDialog) {
-                Button b = ((AlertDialog) d).getButton(AlertDialog.BUTTON_POSITIVE);
-                b.setEnabled(et.getText().length() > 0);
-            }
-        }
-    }
-
-    public void pause() {
-        EditText et = getEditText();
-        if (et != null) {
-            et.removeTextChangedListener(this);
-        }
-        getContext().unregisterReceiver(mReceiver);
-    }
-
-    private void setSummaryToName() {
-        if (mLocalAdapter != null && mLocalAdapter.isEnabled()) {
-            setSummary(mLocalAdapter.getName());
-        }
-    }
-
-    @Override
-    protected boolean persistString(String value) {
-        // Persist with Bluez instead of shared preferences
-        if (mLocalAdapter != null) {
-            mLocalAdapter.setName(value);
-        }
-        return true;
-    }
-
-    @Override
-    protected void onClick() {
-        super.onClick();
-
-        // The dialog should be created by now
-        EditText et = getEditText();
-        if (et != null && mLocalAdapter != null) {
-            et.setText(mLocalAdapter.getName());
-        }
-    }
-
-    // TextWatcher interface
-    public void afterTextChanged(Editable s) {
-        Dialog d = getDialog();
-        if (d instanceof AlertDialog) {
-            ((AlertDialog) d).getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(s.length() > 0);
-        }
-    }
-
-    // TextWatcher interface
-    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-        // not used
-    }
-
-    // TextWatcher interface
-    public void onTextChanged(CharSequence s, int start, int before, int count) {
-        // not used
-    }
-
-}
diff --git a/src/com/android/settings/bluetooth/BluetoothPairingDialog.java b/src/com/android/settings/bluetooth/BluetoothPairingDialog.java
index 1b443c4..1ec8ff2 100644
--- a/src/com/android/settings/bluetooth/BluetoothPairingDialog.java
+++ b/src/com/android/settings/bluetooth/BluetoothPairingDialog.java
@@ -24,13 +24,17 @@
 import android.content.IntentFilter;
 import android.os.Bundle;
 import android.text.Editable;
+import android.text.Html;
 import android.text.InputFilter;
 import android.text.InputType;
+import android.text.Spanned;
 import android.text.TextWatcher;
 import android.text.InputFilter.LengthFilter;
 import android.util.Log;
 import android.view.View;
 import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
 import android.widget.EditText;
 import android.widget.TextView;
 
@@ -42,8 +46,8 @@
  * BluetoothPairingDialog asks the user to enter a PIN / Passkey / simple confirmation
  * for pairing with a remote Bluetooth device. It is an activity that appears as a dialog.
  */
-public final class BluetoothPairingDialog extends AlertActivity implements DialogInterface.OnClickListener,
-        TextWatcher {
+public final class BluetoothPairingDialog extends AlertActivity implements
+        CompoundButton.OnCheckedChangeListener, DialogInterface.OnClickListener, TextWatcher {
     private static final String TAG = "BluetoothPairingDialog";
 
     private static final int BLUETOOTH_PIN_MAX_LENGTH = 16;
@@ -156,7 +160,7 @@
         final AlertController.AlertParams p = mAlertParams;
         p.mIconId = android.R.drawable.ic_dialog_info;
         p.mTitle = getString(R.string.bluetooth_pairing_request);
-        p.mView = createView(deviceManager);
+        p.mView = createPinEntryView(deviceManager.getName(mDevice));
         p.mPositiveButtonText = getString(android.R.string.ok);
         p.mPositiveButtonListener = this;
         p.mNegativeButtonText = getString(android.R.string.cancel);
@@ -167,56 +171,78 @@
         mOkButton.setEnabled(false);
     }
 
-    private View createView(CachedBluetoothDeviceManager deviceManager) {
+    private View createPinEntryView(String deviceName) {
         View view = getLayoutInflater().inflate(R.layout.bluetooth_pin_entry, null);
-        String name = deviceManager.getName(mDevice);
         TextView messageView = (TextView) view.findViewById(R.id.message);
+        TextView messageView2 = (TextView) view.findViewById(R.id.message_below_pin);
+        CheckBox alphanumericPin = (CheckBox) view.findViewById(R.id.alphanumeric_pin);
         mPairingView = (EditText) view.findViewById(R.id.text);
         mPairingView.addTextChangedListener(this);
+        alphanumericPin.setOnCheckedChangeListener(this);
 
+        int messageId1;
+        int messageId2;
+        int maxLength;
         switch (mType) {
             case BluetoothDevice.PAIRING_VARIANT_PIN:
-                messageView.setText(getString(R.string.bluetooth_enter_pin_msg, name));
-                // Maximum of 16 characters in a PIN adb sync
-                mPairingView.setFilters(new InputFilter[] {
-                        new LengthFilter(BLUETOOTH_PIN_MAX_LENGTH) });
+                messageId1 = R.string.bluetooth_enter_pin_msg;
+                messageId2 = R.string.bluetooth_enter_pin_other_device;
+                // Maximum of 16 characters in a PIN
+                maxLength = BLUETOOTH_PIN_MAX_LENGTH;
                 break;
 
             case BluetoothDevice.PAIRING_VARIANT_PASSKEY:
-                messageView.setText(getString(R.string.bluetooth_enter_passkey_msg, name));
+                messageId1 = R.string.bluetooth_enter_passkey_msg;
+                messageId2 = R.string.bluetooth_enter_passkey_other_device;
                 // Maximum of 6 digits for passkey
-                mPairingView.setInputType(InputType.TYPE_CLASS_NUMBER |
-                        InputType.TYPE_NUMBER_FLAG_SIGNED);
-                mPairingView.setFilters(new InputFilter[] {
-                        new LengthFilter(BLUETOOTH_PASSKEY_MAX_LENGTH)});
+                maxLength = BLUETOOTH_PASSKEY_MAX_LENGTH;
+                alphanumericPin.setVisibility(View.GONE);
                 break;
 
+            default:
+                Log.e(TAG, "Incorrect pairing type for createPinEntryView: " + mType);
+                return null;
+        }
+
+        // Format the message string, then parse HTML style tags
+        String messageText = getString(messageId1, deviceName);
+        messageView.setText(Html.fromHtml(messageText));
+        messageView2.setText(messageId2);
+        mPairingView.setInputType(InputType.TYPE_CLASS_NUMBER);
+        mPairingView.setFilters(new InputFilter[] {
+                new LengthFilter(maxLength) });
+
+        return view;
+    }
+
+    private View createView(CachedBluetoothDeviceManager deviceManager) {
+        View view = getLayoutInflater().inflate(R.layout.bluetooth_pin_confirm, null);
+        String name = deviceManager.getName(mDevice);
+        TextView messageView = (TextView) view.findViewById(R.id.message);
+
+        String messageText; // formatted string containing HTML style tags
+        switch (mType) {
             case BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION:
-                mPairingView.setVisibility(View.GONE);
-                messageView.setText(getString(R.string.bluetooth_confirm_passkey_msg, name,
-                        mPairingKey));
+                messageText = getString(R.string.bluetooth_confirm_passkey_msg,
+                        name, mPairingKey);
                 break;
 
             case BluetoothDevice.PAIRING_VARIANT_CONSENT:
-                mPairingView.setVisibility(View.GONE);
-                messageView.setText(getString(R.string.bluetooth_incoming_pairing_msg, name));
+            case BluetoothDevice.PAIRING_VARIANT_OOB_CONSENT:
+                messageText = getString(R.string.bluetooth_incoming_pairing_msg, name);
                 break;
 
             case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY:
             case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN:
-                mPairingView.setVisibility(View.GONE);
-                messageView.setText(getString(R.string.bluetooth_display_passkey_pin_msg, name,
-                        mPairingKey));
-                break;
-
-            case BluetoothDevice.PAIRING_VARIANT_OOB_CONSENT:
-                mPairingView.setVisibility(View.GONE);
-                messageView.setText(getString(R.string.bluetooth_incoming_pairing_msg, name));
+                messageText = getString(R.string.bluetooth_display_passkey_pin_msg, name,
+                        mPairingKey);
                 break;
 
             default:
                 Log.e(TAG, "Incorrect pairing type received, not creating view");
+                return null;
         }
+        messageView.setText(Html.fromHtml(messageText));
         return view;
     }
 
@@ -317,7 +343,11 @@
     public void onClick(DialogInterface dialog, int which) {
         switch (which) {
             case BUTTON_POSITIVE:
-                onPair(mPairingView.getText().toString());
+                if (mPairingView != null) {
+                    onPair(mPairingView.getText().toString());
+                } else {
+                    onPair(null);
+                }
                 break;
 
             case BUTTON_NEGATIVE:
@@ -335,4 +365,12 @@
     public void onTextChanged(CharSequence s, int start, int before, int count) {
     }
 
+    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+        // change input type for soft keyboard to numeric or alphanumeric
+        if (isChecked) {
+            mPairingView.setInputType(InputType.TYPE_CLASS_TEXT);
+        } else {
+            mPairingView.setInputType(InputType.TYPE_CLASS_NUMBER);
+        }
+    }
 }
diff --git a/src/com/android/settings/bluetooth/BluetoothSettings.java b/src/com/android/settings/bluetooth/BluetoothSettings.java
index 2208223..ede218d 100644
--- a/src/com/android/settings/bluetooth/BluetoothSettings.java
+++ b/src/com/android/settings/bluetooth/BluetoothSettings.java
@@ -20,6 +20,10 @@
 import android.app.Activity;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.os.Bundle;
 import android.preference.Preference;
 import android.preference.PreferenceActivity;
@@ -48,16 +52,48 @@
     private static final String TAG = "BluetoothSettings";
 
     private static final int MENU_ID_SCAN = Menu.FIRST;
-    private static final int MENU_ID_ADVANCED = Menu.FIRST + 1;
+    private static final int MENU_ID_RENAME_DEVICE = Menu.FIRST + 1;
+    private static final int MENU_ID_VISIBILITY_TIMEOUT = Menu.FIRST + 2;
+    private static final int MENU_ID_SHOW_RECEIVED = Menu.FIRST + 3;
+
+    /* 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";
 
     private BluetoothEnabler mBluetoothEnabler;
 
+    private BluetoothDiscoverableEnabler mDiscoverableEnabler;
+
+    private PreferenceGroup mPairedDevicesCategory;
+
     private PreferenceGroup mAvailableDevicesCategory;
     private boolean mAvailableDevicesCategoryIsPresent;
 
     private View mView;
     private TextView mEmptyView;
 
+    // accessed from inner class (not private to avoid thunks)
+    Preference mMyDevicePreference;
+
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (action.equals(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED) ||
+                    (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED) &&
+                            (intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
+                                    BluetoothAdapter.ERROR) == BluetoothAdapter.STATE_ON))) {
+                updateDeviceName();
+            }
+        }
+
+        private void updateDeviceName() {
+            if (mLocalAdapter != null && mLocalAdapter.isEnabled() && mMyDevicePreference != null) {
+                mMyDevicePreference.setTitle(mLocalAdapter.getName());
+            }
+        }
+    };
+
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
             Bundle savedInstanceState) {
@@ -106,15 +142,26 @@
         super.onResume();
 
         mBluetoothEnabler.resume();
-
         updateContent(mLocalAdapter.getBluetoothState());
+
+        if (mDiscoverableEnabler != null) {
+            mDiscoverableEnabler.resume();
+        }
+
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
+        filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
+        getActivity().registerReceiver(mReceiver, filter);
     }
 
     @Override
     public void onPause() {
         super.onPause();
-
         mBluetoothEnabler.pause();
+        getActivity().unregisterReceiver(mReceiver);
+        if (mDiscoverableEnabler != null) {
+            mDiscoverableEnabler.pause();
+        }
     }
 
     @Override
@@ -124,12 +171,14 @@
         int textId = isDiscovering ? R.string.bluetooth_searching_for_devices :
             R.string.bluetooth_search_for_devices;
         menu.add(Menu.NONE, MENU_ID_SCAN, 0, textId)
-                //.setIcon(R.drawable.ic_menu_scan_network)
                 .setEnabled(bluetoothIsEnabled && !isDiscovering)
                 .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
-        menu.add(Menu.NONE, MENU_ID_ADVANCED, 0, R.string.bluetooth_menu_advanced)
-                //.setIcon(android.R.drawable.ic_menu_manage)
+        menu.add(Menu.NONE, MENU_ID_RENAME_DEVICE, 0, R.string.bluetooth_rename_device)
                 .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+        menu.add(Menu.NONE, MENU_ID_VISIBILITY_TIMEOUT, 0, R.string.bluetooth_visibility_timeout)
+                .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
+        menu.add(Menu.NONE, MENU_ID_SHOW_RECEIVED, 0, R.string.bluetooth_show_received_files)
+                .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
     }
 
     @Override
@@ -140,16 +189,20 @@
                     startScanning();
                 }
                 return true;
-            case MENU_ID_ADVANCED:
-                if (getActivity() instanceof PreferenceActivity) {
-                    ((PreferenceActivity) getActivity()).startPreferencePanel(
-                            AdvancedBluetoothSettings.class.getCanonicalName(),
-                            null,
-                            R.string.bluetooth_advanced_titlebar, null,
-                            this, 0);
-                } else {
-                    startFragment(this, AdvancedBluetoothSettings.class.getCanonicalName(), -1, null);
-                }
+
+            case MENU_ID_RENAME_DEVICE:
+                new BluetoothNameDialogFragment(mLocalAdapter).show(
+                        getFragmentManager(), "rename device");
+                return true;
+
+            case MENU_ID_VISIBILITY_TIMEOUT:
+                new BluetoothVisibilityTimeoutFragment(mDiscoverableEnabler).show(
+                        getFragmentManager(), "visibility timeout");
+                return true;
+
+            case MENU_ID_SHOW_RECEIVED:
+                Intent intent = new Intent(BTOPP_ACTION_OPEN_RECEIVED_FILES);
+                getActivity().sendBroadcast(intent);
                 return true;
         }
         return super.onOptionsItemSelected(item);
@@ -195,9 +248,15 @@
                 if (mLocalAdapter != null) {
                     mMyDevicePreference.setTitle(mLocalAdapter.getName());
                 }
+                mMyDevicePreference.setPersistent(false);
                 mMyDevicePreference.setEnabled(true);
                 preferenceScreen.addPreference(mMyDevicePreference);
 
+                if (mDiscoverableEnabler == null) {
+                    mDiscoverableEnabler = new BluetoothDiscoverableEnabler(getActivity(),
+                            mLocalAdapter, mMyDevicePreference);
+                }
+
                 // Paired devices category
                 if (mPairedDevicesCategory == null) {
                     mPairedDevicesCategory = new PreferenceCategory(getActivity());
@@ -209,6 +268,8 @@
                         BluetoothDeviceFilter.BONDED_DEVICE_FILTER);
                 int numberOfPairedDevices = mPairedDevicesCategory.getPreferenceCount();
 
+                mDiscoverableEnabler.setNumberOfPairedDevices(numberOfPairedDevices);
+
                 // Available devices category
                 if (mAvailableDevicesCategory == null) {
                     mAvailableDevicesCategory = new ProgressCategory(getActivity(), null);
@@ -291,10 +352,6 @@
         }
     };
 
-    private Preference mMyDevicePreference;
-
-    private PreferenceGroup mPairedDevicesCategory;
-
     /**
      * Add a listener, which enables the advanced settings icon.
      * @param preference the newly added preference
diff --git a/src/com/android/settings/bluetooth/BluetoothVisibilityTimeoutFragment.java b/src/com/android/settings/bluetooth/BluetoothVisibilityTimeoutFragment.java
new file mode 100644
index 0000000..dbdb052
--- /dev/null
+++ b/src/com/android/settings/bluetooth/BluetoothVisibilityTimeoutFragment.java
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+package com.android.settings.bluetooth;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.bluetooth.BluetoothAdapter;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.InputFilter;
+import android.text.TextWatcher;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+
+import com.android.internal.app.AlertController;
+import com.android.settings.R;
+
+/**
+ * Dialog fragment for setting the discoverability timeout.
+ */
+final class BluetoothVisibilityTimeoutFragment extends DialogFragment
+        implements DialogInterface.OnClickListener {
+
+    private final BluetoothDiscoverableEnabler mDiscoverableEnabler;
+
+    public BluetoothVisibilityTimeoutFragment(BluetoothDiscoverableEnabler enabler) {
+        mDiscoverableEnabler = enabler;
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        return new AlertDialog.Builder(getActivity())
+                .setIcon(android.R.drawable.ic_dialog_info)
+                .setTitle(R.string.bluetooth_visibility_timeout)
+                .setSingleChoiceItems(R.array.bluetooth_visibility_timeout_entries,
+                        mDiscoverableEnabler.getDiscoverableTimeoutIndex(), this)
+                .setNegativeButton(android.R.string.cancel, null)
+                .create();
+    }
+
+    public void onClick(DialogInterface dialog, int which) {
+        mDiscoverableEnabler.setDiscoverableTimeout(which);
+        dismiss();
+    }
+}
diff --git a/src/com/android/settings/bluetooth/CachedBluetoothDevice.java b/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
index 71a5c01..846c379 100644
--- a/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
+++ b/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
@@ -257,6 +257,14 @@
         return true;
     }
 
+    /**
+     * Return true if user initiated pairing on this device. The message text is
+     * slightly different for local vs. remote initiated pairing dialogs.
+     */
+    boolean isUserInitiatedPairing() {
+        return mConnectAfterPairing;
+    }
+
     void unpair() {
         disconnect();
 
diff --git a/src/com/android/settings/deviceinfo/Status.java b/src/com/android/settings/deviceinfo/Status.java
index 68ba354..456bc98 100644
--- a/src/com/android/settings/deviceinfo/Status.java
+++ b/src/com/android/settings/deviceinfo/Status.java
@@ -82,6 +82,7 @@
     private static final String KEY_WIFI_MAC_ADDRESS = "wifi_mac_address";
     private static final String KEY_BT_ADDRESS = "bt_address";
     private static final String KEY_SERIAL_NUMBER = "serial_number";
+    private static final String KEY_ICC_ID = "icc_id";
 
     private static final String[] PHONE_RELATED_ENTRIES = {
         KEY_DATA_STATE,
@@ -95,7 +96,8 @@
         KEY_PRL_VERSION,
         KEY_MIN_NUMBER,
         KEY_MEID_NUMBER,
-        KEY_SIGNAL_STRENGTH
+        KEY_SIGNAL_STRENGTH,
+        KEY_ICC_ID
     };
 
     private static final int EVENT_SIGNAL_STRENGTH_CHANGED = 200;
@@ -111,7 +113,7 @@
     private Preference mUptime;
 
     private static String sUnknown;
-    
+
     private Preference mBatteryStatus;
     private Preference mBatteryLevel;
 
@@ -150,7 +152,7 @@
     }
 
     private BroadcastReceiver mBatteryInfoReceiver = new BroadcastReceiver() {
-        
+
         @Override
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
@@ -158,9 +160,9 @@
 
                 int level = intent.getIntExtra("level", 0);
                 int scale = intent.getIntExtra("scale", 100);
-                
+
                 mBatteryLevel.setSummary(String.valueOf(level * 100 / scale) + "%");
-                
+
                 int plugType = intent.getIntExtra("plugged", 0);
                 int status = intent.getIntExtra("status", BatteryManager.BATTERY_STATUS_UNKNOWN);
                 String statusString;
@@ -193,7 +195,7 @@
             updateNetworkType();
         }
     };
-    
+
     @Override
     protected void onCreate(Bundle icicle) {
         super.onCreate(icicle);
@@ -231,11 +233,18 @@
                     findPreference(KEY_MIN_NUMBER).setTitle(R.string.status_msid_number);
                 }
                 setSummaryText(KEY_PRL_VERSION, mPhone.getCdmaPrlVersion());
-
-                // device is not GSM/UMTS, do not display GSM/UMTS features
-                // check Null in case no specified preference in overlay xml
-                removePreferenceFromScreen(KEY_IMEI);
                 removePreferenceFromScreen(KEY_IMEI_SV);
+
+                if (mPhone.getLteOnCdmaMode() == Phone.LTE_ON_CDMA_TRUE) {
+                    // Show ICC ID and IMEI for LTE device
+                    setSummaryText(KEY_ICC_ID, mPhone.getIccSerialNumber());
+                    setSummaryText(KEY_IMEI, mPhone.getImei());
+                } else {
+                    // device is not GSM/UMTS, do not display GSM/UMTS features
+                    // check Null in case no specified preference in overlay xml
+                    removePreferenceFromScreen(KEY_IMEI);
+                    removePreferenceFromScreen(KEY_ICC_ID);
+                }
             } else {
                 setSummaryText(KEY_IMEI, mPhone.getDeviceId());
 
@@ -248,6 +257,7 @@
                 removePreferenceFromScreen(KEY_PRL_VERSION);
                 removePreferenceFromScreen(KEY_MEID_NUMBER);
                 removePreferenceFromScreen(KEY_MIN_NUMBER);
+                removePreferenceFromScreen(KEY_ICC_ID);
             }
 
             String rawNumber = mPhone.getLine1Number();  // may be null or empty
@@ -291,7 +301,7 @@
         registerReceiver(mBatteryInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
         mHandler.sendEmptyMessage(EVENT_UPDATE_STATS);
     }
-    
+
     @Override
     public void onPause() {
         super.onPause();
@@ -325,7 +335,7 @@
             findPreference(preference).setSummary(
                     SystemProperties.get(property, alt));
         } catch (RuntimeException e) {
-            
+
         }
     }
 
@@ -338,12 +348,12 @@
                  findPreference(preference).setSummary(text);
              }
     }
-    
+
     private void updateNetworkType() {
         // Whether EDGE, UMTS, etc...
         setSummary(KEY_NETWORK_TYPE, TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE, sUnknown);
     }
-    
+
     private void updateDataState() {
         int state = mTelephonyManager.getDataState();
         String display = mRes.getString(R.string.radioInfo_unknown);
@@ -362,14 +372,14 @@
                 display = mRes.getString(R.string.radioInfo_data_disconnected);
                 break;
         }
-        
+
         setSummaryText(KEY_DATA_STATE, display);
     }
 
     private void updateServiceState(ServiceState serviceState) {
         int state = serviceState.getState();
         String display = mRes.getString(R.string.radioInfo_unknown);
-        
+
         switch (state) {
             case ServiceState.STATE_IN_SERVICE:
                 display = mRes.getString(R.string.radioInfo_service_in);
@@ -382,9 +392,9 @@
                 display = mRes.getString(R.string.radioInfo_service_off);
                 break;
         }
-        
+
         setSummaryText(KEY_SERVICE_STATE, display);
-        
+
         if (serviceState.getRoaming()) {
             setSummaryText(KEY_ROAMING_STATE, mRes.getString(R.string.radioInfo_roaming_in));
         } else {
@@ -392,7 +402,7 @@
         }
         setSummaryText(KEY_OPERATOR_NAME, serviceState.getOperatorAlphaLong());
     }
-    
+
     void updateSignalStrength() {
         // TODO PhoneStateIntentReceiver is deprecated and PhoneStateListener
         // should probably used instead.
@@ -429,7 +439,7 @@
 
         Preference wifiMacAddressPref = findPreference(KEY_WIFI_MAC_ADDRESS);
         String macAddress = wifiInfo == null ? null : wifiInfo.getMacAddress();
-        wifiMacAddressPref.setSummary(!TextUtils.isEmpty(macAddress) ? macAddress 
+        wifiMacAddressPref.setSummary(!TextUtils.isEmpty(macAddress) ? macAddress
                 : getString(R.string.status_unavailable));
 
         Preference wifiIpAddressPref = findPreference(KEY_WIFI_IP_ADDRESS);
@@ -465,7 +475,7 @@
 
         mUptime.setSummary(convert(ut));
     }
-    
+
     private String pad(int n) {
         if (n >= 10) {
             return String.valueOf(n);
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
index fc903eb..d46853d 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
@@ -16,18 +16,10 @@
 
 package com.android.settings.fuelgauge;
 
-import com.android.internal.app.IBatteryStats;
-import com.android.internal.os.BatteryStatsImpl;
-import com.android.internal.os.PowerProfile;
-import com.android.settings.R;
-import com.android.settings.applications.InstalledAppDetails;
-import com.android.settings.fuelgauge.PowerUsageDetail.DrainType;
-
-import android.content.ContentResolver;
 import android.content.Context;
-import android.content.Intent;
 import android.hardware.SensorManager;
 import android.os.BatteryStats;
+import android.os.BatteryStats.Uid;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
@@ -36,7 +28,6 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemClock;
-import android.os.BatteryStats.Uid;
 import android.preference.Preference;
 import android.preference.PreferenceActivity;
 import android.preference.PreferenceFragment;
@@ -49,6 +40,12 @@
 import android.view.MenuInflater;
 import android.view.MenuItem;
 
+import com.android.internal.app.IBatteryStats;
+import com.android.internal.os.BatteryStatsImpl;
+import com.android.internal.os.PowerProfile;
+import com.android.settings.R;
+import com.android.settings.fuelgauge.PowerUsageDetail.DrainType;
+
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.io.Writer;
@@ -292,7 +289,8 @@
         MenuItem refresh = menu.add(0, MENU_STATS_REFRESH, 0, R.string.menu_stats_refresh)
                 .setIcon(R.drawable.ic_menu_refresh_holo_dark)
                 .setAlphabeticShortcut('r');
-        refresh.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+        refresh.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM |
+                MenuItem.SHOW_AS_ACTION_WITH_TEXT);
     }
 
     @Override
diff --git a/src/com/android/settings/net/NetworkPolicyEditor.java b/src/com/android/settings/net/NetworkPolicyEditor.java
index 61c2550..1e64ec2 100644
--- a/src/com/android/settings/net/NetworkPolicyEditor.java
+++ b/src/com/android/settings/net/NetworkPolicyEditor.java
@@ -20,7 +20,9 @@
 import static android.net.NetworkPolicy.WARNING_DISABLED;
 import static android.net.NetworkTemplate.MATCH_MOBILE_3G_LOWER;
 import static android.net.NetworkTemplate.MATCH_MOBILE_4G;
-import static android.net.NetworkTemplate.MATCH_MOBILE_ALL;
+import static android.net.NetworkTemplate.buildTemplateMobile3gLower;
+import static android.net.NetworkTemplate.buildTemplateMobile4g;
+import static android.net.NetworkTemplate.buildTemplateMobileAll;
 import static com.android.internal.util.Preconditions.checkNotNull;
 
 import android.net.INetworkPolicyManager;
@@ -134,9 +136,9 @@
     public void setMobilePolicySplit(String subscriberId, boolean split) {
         final boolean beforeSplit = isMobilePolicySplit(subscriberId);
 
-        final NetworkTemplate template3g = new NetworkTemplate(MATCH_MOBILE_3G_LOWER, subscriberId);
-        final NetworkTemplate template4g = new NetworkTemplate(MATCH_MOBILE_4G, subscriberId);
-        final NetworkTemplate templateAll = new NetworkTemplate(MATCH_MOBILE_ALL, subscriberId);
+        final NetworkTemplate template3g = buildTemplateMobile3gLower(subscriberId);
+        final NetworkTemplate template4g = buildTemplateMobile4g(subscriberId);
+        final NetworkTemplate templateAll = buildTemplateMobileAll(subscriberId);
 
         if (split == beforeSplit) {
             // already in requested state; skip
diff --git a/src/com/android/settings/vpn2/VpnDialog.java b/src/com/android/settings/vpn2/VpnDialog.java
index 4f9d0a2..d644700 100644
--- a/src/com/android/settings/vpn2/VpnDialog.java
+++ b/src/com/android/settings/vpn2/VpnDialog.java
@@ -36,17 +36,6 @@
 import android.widget.TextView;
 
 class VpnDialog extends AlertDialog implements TextWatcher, OnItemSelectedListener {
-    private static final String DUMMY = "\r";
-
-    private static String getDummy(String secret) {
-        return secret.isEmpty() ? "" : DUMMY;
-    }
-
-    private static String getSecret(String oldSecret, TextView view) {
-        String newSecret = view.getText().toString();
-        return DUMMY.equals(newSecret) ? oldSecret : newSecret;
-    }
-
     private final KeyStore mKeyStore = KeyStore.getInstance();
     private final DialogInterface.OnClickListener mListener;
     private final VpnProfile mProfile;
@@ -107,13 +96,13 @@
         mType.setSelection(mProfile.type);
         mServer.setText(mProfile.server);
         mUsername.setText(mProfile.username);
-        mPassword.setText(getDummy(mProfile.password));
+        mPassword.setText(mProfile.password);
         mSearchDomains.setText(mProfile.searchDomains);
         mRoutes.setText(mProfile.routes);
         mMppe.setChecked(mProfile.mppe);
-        mL2tpSecret.setText(getDummy(mProfile.l2tpSecret));
+        mL2tpSecret.setText(mProfile.l2tpSecret);
         mIpsecIdentifier.setText(mProfile.ipsecIdentifier);
-        mIpsecSecret.setText(getDummy(mProfile.ipsecSecret));
+        mIpsecSecret.setText(mProfile.ipsecSecret);
         loadCertificates(mIpsecUserCert, Credentials.USER_CERTIFICATE,
                 0, mProfile.ipsecUserCert);
         loadCertificates(mIpsecCaCert, Credentials.CA_CERTIFICATE,
@@ -288,7 +277,7 @@
         profile.type = mType.getSelectedItemPosition();
         profile.server = mServer.getText().toString().trim();
         profile.username = mUsername.getText().toString();
-        profile.password = getSecret(mProfile.password, mPassword);
+        profile.password = mPassword.getText().toString();
         profile.searchDomains = mSearchDomains.getText().toString().trim();
         profile.routes = mRoutes.getText().toString().trim();
 
@@ -298,16 +287,16 @@
                 profile.mppe = mMppe.isChecked();
                 break;
             case VpnProfile.TYPE_L2TP_IPSEC_PSK:
-                profile.l2tpSecret = getSecret(mProfile.l2tpSecret, mL2tpSecret);
-                profile.ipsecSecret = getSecret(mProfile.ipsecSecret, mIpsecSecret);
+                profile.l2tpSecret = mL2tpSecret.getText().toString();
+                profile.ipsecSecret = mIpsecSecret.getText().toString();
                 break;
             case VpnProfile.TYPE_IPSEC_XAUTH_PSK:
                 profile.ipsecIdentifier = mIpsecIdentifier.getText().toString();
-                profile.ipsecSecret = getSecret(mProfile.ipsecSecret, mIpsecSecret);
+                profile.ipsecSecret = mIpsecSecret.getText().toString();
                 break;
 
             case VpnProfile.TYPE_L2TP_IPSEC_RSA:
-                profile.l2tpSecret = getSecret(mProfile.l2tpSecret, mL2tpSecret);
+                profile.l2tpSecret = mL2tpSecret.getText().toString();
                 // fall through
             case VpnProfile.TYPE_IPSEC_XAUTH_RSA:
                 if (mIpsecUserCert.getSelectedItemPosition() != 0) {
diff --git a/src/com/android/settings/vpn2/VpnProfile.java b/src/com/android/settings/vpn2/VpnProfile.java
index 24c2f5f..3ee3af0 100644
--- a/src/com/android/settings/vpn2/VpnProfile.java
+++ b/src/com/android/settings/vpn2/VpnProfile.java
@@ -45,7 +45,7 @@
     String dnsServers = "";     // 5
     String searchDomains = "";  // 6
     String routes = "";         // 7
-    boolean mppe = false;       // 8
+    boolean mppe = true;        // 8
     String l2tpSecret = "";     // 9
     String ipsecIdentifier = "";// 10
     String ipsecSecret = "";    // 11
diff --git a/src/com/android/settings/vpn2/VpnSettings.java b/src/com/android/settings/vpn2/VpnSettings.java
index f345c22..4dbb6bd 100644
--- a/src/com/android/settings/vpn2/VpnSettings.java
+++ b/src/com/android/settings/vpn2/VpnSettings.java
@@ -22,6 +22,7 @@
 import android.content.DialogInterface;
 import android.net.IConnectivityManager;
 import android.net.LinkProperties;
+import android.net.RouteInfo;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
@@ -42,6 +43,7 @@
 import com.android.internal.net.VpnConfig;
 import com.android.settings.SettingsPreferenceFragment;
 
+import java.net.Inet4Address;
 import java.nio.charset.Charsets;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -51,6 +53,7 @@
         DialogInterface.OnClickListener, DialogInterface.OnDismissListener {
 
     private static final String TAG = "VpnSettings";
+    private static final String SCRIPT = "/etc/ppp/ip-up-vpn";
 
     private final IConnectivityManager mService = IConnectivityManager.Stub
             .asInterface(ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
@@ -70,9 +73,7 @@
     public void onCreate(Bundle savedState) {
         super.onCreate(savedState);
         addPreferencesFromResource(R.xml.vpn_settings2);
-        PreferenceGroup group = getPreferenceScreen();
-        group.setOrderingAsAdded(false);
-        group.findPreference("add_network").setOnPreferenceClickListener(this);
+        getPreferenceScreen().setOrderingAsAdded(false);
 
         if (savedState != null) {
             VpnProfile profile = VpnProfile.decode(savedState.getString("VpnKey"),
@@ -121,6 +122,7 @@
         // safely cache profiles in the memory.
         if (mPreferences == null) {
             mPreferences = new HashMap<String, VpnPreference>();
+            PreferenceGroup group = getPreferenceScreen();
 
             String[] keys = mKeyStore.saw(Credentials.VPN);
             if (keys != null && keys.length > 0) {
@@ -135,13 +137,11 @@
                     } else {
                         VpnPreference preference = new VpnPreference(context, profile);
                         mPreferences.put(key, preference);
+                        group.addPreference(preference);
                     }
                 }
             }
-        }
-        PreferenceGroup group = getPreferenceScreen();
-        for (VpnPreference preference : mPreferences.values()) {
-            group.addPreference(preference);
+            group.findPreference("add_network").setOnPreferenceClickListener(this);
         }
 
         // Show the dialog if there is one.
@@ -320,13 +320,34 @@
         return true;
     }
 
-    private void connect(VpnProfile profile) throws Exception {
-        // Get the current active interface.
+    private String[] getDefaultNetwork() throws Exception {
         LinkProperties network = mService.getActiveLinkProperties();
-        String interfaze = (network == null) ? null : network.getInterfaceName();
-        if (interfaze == null) {
-            throw new IllegalStateException("Cannot get network interface");
+        if (network == null) {
+            throw new IllegalStateException("Network is not available");
         }
+        String interfaze = network.getInterfaceName();
+        if (interfaze == null) {
+            throw new IllegalStateException("Cannot get the default interface");
+        }
+        String gateway = null;
+        for (RouteInfo route : network.getRoutes()) {
+            // Currently legacy VPN only works on IPv4.
+            if (route.isDefaultRoute() && route.getGateway() instanceof Inet4Address) {
+                gateway = route.getGateway().getHostAddress();
+                break;
+            }
+        }
+        if (gateway == null) {
+            throw new IllegalStateException("Cannot get the default gateway");
+        }
+        return new String[] {interfaze, gateway};
+    }
+
+    private void connect(VpnProfile profile) throws Exception {
+        // Get the default interface and the default gateway.
+        String[] network = getDefaultNetwork();
+        String interfaze = network[0];
+        String gateway = network[1];
 
         // Load certificates.
         String privateKey = "";
@@ -346,26 +367,37 @@
             // TODO: find out a proper way to handle this. Delete these keys?
             throw new IllegalStateException("Cannot load credentials");
         }
-        Log.i(TAG, userCert);
 
         // Prepare arguments for racoon.
         String[] racoon = null;
         switch (profile.type) {
             case VpnProfile.TYPE_L2TP_IPSEC_PSK:
                 racoon = new String[] {
-                    interfaze, profile.server, "udppsk", "1701", profile.ipsecSecret,
+                    interfaze, profile.server, "udppsk", profile.ipsecSecret, "1701",
                 };
                 break;
             case VpnProfile.TYPE_L2TP_IPSEC_RSA:
                 racoon = new String[] {
-                    interfaze, profile.server, "udprsa", "1701", privateKey, userCert, caCert,
+                    interfaze, profile.server, "udprsa", privateKey, userCert, caCert, "1701",
                 };
                 break;
             case VpnProfile.TYPE_IPSEC_XAUTH_PSK:
+                racoon = new String[] {
+                    interfaze, profile.server, "xauthpsk", profile.ipsecIdentifier,
+                    profile.ipsecSecret, profile.username, profile.password, SCRIPT, gateway,
+                };
                 break;
             case VpnProfile.TYPE_IPSEC_XAUTH_RSA:
+                racoon = new String[] {
+                    interfaze, profile.server, "xauthrsa", privateKey, userCert, caCert,
+                    profile.username, profile.password, SCRIPT, gateway,
+                };
                 break;
             case VpnProfile.TYPE_IPSEC_HYBRID_RSA:
+                racoon = new String[] {
+                    interfaze, profile.server, "hybridrsa", caCert,
+                    profile.username, profile.password, SCRIPT, gateway,
+                };
                 break;
         }
 
@@ -374,27 +406,27 @@
         switch (profile.type) {
             case VpnProfile.TYPE_PPTP:
                 mtpd = new String[] {
-                    "pptp", profile.server, "1723",
+                    interfaze, "pptp", profile.server, "1723",
                     "name", profile.username, "password", profile.password,
                     "linkname", "vpn", "refuse-eap", "nodefaultroute",
                     "usepeerdns", "idle", "1800", "mtu", "1400", "mru", "1400",
-                    "ipparam", profile.routes, (profile.mppe ? "+mppe" : "nomppe"),
+                    (profile.mppe ? "+mppe" : "nomppe"),
                 };
                 break;
             case VpnProfile.TYPE_L2TP_IPSEC_PSK:
             case VpnProfile.TYPE_L2TP_IPSEC_RSA:
                 mtpd = new String[] {
-                    "l2tp", profile.server, "1701", profile.l2tpSecret,
+                    interfaze, "l2tp", profile.server, "1701", profile.l2tpSecret,
                     "name", profile.username, "password", profile.password,
                     "linkname", "vpn", "refuse-eap", "nodefaultroute",
                     "usepeerdns", "idle", "1800", "mtu", "1400", "mru", "1400",
-                    "ipparam", profile.routes,
                 };
                 break;
         }
 
         VpnConfig config = new VpnConfig();
         config.packagz = profile.key;
+        config.interfaze = interfaze;
         config.session = profile.name;
         config.routes = profile.routes;
         if (!profile.searchDomains.isEmpty()) {