Bluetooth settings revamp

Added a separate scanning screen.
UI changes to not require long-press options.
Needs TODOs to be filled by BT team.

Bug: 3038327
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 6a773a4..5b9af25 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -659,9 +659,6 @@
 
         <!-- Bluetooth stuff -->
 
-        <activity android:name=".bluetooth.ConnectSpecificProfilesActivity"
-                  android:label="@string/bluetooth_connect_specific_profiles_title" />
-
         <activity android:name=".bluetooth.BluetoothPairingDialog"
                   android:label="@string/bluetooth_pairing_request"
                   android:excludeFromRecents="true"
diff --git a/res/drawable-hdpi/ic_preferences_collapsed.png b/res/drawable-hdpi/ic_preferences_collapsed.png
new file mode 100644
index 0000000..bc250d8
--- /dev/null
+++ b/res/drawable-hdpi/ic_preferences_collapsed.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_preferences_expanded.png b/res/drawable-hdpi/ic_preferences_expanded.png
new file mode 100644
index 0000000..08c877d
--- /dev/null
+++ b/res/drawable-hdpi/ic_preferences_expanded.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_preferences_collapsed.png b/res/drawable-mdpi/ic_preferences_collapsed.png
new file mode 100644
index 0000000..bc250d8
--- /dev/null
+++ b/res/drawable-mdpi/ic_preferences_collapsed.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_preferences_expanded.png b/res/drawable-mdpi/ic_preferences_expanded.png
new file mode 100644
index 0000000..08c877d
--- /dev/null
+++ b/res/drawable-mdpi/ic_preferences_expanded.png
Binary files differ
diff --git a/res/layout/preference_bluetooth.xml b/res/layout/preference_bluetooth.xml
index 501c827..531bdc34 100644
--- a/res/layout/preference_bluetooth.xml
+++ b/res/layout/preference_bluetooth.xml
@@ -21,7 +21,14 @@
     android:gravity="center_vertical"
     android:paddingLeft="16dip"
     android:paddingRight="?android:attr/scrollbarSize">
-    
+
+    <ImageView
+        android:id="@+id/btClass"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginRight="12dip"
+        android:layout_gravity="center_vertical" />
+
     <RelativeLayout
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
@@ -29,13 +36,15 @@
         android:layout_marginTop="6dip"
         android:layout_marginBottom="6dip"
         android:layout_weight="1">
-    
+
+        <!-- Device name -->
         <TextView android:id="@+android:id/title"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:singleLine="true"
             android:textAppearance="?android:attr/textAppearanceLarge" />
-            
+
+        <!-- Status summary -->
         <TextView android:id="@+android:id/summary"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
@@ -44,13 +53,30 @@
             android:textAppearance="?android:attr/textAppearanceSmall"
             android:maxLines="2" />
 
+        <LinearLayout android:id="@+id/profileIcons"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_centerVertical="true"
+            android:layout_alignParentRight="true"
+            />
     </RelativeLayout>
 
+    <!-- Divider -->
     <ImageView
-        android:id="@+id/btClass"
+        android:id="@+id/divider"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_marginRight="12dip"
-        android:layout_gravity="center_vertical" />
+        android:layout_marginRight="8dip"
+        android:layout_gravity="center_vertical"
+        android:src="@drawable/nav_divider"
+         />
+
+    <!-- Details button -->
+    <ImageView
+        android:id="@+id/deviceDetails"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical"
+        android:src="@drawable/icon" />
 
 </LinearLayout>
diff --git a/res/layout/preference_bluetooth_profile.xml b/res/layout/preference_bluetooth_profile.xml
new file mode 100644
index 0000000..5ec0a47
--- /dev/null
+++ b/res/layout/preference_bluetooth_profile.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:gravity="center_vertical"
+    android:paddingLeft="16dip"
+    android:paddingRight="?android:attr/scrollbarSize">
+
+    <ImageView
+        android:id="@+id/profileIcon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginRight="12dip"
+        android:layout_gravity="center_vertical" />
+
+    <RelativeLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginRight="6dip"
+        android:layout_marginTop="6dip"
+        android:layout_marginBottom="6dip"
+        android:layout_weight="1">
+
+        <!-- Device name -->
+        <TextView android:id="@+android:id/title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:singleLine="true"
+            android:textAppearance="?android:attr/textAppearanceLarge" />
+
+        <!-- Status summary -->
+        <TextView android:id="@+android:id/summary"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_below="@android:id/title"
+            android:layout_alignLeft="@android:id/title"
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            android:maxLines="2" />
+
+        <LinearLayout android:id="@+id/profileIcons"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_centerVertical="true"
+            android:layout_alignParentRight="true"
+            />
+    </RelativeLayout>
+
+    <!-- Divider -->
+    <ImageView
+        android:id="@+id/divider"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginRight="8dip"
+        android:layout_gravity="center_vertical"
+        android:src="@drawable/nav_divider"
+         />
+
+    <!-- Details button -->
+    <ImageView
+        android:id="@+id/profileExpand"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical"
+        android:src="@drawable/icon" />
+
+</LinearLayout>
diff --git a/res/layout/profile_icon_small.xml b/res/layout/profile_icon_small.xml
new file mode 100644
index 0000000..b0a9f4b
--- /dev/null
+++ b/res/layout/profile_icon_small.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<ImageView
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/icon"
+        android:layout_width="20dp"
+        android:layout_height="20dp"
+        android:layout_marginRight="4dip"
+        android:gravity="center"
+        android:layout_gravity="center_vertical" />
diff --git a/res/values/strings.xml b/res/values/strings.xml
index d6221fe..da54e9d 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -782,7 +782,14 @@
 
     <!-- Bluetooth settings: The title of the preference (list item) that initiates a scan for devices -->
     <string name="bluetooth_preference_scan_title">Scan for devices</string>
-
+    <!-- Bluetooth settings: The title of the preference (list item) that finds nearby devices [CHAR LIMIT=30] -->
+    <string name="bluetooth_preference_find_nearby_title">Find nearby devices</string>
+    <!-- Bluetooth settings: The sub heading for device settings. [CHAR LIMIT=30] -->
+    <string name="bluetooth_preference_device_settings">Device settings</string>
+    <!-- Bluetooth settings: The sub heading for paired devices. [CHAR LIMIT=30] -->
+    <string name="bluetooth_preference_paired_devices">Paired devices</string>
+    <!-- Bluetooth settings: The sub heading for found devices when scanning. [CHAR LIMIT=30] -->
+    <string name="bluetooth_preference_found_devices">Found devices</string>
     <!-- Bluetooth settings.  Context menu item for a device.  Action will connect to all profiles on the device. -->
     <string name="bluetooth_device_context_connect">Connect</string>
     <!-- Bluetooth settings.  Context menu item for a device.  Action will disconnect from all profiles on the device. -->
@@ -823,12 +830,18 @@
 
     <!-- Bluetooth settings.  Connection options screen.  The title of the screen. -->
     <string name="bluetooth_device_advanced_title"><xliff:g id="device_name">%1$s</xliff:g> options</string>
+    <!-- Bluetooth settings. Connection options screen. Title of device actions section. [CHAR LIMIT=30] -->
+    <string name="bluetooth_device_advanced_device_actions_title">Device actions</string>
     <!-- Bluetooth settings.  Connection options screen.  The title of the checkbox that controls whether the device is in "online" mode or "offline" mode.  This essentially is the checkbox that controls whether any checks / unchecks on a profile should be applied immediately, or next time the device is connected. -->
     <string name="bluetooth_device_advanced_online_mode_title">Connect</string>
     <!-- Bluetooth settings.  Connection options screen.  The summary of the online mode checkbox.  This describes what the setting does in the context of the screen. -->
     <string name="bluetooth_device_advanced_online_mode_summary">Connect to Bluetooth device</string>
     <!-- Bluetooth settings.  Connection options screen.  The title of the header that is above all of the profiles. -->
     <string name="bluetooth_device_advanced_profile_header_title">Profiles</string>
+    <!-- Bluetooth settings. Connection options screen. Title for option to rename the device. [CHAR LIMIT=30] -->
+    <string name="bluetooth_device_advanced_rename_device">Rename device</string>
+    <!-- Bluetooth settings. Connection options screen. Title for checkbox to enable incoming file transfers [CHAR LIMIT=30] -->
+    <string name="bluetooth_device_advanced_enable_opp_title">Allow incoming file transfers</string>
     <!-- Bluetooth settings.  Connection options screen.  The summary for the A2DP checkbox preference when A2DP is connected. -->
     <string name="bluetooth_a2dp_profile_summary_connected">Connected to media audio</string>
     <!-- Bluetooth settings.  Connection options screen.  The summary for the headset checkbox preference when headset is connected. -->
diff --git a/res/xml/bluetooth_device_advanced.xml b/res/xml/bluetooth_device_advanced.xml
index 5611595..b4a0978 100644
--- a/res/xml/bluetooth_device_advanced.xml
+++ b/res/xml/bluetooth_device_advanced.xml
@@ -18,15 +18,32 @@
         xmlns:android="http://schemas.android.com/apk/res/android">
 
     <PreferenceCategory
-            android:key="title" />
-            
-    <CheckBoxPreference
-            android:key="online_mode"
-            android:title="@string/bluetooth_device_advanced_online_mode_title"
+            android:key="title"
+            android:order="10"
+            android:title="@string/bluetooth_device_advanced_device_actions_title" />
+
+    <EditTextPreference
+            android:key="rename_device"
+            android:title="@string/bluetooth_device_advanced_rename_device"
+            android:order="20"
             android:persistent="false" />
-                
+
+    <CheckBoxPreference
+            android:key="allow_incoming"
+            android:title="@string/bluetooth_device_advanced_enable_opp_title"
+            android:order="30"
+            android:persistent="false" />
+
+    <Preference
+            android:key="unpair"
+            android:title="@string/bluetooth_device_context_unpair"
+            android:order="40"
+            android:persistent="false"
+            />
+
     <PreferenceCategory
             android:key="profile_container"
+            android:order="100"
             android:title="@string/bluetooth_device_advanced_profile_header_title">
 
         <!-- Profile checkboxes will be added here programmatically. -->
diff --git a/res/xml/bluetooth_settings.xml b/res/xml/bluetooth_settings.xml
index 131f7a0..b7a0edc 100644
--- a/res/xml/bluetooth_settings.xml
+++ b/res/xml/bluetooth_settings.xml
@@ -18,6 +18,9 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:title="@string/bluetooth_settings" >
 
+    <PreferenceCategory
+        android:title="@string/bluetooth_preference_device_settings"/>
+
     <CheckBoxPreference
         android:key="bt_checkbox"
         android:title="@string/bluetooth"
@@ -40,15 +43,16 @@
         android:summaryOff="@string/bluetooth_not_discoverable"
         android:persistent="false" />
 
-    <Preference
-        android:key="bt_scan"
-        android:dependency="bt_checkbox"
-        android:title="@string/bluetooth_preference_scan_title" />
-
-    <com.android.settings.ProgressCategory
+    <PreferenceCategory
         android:key="bt_device_list"
-        android:title="@string/bluetooth_devices"
+        android:title="@string/bluetooth_preference_paired_devices"
         android:dependency="bt_checkbox"
         android:orderingFromXml="false" />
 
+    <Preference
+        android:key="bt_find_nearby"
+        android:dependency="bt_checkbox"
+        android:fragment="com.android.settings.bluetooth.BluetoothSettings$FindNearby"
+        android:title="@string/bluetooth_preference_find_nearby_title" />
+
 </PreferenceScreen>
diff --git a/res/xml/device_picker.xml b/res/xml/device_picker.xml
index 7dd5b68..43b5829 100644
--- a/res/xml/device_picker.xml
+++ b/res/xml/device_picker.xml
@@ -23,7 +23,7 @@
 
     <com.android.settings.ProgressCategory
         android:key="bt_device_list"
-        android:title="@string/bluetooth_devices"
+        android:title="@string/bluetooth_preference_found_devices"
         android:orderingFromXml="false" />
 
 </PreferenceScreen>
diff --git a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
index f0b1705..1f9408d 100644
--- a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
+++ b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
@@ -19,16 +19,22 @@
 import com.android.settings.R;
 
 import android.content.Context;
+import android.graphics.drawable.Drawable;
 import android.preference.Preference;
 import android.util.TypedValue;
+import android.view.LayoutInflater;
 import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnClickListener;
 import android.widget.ImageView;
+import android.widget.LinearLayout;
 
 /**
  * BluetoothDevicePreference is the preference type used to display each remote
  * Bluetooth device in the Bluetooth Settings screen.
  */
-public class BluetoothDevicePreference extends Preference implements CachedBluetoothDevice.Callback {
+public class BluetoothDevicePreference extends Preference implements
+        CachedBluetoothDevice.Callback, OnClickListener {
     private static final String TAG = "BluetoothDevicePreference";
 
     private static int sDimAlpha = Integer.MIN_VALUE;
@@ -36,6 +42,9 @@
     private CachedBluetoothDevice mCachedDevice;
     private int mAccessibleProfile;
 
+    private ImageView mDeviceSettings;
+    private OnClickListener mOnSettingsClickListener;
+
     /**
      * Cached local copy of whether the device is busy. This is only updated
      * from {@link #onDeviceAttributesChanged(CachedBluetoothDevice)}.
@@ -66,6 +75,10 @@
         return mCachedDevice;
     }
 
+    public void setOnSettingsClickListener(OnClickListener listener) {
+        mOnSettingsClickListener = listener;
+    }
+
     @Override
     protected void onPrepareForRemoval() {
         super.onPrepareForRemoval();
@@ -117,6 +130,34 @@
         ImageView btClass = (ImageView) view.findViewById(R.id.btClass);
         btClass.setImageResource(mCachedDevice.getBtClassDrawable());
         btClass.setAlpha(isEnabled() ? 255 : sDimAlpha);
+
+        mDeviceSettings = (ImageView) view.findViewById(R.id.deviceDetails);
+        if (mOnSettingsClickListener != null) {
+            mDeviceSettings.setOnClickListener(this);
+            mDeviceSettings.setTag(mCachedDevice);
+        } else { // Hide the settings icon and divider
+            mDeviceSettings.setVisibility(View.GONE);
+            ImageView divider = (ImageView) view.findViewById(R.id.divider);
+            if (divider != null) {
+                divider.setVisibility(View.GONE);
+            }
+        }
+
+        LayoutInflater inflater = (LayoutInflater)
+                getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        ViewGroup profilesGroup = (ViewGroup) view.findViewById(R.id.profileIcons);
+        for (Drawable icon : mCachedDevice.getProfileIcons()) {
+            inflater.inflate(R.layout.profile_icon_small, profilesGroup, true);
+            ImageView imageView =
+                    (ImageView) profilesGroup.getChildAt(profilesGroup.getChildCount() - 1);
+            imageView.setImageDrawable(icon);
+        }
+    }
+
+    public void onClick(View v) {
+        if (v == mDeviceSettings) {
+            if (mOnSettingsClickListener != null) mOnSettingsClickListener.onClick(v);
+        }
     }
 
     @Override
diff --git a/src/com/android/settings/bluetooth/BluetoothProfilePreference.java b/src/com/android/settings/bluetooth/BluetoothProfilePreference.java
new file mode 100644
index 0000000..c0df8a7
--- /dev/null
+++ b/src/com/android/settings/bluetooth/BluetoothProfilePreference.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.bluetooth;
+
+import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
+import com.android.settings.R;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.preference.Preference;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnClickListener;
+import android.widget.ImageView;
+
+/**
+ * BluetoothProfilePreference is the preference type used to display each profile for a
+ * particular bluetooth device.
+ */
+public class BluetoothProfilePreference extends Preference implements OnClickListener {
+
+    private static final String TAG = "BluetoothProfilePreference";
+
+    private Drawable mProfileDrawable;
+    private boolean mExpanded;
+    private ImageView mProfileExpandView;
+    private Profile mProfile;
+
+    private OnClickListener mOnExpandClickListener;
+
+    public BluetoothProfilePreference(Context context, Profile profile) {
+        super(context);
+
+        mProfile = profile;
+
+        setLayoutResource(R.layout.preference_bluetooth_profile);
+        setExpanded(false);
+    }
+
+    public void setOnExpandClickListener(OnClickListener listener) {
+        mOnExpandClickListener = listener;
+    }
+
+    public void setExpanded(boolean expanded) {
+        mExpanded = expanded;
+        notifyChanged();
+    }
+
+    public boolean isExpanded() {
+        return mExpanded;
+    }
+
+    public void setProfileDrawable(Drawable drawable) {
+        mProfileDrawable = drawable;
+    }
+
+    @Override
+    protected void onBindView(View view) {
+        super.onBindView(view);
+
+        ImageView btProfile = (ImageView) view.findViewById(R.id.profileIcon);
+        btProfile.setImageDrawable(mProfileDrawable);
+
+        mProfileExpandView = (ImageView) view.findViewById(R.id.profileExpand);
+        mProfileExpandView.setOnClickListener(this);
+        mProfileExpandView.setTag(mProfile);
+
+        mProfileExpandView.setImageResource(mExpanded ? R.drawable.ic_preferences_expanded
+                : R.drawable.ic_preferences_collapsed);
+    }
+
+    public void onClick(View v) {
+        if (v == mProfileExpandView) {
+            if (mOnExpandClickListener != null) {
+                setExpanded(!mExpanded);
+                mOnExpandClickListener.onClick(v);
+            }
+        }
+    }
+}
diff --git a/src/com/android/settings/bluetooth/BluetoothSettings.java b/src/com/android/settings/bluetooth/BluetoothSettings.java
index 0de3bfa..841c9abc 100644
--- a/src/com/android/settings/bluetooth/BluetoothSettings.java
+++ b/src/com/android/settings/bluetooth/BluetoothSettings.java
@@ -16,11 +16,11 @@
 
 package com.android.settings.bluetooth;
 
+import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
 import com.android.settings.ProgressCategory;
 import com.android.settings.R;
 import com.android.settings.SettingsPreferenceFragment;
 import com.android.settings.UserLeaveHintListener;
-import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
 
 import android.app.Activity;
 import android.app.AlertDialog;
@@ -39,6 +39,7 @@
 import android.os.ParcelUuid;
 import android.preference.CheckBoxPreference;
 import android.preference.Preference;
+import android.preference.PreferenceCategory;
 import android.preference.PreferenceScreen;
 import android.text.TextUtils;
 import android.view.ContextMenu;
@@ -55,7 +56,7 @@
  * connection management.
  */
 public class BluetoothSettings extends SettingsPreferenceFragment
-        implements LocalBluetoothManager.Callback, UserLeaveHintListener {
+        implements LocalBluetoothManager.Callback, UserLeaveHintListener, View.OnClickListener {
 
     private static final String TAG = "BluetoothSettings";
 
@@ -64,14 +65,18 @@
     private static final String KEY_BT_DEVICE_LIST = "bt_device_list";
     private static final String KEY_BT_NAME = "bt_name";
     private static final String KEY_BT_SCAN = "bt_scan";
+    private static final String KEY_BT_FIND_NEARBY = "bt_find_nearby";
 
     private static final int SCREEN_TYPE_SETTINGS = 0;
     private static final int SCREEN_TYPE_DEVICEPICKER = 1;
     private static final int SCREEN_TYPE_TETHERING = 2;
+    private static final int SCREEN_TYPE_SCAN = 3;
 
     public static final String ACTION = "bluetooth_action";
     public static final String ACTION_LAUNCH_TETHER_PICKER =
-        "com.android.settings.bluetooth.action.LAUNCH_TETHER_PICKER";
+            "com.android.settings.bluetooth.action.LAUNCH_TETHER_PICKER";
+    public static final String ACTION_LAUNCH_SCAN_MODE =
+            "com.android.settings.bluetooth.action.LAUNCH_SCAN_MODE";
 
     private int mScreenType;
     private int mFilterType;
@@ -88,7 +93,7 @@
 
     private BluetoothNamePreference mNamePreference;
 
-    private ProgressCategory mDeviceList;
+    private PreferenceCategory mDeviceList;
 
     private WeakHashMap<CachedBluetoothDevice, BluetoothDevicePreference> mDevicePreferenceMap =
             new WeakHashMap<CachedBluetoothDevice, BluetoothDevicePreference>();
@@ -96,11 +101,11 @@
     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            // TODO: put this in callback instead of receiving
-
             if (intent.getAction().equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
                 onBluetoothStateChanged(mLocalManager.getBluetoothState());
             } else if (intent.getAction().equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
+                // TODO: If this is a scanning screen, maybe return on successful pairing
+
                 int bondState = intent
                         .getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);
                 if (bondState == BluetoothDevice.BOND_BONDED) {
@@ -153,6 +158,8 @@
             action = intent.getAction();
         }
 
+        if (getPreferenceScreen() != null) getPreferenceScreen().removeAll();
+
         if (action.equals(BluetoothDevicePicker.ACTION_LAUNCH)) {
             mScreenType = SCREEN_TYPE_DEVICEPICKER;
             mNeedAuth = intent.getBooleanExtra(BluetoothDevicePicker.EXTRA_NEED_AUTH, false);
@@ -169,6 +176,10 @@
 
             activity.setTitle(activity.getString(R.string.device_picker));
             addPreferencesFromResource(R.xml.device_picker);
+        } else if (action.equals(ACTION_LAUNCH_SCAN_MODE)) {
+            mScreenType = SCREEN_TYPE_SCAN;
+
+            addPreferencesFromResource(R.xml.device_picker);
         } else {
             addPreferencesFromResource(R.xml.bluetooth_settings);
 
@@ -182,10 +193,9 @@
 
             mNamePreference = (BluetoothNamePreference) findPreference(KEY_BT_NAME);
 
-            mDeviceList = (ProgressCategory) findPreference(KEY_BT_DEVICE_LIST);
         }
 
-        mDeviceList = (ProgressCategory) findPreference(KEY_BT_DEVICE_LIST);
+        mDeviceList = (PreferenceCategory) findPreference(KEY_BT_DEVICE_LIST);
 
         registerForContextMenu(getListView());
 
@@ -200,7 +210,9 @@
         // bluetooth manager
         mDevicePreferenceMap.clear();
         mDeviceList.removeAll();
-        addDevices();
+        if (mScreenType != SCREEN_TYPE_SCAN) {
+            addDevices();
+        }
 
         if (mScreenType == SCREEN_TYPE_SETTINGS) {
             mEnabler.resume();
@@ -210,8 +222,11 @@
 
         mLocalManager.registerCallback(this);
 
-        mDeviceList.setProgress(mLocalManager.getBluetoothAdapter().isDiscovering());
-        mLocalManager.startScanning(false);
+        updateProgressUi(mLocalManager.getBluetoothAdapter().isDiscovering());
+
+        if (mScreenType != SCREEN_TYPE_SETTINGS) {
+            mLocalManager.startScanning(true);
+        }
 
         IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
@@ -249,6 +264,13 @@
         }
     }
 
+    public void onClick(View v) {
+        if (v.getTag() instanceof CachedBluetoothDevice) {
+            CachedBluetoothDevice device = (CachedBluetoothDevice) v.getTag();
+            device.onClickedAdvancedOptions(this);
+        }
+    }
+
     @Override
     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
             Preference preference) {
@@ -260,7 +282,7 @@
 
         if (preference instanceof BluetoothDevicePreference) {
             BluetoothDevicePreference btPreference = (BluetoothDevicePreference)preference;
-            if (mScreenType == SCREEN_TYPE_SETTINGS) {
+            if (mScreenType == SCREEN_TYPE_SETTINGS || mScreenType == SCREEN_TYPE_SCAN) {
                 btPreference.getCachedDevice().onClicked();
             } else if (mScreenType == SCREEN_TYPE_DEVICEPICKER) {
                 CachedBluetoothDevice device = btPreference.getCachedDevice();
@@ -312,7 +334,7 @@
         CachedBluetoothDevice cachedDevice = getDeviceFromMenuInfo(item.getMenuInfo());
         if (cachedDevice == null) return false;
 
-        cachedDevice.onContextItemSelected(item);
+        cachedDevice.onContextItemSelected(item, this);
         return true;
     }
 
@@ -337,8 +359,11 @@
             throw new IllegalStateException("Got onDeviceAdded, but cachedDevice already exists");
         }
 
-        if (addDevicePreference(cachedDevice)) {
-            createDevicePreference(cachedDevice);
+        if (mScreenType != SCREEN_TYPE_SETTINGS
+                || cachedDevice.getBondState() == BluetoothDevice.BOND_BONDED) {
+            if (addDevicePreference(cachedDevice)) {
+                createDevicePreference(cachedDevice);
+            }
         }
      }
 
@@ -406,6 +431,9 @@
             preference = new BluetoothDevicePreference(
                     getActivity(), cachedDevice, CachedBluetoothDevice.OTHER_PROFILES);
         }
+        if (mScreenType == SCREEN_TYPE_SETTINGS) {
+            preference.setOnSettingsClickListener(this);
+        }
         mDeviceList.addPreference(preference);
         mDevicePreferenceMap.put(cachedDevice, preference);
     }
@@ -418,16 +446,23 @@
     }
 
     public void onScanningStateChanged(boolean started) {
-        mDeviceList.setProgress(started);
+        updateProgressUi(started);
     }
 
+    private void updateProgressUi(boolean start) {
+        if (mDeviceList instanceof ProgressCategory) {
+            ((ProgressCategory) mDeviceList).setProgress(start);
+        }
+    }
     private void onBluetoothStateChanged(int bluetoothState) {
         // When bluetooth is enabled (and we are in the activity, which we are),
         // we should start a scan
         if (bluetoothState == BluetoothAdapter.STATE_ON) {
-            mLocalManager.startScanning(false);
+            if (mScreenType != SCREEN_TYPE_SETTINGS) {
+                mLocalManager.startScanning(false);
+            }
         } else if (bluetoothState == BluetoothAdapter.STATE_OFF) {
-            mDeviceList.setProgress(false);
+            updateProgressUi(false);
         }
     }
 
@@ -480,4 +515,22 @@
         }
         getActivity().sendBroadcast(intent);
     }
+
+    public static class FindNearby extends BluetoothSettings {
+
+        public FindNearby() {
+        }
+
+        @Override
+        public void onActivityCreated(Bundle savedInstanceState) {
+            Bundle args = super.getArguments();
+            if (args == null) {
+                args = new Bundle();
+                setArguments(args);
+            }
+            args.putString(ACTION, ACTION_LAUNCH_SCAN_MODE);
+            super.onActivityCreated(savedInstanceState);
+        }
+    }
 }
+
diff --git a/src/com/android/settings/bluetooth/CachedBluetoothDevice.java b/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
index c0fa105..22fa005 100644
--- a/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
+++ b/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
@@ -16,28 +16,31 @@
 
 package com.android.settings.bluetooth;
 
+import com.android.settings.R;
+
+import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
+
 import android.app.AlertDialog;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothClass;
 import android.bluetooth.BluetoothDevice;
 import android.content.Context;
 import android.content.DialogInterface;
-import android.content.Intent;
 import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
 import android.os.ParcelUuid;
 import android.os.SystemClock;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.ContextMenu;
 import android.view.Menu;
 import android.view.MenuItem;
 
-import com.android.settings.R;
-import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
-
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Set;
 
 /**
  * CachedBluetoothDevice represents a remote Bluetooth device. It contains
@@ -63,6 +66,7 @@
     private String mName;
     private short mRssi;
     private BluetoothClass mBtClass;
+    private Context mContext;
 
     private List<Profile> mProfiles = new ArrayList<Profile>();
 
@@ -138,6 +142,7 @@
         }
 
         mDevice = device;
+        mContext = context;
 
         fillData();
     }
@@ -655,6 +660,20 @@
         return SettingsBtStatus.getPairingStatusSummary(getBondState());
     }
 
+    public List<Drawable> getProfileIcons() {
+        ArrayList<Drawable> drawables = new ArrayList<Drawable>();
+
+        for (Profile profile : mProfiles) {
+            LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
+                    .getProfileManager(mLocalManager, profile);
+            int iconResource = profileManager.getDrawableResource();
+            if (iconResource != 0) {
+                drawables.add(mContext.getResources().getDrawable(iconResource));
+            }
+        }
+
+        return drawables;
+    }
     /**
      * We have special summaries when particular profiles are connected. This
      * checks for those states and returns an applicable summary.
@@ -781,7 +800,7 @@
      *
      * @param item The item that was clicked.
      */
-    public void onContextItemSelected(MenuItem item) {
+    public void onContextItemSelected(MenuItem item, SettingsPreferenceFragment fragment) {
         switch (item.getItemId()) {
             case CONTEXT_ITEM_DISCONNECT:
                 disconnect();
@@ -796,21 +815,34 @@
                 break;
 
             case CONTEXT_ITEM_CONNECT_ADVANCED:
-                Intent intent = new Intent();
-                // Need an activity context to open this in our task
-                Context context = mLocalManager.getForegroundActivity();
-                if (context == null) {
-                    // Fallback on application context, and open in a new task
-                    context = mLocalManager.getContext();
-                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                }
-                intent.setClass(context, ConnectSpecificProfilesActivity.class);
-                intent.putExtra(ConnectSpecificProfilesActivity.EXTRA_DEVICE, mDevice);
-                context.startActivity(intent);
+            onClickedAdvancedOptions(fragment);
                 break;
         }
     }
 
+    public void onClickedAdvancedOptions(SettingsPreferenceFragment fragment) {
+        // TODO: Verify if there really is a case when there's no foreground
+        // activity
+
+        // Intent intent = new Intent();
+        // // Need an activity context to open this in our task
+        // Context context = mLocalManager.getForegroundActivity();
+        // if (context == null) {
+        // // Fallback on application context, and open in a new task
+        // context = mLocalManager.getContext();
+        // intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        // }
+        // intent.setClass(context, ConnectSpecificProfilesActivity.class);
+        // intent.putExtra(ConnectSpecificProfilesActivity.EXTRA_DEVICE,
+        // mDevice);
+        // context.startActivity(intent);
+        Preference pref = new Preference(fragment.getActivity());
+        pref.setTitle(getName());
+        pref.setFragment(DeviceProfilesSettings.class.getName());
+        pref.getExtras().putParcelable(DeviceProfilesSettings.EXTRA_DEVICE, mDevice);
+        ((PreferenceActivity) fragment.getActivity()).onPreferenceStartFragment(fragment, pref);
+    }
+
     public void registerCallback(Callback callback) {
         synchronized (mCallbacks) {
             mCallbacks.add(callback);
diff --git a/src/com/android/settings/bluetooth/ConnectSpecificProfilesActivity.java b/src/com/android/settings/bluetooth/ConnectSpecificProfilesActivity.java
deleted file mode 100644
index ac2b4d8..0000000
--- a/src/com/android/settings/bluetooth/ConnectSpecificProfilesActivity.java
+++ /dev/null
@@ -1,310 +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.bluetooth.BluetoothDevice;
-import android.content.Intent;
-import android.os.Bundle;
-import android.preference.CheckBoxPreference;
-import android.preference.Preference;
-import android.preference.PreferenceActivity;
-import android.preference.PreferenceGroup;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.settings.R;
-import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
-
-/**
- * ConnectSpecificProfilesActivity presents the user with all of the profiles
- * for a particular device, and allows him to choose which should be connected
- * (or disconnected).
- */
-public class ConnectSpecificProfilesActivity extends PreferenceActivity
-        implements CachedBluetoothDevice.Callback, Preference.OnPreferenceChangeListener {
-    private static final String TAG = "ConnectSpecificProfilesActivity";
-
-    private static final String KEY_ONLINE_MODE = "online_mode";
-    private static final String KEY_TITLE = "title";
-    private static final String KEY_PROFILE_CONTAINER = "profile_container";
-
-    public static final String EXTRA_DEVICE = "device";
-
-    private LocalBluetoothManager mManager;
-    private CachedBluetoothDevice mCachedDevice;
-
-    private PreferenceGroup mProfileContainer;
-    private CheckBoxPreference mOnlineModePreference;
-
-    /**
-     * The current mode of this activity and its checkboxes (either online mode
-     * or offline mode). In online mode, user interactions with the profile
-     * checkboxes will also toggle the profile's connectivity. In offline mode,
-     * they will not, and only the preferred state will be saved for the
-     * profile.
-     */
-    private boolean mOnlineMode;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        BluetoothDevice device;
-        if (savedInstanceState != null) {
-            device = savedInstanceState.getParcelable(EXTRA_DEVICE);
-        } else {
-            Intent intent = getIntent();
-            device = intent.getParcelableExtra(EXTRA_DEVICE);
-        }
-
-        if (device == null) {
-            Log.w(TAG, "Activity started without a remote Bluetooth device");
-            finish();
-        }
-
-        mManager = LocalBluetoothManager.getInstance(this);
-        mCachedDevice = mManager.getCachedDeviceManager().findDevice(device);
-        if (mCachedDevice == null) {
-            Log.w(TAG, "Device not found, cannot connect to it");
-            finish();
-        }
-
-        addPreferencesFromResource(R.xml.bluetooth_device_advanced);
-        mProfileContainer = (PreferenceGroup) findPreference(KEY_PROFILE_CONTAINER);
-
-        // Set the title of the screen
-        findPreference(KEY_TITLE).setTitle(
-                getString(R.string.bluetooth_device_advanced_title, mCachedDevice.getName()));
-
-        // Listen for check/uncheck of the online mode checkbox
-        mOnlineModePreference = (CheckBoxPreference) findPreference(KEY_ONLINE_MODE);
-        mOnlineModePreference.setOnPreferenceChangeListener(this);
-
-        // Add a preference for each profile
-        addPreferencesForProfiles();
-    }
-
-    @Override
-    protected void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-
-        outState.putParcelable(EXTRA_DEVICE, mCachedDevice.getDevice());
-    }
-
-    @Override
-    protected void onResume() {
-        super.onResume();
-
-        mManager.setForegroundActivity(this);
-        mCachedDevice.registerCallback(this);
-
-        refresh();
-    }
-
-    @Override
-    protected void onPause() {
-        super.onPause();
-
-        mCachedDevice.unregisterCallback(this);
-        mManager.setForegroundActivity(null);
-    }
-
-    private void addPreferencesForProfiles() {
-        for (Profile profile : mCachedDevice.getConnectableProfiles()) {
-            Preference pref = createProfilePreference(profile);
-            mProfileContainer.addPreference(pref);
-        }
-    }
-
-    /**
-     * Creates a checkbox preference for the particular profile. The key will be
-     * the profile's name.
-     *
-     * @param profile The profile for which the preference controls.
-     * @return A preference that allows the user to choose whether this profile
-     *         will be connected to.
-     */
-    private CheckBoxPreference createProfilePreference(Profile profile) {
-        CheckBoxPreference pref = new CheckBoxPreference(this);
-        pref.setKey(profile.toString());
-        pref.setTitle(profile.localizedString);
-        pref.setPersistent(false);
-        pref.setOnPreferenceChangeListener(this);
-
-        LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
-                .getProfileManager(mManager, profile);
-
-        /**
-         * Gray out checkbox while connecting and disconnecting
-         */
-        pref.setEnabled(!mCachedDevice.isBusy());
-
-        refreshProfilePreference(pref, profile);
-
-        return pref;
-    }
-
-    public boolean onPreferenceChange(Preference preference, Object newValue) {
-        String key = preference.getKey();
-        if (TextUtils.isEmpty(key) || newValue == null) return true;
-
-        if (key.equals(KEY_ONLINE_MODE)) {
-            onOnlineModeCheckedStateChanged((Boolean) newValue);
-
-        } else {
-            Profile profile = getProfileOf(preference);
-            if (profile == null) return false;
-            onProfileCheckedStateChanged(profile, (Boolean) newValue);
-        }
-
-        return true;
-    }
-
-    private void onOnlineModeCheckedStateChanged(boolean checked) {
-        setOnlineMode(checked, true);
-    }
-
-    private void onProfileCheckedStateChanged(Profile profile, boolean checked) {
-        LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
-                .getProfileManager(mManager, profile);
-        profileManager.setPreferred(mCachedDevice.getDevice(), checked);
-        if (mOnlineMode) {
-            if (checked) {
-                mCachedDevice.connect(profile);
-            } else {
-                mCachedDevice.disconnect(profile);
-            }
-        }
-    }
-
-    public void onDeviceAttributesChanged(CachedBluetoothDevice cachedDevice) {
-        refresh();
-    }
-
-    private void refresh() {
-        // We are in 'online mode' if we are connected, connecting, or disconnecting
-        setOnlineMode(mCachedDevice.isConnected() || mCachedDevice.isBusy(), false);
-        refreshProfiles();
-    }
-
-    /**
-     * Switches between online/offline mode.
-     *
-     * @param onlineMode Whether to be in online mode, or offline mode.
-     * @param takeAction Whether to take action (i.e., connect or disconnect)
-     *            based on the new online mode.
-     */
-    private void setOnlineMode(boolean onlineMode, boolean takeAction) {
-        mOnlineMode = onlineMode;
-
-        if (takeAction) {
-            if (onlineMode) {
-                mCachedDevice.connect();
-            } else {
-                mCachedDevice.disconnect();
-            }
-        }
-
-        refreshOnlineModePreference();
-    }
-
-    private void refreshOnlineModePreference() {
-        mOnlineModePreference.setChecked(mOnlineMode);
-
-        /* Gray out checkbox while connecting and disconnecting */
-        mOnlineModePreference.setEnabled(!mCachedDevice.isBusy());
-
-        /**
-         * If the device is online, show status. Otherwise, show a summary that
-         * describes what the checkbox does.
-         */
-        mOnlineModePreference.setSummary(mOnlineMode ?
-                mCachedDevice.getSummary(CachedBluetoothDevice.OTHER_PROFILES)
-                : R.string.bluetooth_device_advanced_online_mode_summary);
-    }
-
-    private void refreshProfiles() {
-        for (Profile profile : mCachedDevice.getConnectableProfiles()) {
-            CheckBoxPreference profilePref =
-                    (CheckBoxPreference) findPreference(profile.toString());
-            if (profilePref == null) {
-                profilePref = createProfilePreference(profile);
-                mProfileContainer.addPreference(profilePref);
-            } else {
-                refreshProfilePreference(profilePref, profile);
-            }
-        }
-    }
-
-    private void refreshProfilePreference(CheckBoxPreference profilePref, Profile profile) {
-        BluetoothDevice device = mCachedDevice.getDevice();
-        LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
-                .getProfileManager(mManager, profile);
-
-        int connectionStatus = profileManager.getConnectionStatus(device);
-
-        /*
-         * Gray out checkbox while connecting and disconnecting
-         */
-        profilePref.setEnabled(!mCachedDevice.isBusy());
-        profilePref.setSummary(getProfileSummary(profileManager, profile, device,
-                connectionStatus, mOnlineMode));
-
-        profilePref.setChecked(profileManager.isPreferred(device));
-    }
-
-    private Profile getProfileOf(Preference pref) {
-        if (!(pref instanceof CheckBoxPreference)) return null;
-        String key = pref.getKey();
-        if (TextUtils.isEmpty(key)) return null;
-
-        try {
-            return Profile.valueOf(pref.getKey());
-        } catch (IllegalArgumentException e) {
-            return null;
-        }
-    }
-
-    private static int getProfileSummary(LocalBluetoothProfileManager profileManager,
-            Profile profile, BluetoothDevice device, int connectionStatus, boolean onlineMode) {
-        if (!onlineMode || connectionStatus == SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED) {
-            return getProfileSummaryForSettingPreference(profile);
-        } else {
-            return profileManager.getSummary(device);
-        }
-    }
-
-    /**
-     * Gets the summary that describes when checked, it will become a preferred profile.
-     *
-     * @param profile The profile to get the summary for.
-     * @return The summary.
-     */
-    private static final int getProfileSummaryForSettingPreference(Profile profile) {
-        switch (profile) {
-            case A2DP:
-                return R.string.bluetooth_a2dp_profile_summary_use_for;
-            case HEADSET:
-                return R.string.bluetooth_headset_profile_summary_use_for;
-            case HID:
-                return R.string.bluetooth_hid_profile_summary_use_for;
-            default:
-                return 0;
-        }
-    }
-
-}
diff --git a/src/com/android/settings/bluetooth/DeviceProfilesSettings.java b/src/com/android/settings/bluetooth/DeviceProfilesSettings.java
new file mode 100644
index 0000000..f8a66f6
--- /dev/null
+++ b/src/com/android/settings/bluetooth/DeviceProfilesSettings.java
@@ -0,0 +1,346 @@
+/*
+ * 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 com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
+
+import android.bluetooth.BluetoothDevice;
+import android.content.Context;
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.EditTextPreference;
+import android.preference.Preference;
+import android.preference.PreferenceGroup;
+import android.preference.PreferenceScreen;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.View;
+
+import java.util.HashMap;
+
+/**
+ * ConnectSpecificProfilesActivity presents the user with all of the profiles
+ * for a particular device, and allows him to choose which should be connected
+ * (or disconnected).
+ */
+public class DeviceProfilesSettings extends SettingsPreferenceFragment
+        implements CachedBluetoothDevice.Callback, Preference.OnPreferenceChangeListener,
+                View.OnClickListener {
+    private static final String TAG = "DeviceProfilesSettings";
+
+    private static final String KEY_TITLE = "title";
+    private static final String KEY_RENAME_DEVICE = "rename_device";
+    private static final String KEY_PROFILE_CONTAINER = "profile_container";
+    private static final String KEY_UNPAIR = "unpair";
+    private static final String KEY_ALLOW_INCOMING = "allow_incoming";
+
+    private static final String AUTO_CONNECT_KEY_SUFFIX = "X";
+
+    public static final String EXTRA_DEVICE = "device";
+
+    private LocalBluetoothManager mManager;
+    private CachedBluetoothDevice mCachedDevice;
+
+    private PreferenceGroup mProfileContainer;
+    private CheckBoxPreference mAllowIncomingPref;
+    private EditTextPreference mDeviceNamePref;
+    private HashMap<String,CheckBoxPreference> mAutoConnectPrefs
+            = new HashMap<String,CheckBoxPreference>();
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        BluetoothDevice device;
+        if (savedInstanceState != null) {
+            device = savedInstanceState.getParcelable(EXTRA_DEVICE);
+        } else {
+            Bundle args = getArguments();
+            device = args.getParcelable(EXTRA_DEVICE);
+        }
+
+        if (device == null) {
+            Log.w(TAG, "Activity started without a remote Bluetooth device");
+            finish();
+        }
+
+        mManager = LocalBluetoothManager.getInstance(getActivity());
+        mCachedDevice = mManager.getCachedDeviceManager().findDevice(device);
+        if (mCachedDevice == null) {
+            Log.w(TAG, "Device not found, cannot connect to it");
+            finish();
+        }
+
+        addPreferencesFromResource(R.xml.bluetooth_device_advanced);
+        getPreferenceScreen().setOrderingAsAdded(false);
+
+        mProfileContainer = (PreferenceGroup) findPreference(KEY_PROFILE_CONTAINER);
+        mAllowIncomingPref = (CheckBoxPreference) findPreference(KEY_ALLOW_INCOMING);
+        mAllowIncomingPref.setChecked(isIncomingFileTransfersAllowed());
+
+        mDeviceNamePref = (EditTextPreference) findPreference(KEY_RENAME_DEVICE);
+        mDeviceNamePref.setSummary(mCachedDevice.getName());
+        mDeviceNamePref.setText(mCachedDevice.getName());
+
+        // Set the title of the screen
+        findPreference(KEY_TITLE).setTitle(getResources()
+                .getString(R.string.bluetooth_device_advanced_title, mCachedDevice.getName()));
+
+        // Add a preference for each profile
+        addPreferencesForProfiles();
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+
+        outState.putParcelable(EXTRA_DEVICE, mCachedDevice.getDevice());
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+
+        mManager.setForegroundActivity(getActivity());
+        mCachedDevice.registerCallback(this);
+
+        refresh();
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+
+        mCachedDevice.unregisterCallback(this);
+        mManager.setForegroundActivity(null);
+    }
+
+    private void addPreferencesForProfiles() {
+        for (Profile profile : mCachedDevice.getConnectableProfiles()) {
+            Preference pref = createProfilePreference(profile);
+            mProfileContainer.addPreference(pref);
+        }
+    }
+
+    /**
+     * Creates a checkbox preference for the particular profile. The key will be
+     * the profile's name.
+     *
+     * @param profile The profile for which the preference controls.
+     * @return A preference that allows the user to choose whether this profile
+     *         will be connected to.
+     */
+    private Preference createProfilePreference(Profile profile) {
+        BluetoothProfilePreference pref = new BluetoothProfilePreference(getActivity(), profile);
+        pref.setKey(profile.toString());
+        pref.setTitle(profile.localizedString);
+        pref.setExpanded(false);
+        pref.setPersistent(false);
+        pref.setOrder(getProfilePreferenceIndex(profile));
+        pref.setOnExpandClickListener(this);
+
+        LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
+                .getProfileManager(mManager, profile);
+
+        /**
+         * Gray out profile while connecting and disconnecting
+         */
+        pref.setEnabled(!mCachedDevice.isBusy());
+
+        refreshProfilePreference(pref, profile);
+
+        return pref;
+    }
+
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) {
+        String key = preference.getKey();
+        if (preference instanceof BluetoothProfilePreference) {
+            onProfileClicked(preference, Profile.valueOf(key));
+            return true;
+        } else if (key.equals(KEY_UNPAIR)) {
+            unpairDevice();
+            finish();
+            return true;
+        }
+
+        return false;
+    }
+
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        if (preference == mAllowIncomingPref) {
+            setIncomingFileTransfersAllowed(mAllowIncomingPref.isChecked());
+        } else if (preference == mDeviceNamePref) {
+            // TODO: Verify and check for error conditions
+            mCachedDevice.setName(mDeviceNamePref.getText());
+        } else {
+            return false;
+        }
+
+        return true;
+    }
+
+    private void onProfileClicked(Preference preference, Profile profile) {
+        LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
+                .getProfileManager(mManager, profile);
+        // TODO: Get the current state and flip it, updating the summary for the preference
+
+//        profileManager.setPreferred(mCachedDevice.getDevice(), checked);
+//
+//        if (checked) {
+//            mCachedDevice.connect(profile);
+//        } else {
+//            mCachedDevice.disconnect(profile);
+//        }
+    }
+
+    public void onDeviceAttributesChanged(CachedBluetoothDevice cachedDevice) {
+        refresh();
+    }
+
+    private void refresh() {
+        refreshProfiles();
+    }
+
+    private void refreshProfiles() {
+        for (Profile profile : mCachedDevice.getConnectableProfiles()) {
+            Preference profilePref = findPreference(profile.toString());
+            if (profilePref == null) {
+                profilePref = createProfilePreference(profile);
+                mProfileContainer.addPreference(profilePref);
+            } else {
+                refreshProfilePreference(profilePref, profile);
+            }
+        }
+    }
+
+    private void refreshProfilePreference(Preference profilePref, Profile profile) {
+        BluetoothDevice device = mCachedDevice.getDevice();
+        LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
+                .getProfileManager(mManager, profile);
+
+        int connectionStatus = profileManager.getConnectionStatus(device);
+
+        /*
+         * Gray out checkbox while connecting and disconnecting
+         */
+        profilePref.setEnabled(!mCachedDevice.isBusy());
+        profilePref.setSummary(getProfileSummary(profileManager, profile, device,
+                connectionStatus, isDeviceOnline()));
+        // TODO:
+        //profilePref.setChecked(profileManager.isPreferred(device));
+    }
+
+    private Profile getProfileOf(Preference pref) {
+        if (!(pref instanceof CheckBoxPreference)) return null;
+        String key = pref.getKey();
+        if (TextUtils.isEmpty(key)) return null;
+
+        try {
+            return Profile.valueOf(pref.getKey());
+        } catch (IllegalArgumentException e) {
+            return null;
+        }
+    }
+
+    private static int getProfileSummary(LocalBluetoothProfileManager profileManager,
+            Profile profile, BluetoothDevice device, int connectionStatus, boolean onlineMode) {
+        if (!onlineMode || connectionStatus == SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED) {
+            return getProfileSummaryForSettingPreference(profile);
+        } else {
+            return profileManager.getSummary(device);
+        }
+    }
+
+    /**
+     * Gets the summary that describes when checked, it will become a preferred profile.
+     *
+     * @param profile The profile to get the summary for.
+     * @return The summary.
+     */
+    private static final int getProfileSummaryForSettingPreference(Profile profile) {
+        switch (profile) {
+            case A2DP:
+                return R.string.bluetooth_a2dp_profile_summary_use_for;
+            case HEADSET:
+                return R.string.bluetooth_headset_profile_summary_use_for;
+            case HID:
+                return R.string.bluetooth_hid_profile_summary_use_for;
+            default:
+                return 0;
+        }
+    }
+
+    public void onClick(View v) {
+        if (v.getTag() instanceof Profile) {
+            Profile prof = (Profile) v.getTag();
+            CheckBoxPreference autoConnectPref = mAutoConnectPrefs.get(prof.toString());
+            if (autoConnectPref == null) {
+                autoConnectPref = new CheckBoxPreference(getActivity());
+                autoConnectPref.setKey(prof.toString() + AUTO_CONNECT_KEY_SUFFIX);
+                autoConnectPref.setTitle(getCheckBoxTitle(prof));
+                autoConnectPref.setOrder(getProfilePreferenceIndex(prof) + 1);
+                autoConnectPref.setChecked(getAutoConnect(prof));
+                mAutoConnectPrefs.put(prof.name(), autoConnectPref);
+            }
+            BluetoothProfilePreference profilePref =
+                    (BluetoothProfilePreference) findPreference(prof.toString());
+            if (profilePref != null) {
+                if (profilePref.isExpanded()) {
+                    mProfileContainer.addPreference(autoConnectPref);
+                } else {
+                    mProfileContainer.removePreference(autoConnectPref);
+                }
+            }
+        }
+    }
+
+    private int getProfilePreferenceIndex(Profile prof) {
+        return mProfileContainer.getOrder() + prof.ordinal() * 10;
+    }
+
+    private void unpairDevice() {
+        mCachedDevice.unpair();
+    }
+
+    private boolean isDeviceOnline() {
+        // TODO: Verify
+        return mCachedDevice.isConnected() || mCachedDevice.isBusy();
+    }
+
+    private void setIncomingFileTransfersAllowed(boolean allow) {
+        // TODO:
+        Log.d(TAG, "Set allow incoming = " + allow);
+    }
+
+    private boolean isIncomingFileTransfersAllowed() {
+        // TODO:
+        return true;
+    }
+
+    private String getCheckBoxTitle(Profile prof) {
+        // TODO: Use resources and base it on profile if necessary
+        return "Auto connect";
+    }
+
+    private boolean getAutoConnect(Profile prof) {
+        // TODO: Get the auto connect toggle state for the profile
+        return true;
+    }
+}
diff --git a/src/com/android/settings/bluetooth/LocalBluetoothManager.java b/src/com/android/settings/bluetooth/LocalBluetoothManager.java
index 613ee25..b46cc96 100644
--- a/src/com/android/settings/bluetooth/LocalBluetoothManager.java
+++ b/src/com/android/settings/bluetooth/LocalBluetoothManager.java
@@ -47,7 +47,7 @@
     private static final String SHARED_PREFERENCES_NAME = "bluetooth_settings";
 
     /** Singleton instance. */
-    private static LocalBluetoothManager INSTANCE;
+    private static LocalBluetoothManager sInstance;
     private boolean mInitialized;
 
     private Context mContext;
@@ -87,17 +87,17 @@
 
     public static LocalBluetoothManager getInstance(Context context) {
         synchronized (LocalBluetoothManager.class) {
-            if (INSTANCE == null) {
-                INSTANCE = new LocalBluetoothManager();
+            if (sInstance == null) {
+                sInstance = new LocalBluetoothManager();
             }
 
-            if (!INSTANCE.init(context)) {
+            if (!sInstance.init(context)) {
                 return null;
             }
 
-            LocalBluetoothProfileManager.init(INSTANCE);
+            LocalBluetoothProfileManager.init(sInstance);
 
-            return INSTANCE;
+            return sInstance;
         }
     }
 
diff --git a/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java b/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java
index 1480b16..f7ad3d3 100644
--- a/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java
+++ b/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java
@@ -31,12 +31,10 @@
 import android.util.Log;
 
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 /**
  * LocalBluetoothProfileManager is an abstract class defining the basic
@@ -123,7 +121,8 @@
         }
     }
 
-    private static LinkedList<ServiceListener> mServiceListeners = new LinkedList<ServiceListener>();
+    private static LinkedList<ServiceListener> mServiceListeners =
+            new LinkedList<ServiceListener>();
 
     public static void addServiceListener(ServiceListener l) {
         mServiceListeners.add(l);
@@ -221,6 +220,10 @@
 
     public abstract boolean isProfileReady();
 
+    public int getDrawableResource() {
+        return R.drawable.ic_bt_headphones_a2dp;
+    }
+
     // TODO: int instead of enum
     public enum Profile {
         HEADSET(R.string.bluetooth_profile_headset),
@@ -347,6 +350,11 @@
         public boolean isProfileReady() {
             return true;
         }
+
+        @Override
+        public int getDrawableResource() {
+            return R.drawable.ic_bt_headphones_a2dp;
+        }
     }
 
     /**
@@ -489,6 +497,11 @@
                 return SettingsBtStatus.CONNECTION_STATUS_UNKNOWN;
             }
         }
+
+        @Override
+        public int getDrawableResource() {
+            return R.drawable.ic_bt_headset_hfp;
+        }
     }
 
     /**
@@ -563,6 +576,12 @@
                 return SettingsBtStatus.CONNECTION_STATUS_UNKNOWN;
             }
         }
+
+        @Override
+        public int getDrawableResource() {
+            // TODO:
+            return 0;
+        }
     }
 
     private static class HidProfileManager extends LocalBluetoothProfileManager {
@@ -645,6 +664,12 @@
                 mService.setInputDevicePriority(device, BluetoothInputDevice.PRIORITY_OFF);
             }
         }
+
+        @Override
+        public int getDrawableResource() {
+            // TODO:
+            return 0;
+        }
     }
 
     private static class PanProfileManager extends LocalBluetoothProfileManager {
@@ -721,5 +746,11 @@
         public void setPreferred(BluetoothDevice device, boolean preferred) {
             return;
         }
+
+        @Override
+        public int getDrawableResource() {
+            // TODO:
+            return 0;
+        }
     }
 }