diff --git a/src/com/android/settings/TetherSettings.java b/src/com/android/settings/TetherSettings.java
index 2ff3254..af83157 100644
--- a/src/com/android/settings/TetherSettings.java
+++ b/src/com/android/settings/TetherSettings.java
@@ -35,8 +35,6 @@
 import android.preference.CheckBoxPreference;
 import android.preference.Preference;
 import android.preference.PreferenceScreen;
-import android.view.LayoutInflater;
-import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewParent;
 import android.webkit.WebView;
@@ -49,7 +47,6 @@
  * Displays preferences for Tethering.
  */
 public class TetherSettings extends SettingsPreferenceFragment {
-    private static final String TAG = "TetheringSettings";
 
     private static final String USB_TETHER_SETTINGS = "usb_tether_settings";
     private static final String ENABLE_WIFI_AP = "enable_wifi_ap";
@@ -66,8 +63,6 @@
     private WebView mView;
     private CheckBoxPreference mUsbTether;
 
-    private CheckBoxPreference mEnableWifiAp;
-    private PreferenceScreen mWifiApSettings;
     private WifiApEnabler mWifiApEnabler;
 
     private CheckBoxPreference mBluetoothTether;
@@ -95,9 +90,9 @@
                     BluetoothProfile.PAN);
         }
 
-
-        mEnableWifiAp = (CheckBoxPreference) findPreference(ENABLE_WIFI_AP);
-        mWifiApSettings = (PreferenceScreen) findPreference(WIFI_AP_SETTINGS);
+        CheckBoxPreference enableWifiAp =
+                (CheckBoxPreference) findPreference(ENABLE_WIFI_AP);
+        Preference wifiApSettings = findPreference(WIFI_AP_SETTINGS);
         mUsbTether = (CheckBoxPreference) findPreference(USB_TETHER_SETTINGS);
         mBluetoothTether = (CheckBoxPreference) findPreference(ENABLE_BLUETOOTH_TETHERING);
         mTetherHelp = (PreferenceScreen) findPreference(TETHERING_HELP);
@@ -118,8 +113,8 @@
         }
 
         if (!wifiAvailable) {
-            getPreferenceScreen().removePreference(mEnableWifiAp);
-            getPreferenceScreen().removePreference(mWifiApSettings);
+            getPreferenceScreen().removePreference(enableWifiAp);
+            getPreferenceScreen().removePreference(wifiApSettings);
         }
 
         if (!bluetoothAvailable) {
@@ -132,7 +127,7 @@
             }
         }
 
-        mWifiApEnabler = new WifiApEnabler(activity, mEnableWifiAp);
+        mWifiApEnabler = new WifiApEnabler(activity, enableWifiAp);
         mView = new WebView(activity);
     }
 
@@ -154,22 +149,22 @@
             // check for the full language + country resource, if not there, try just language
             final AssetManager am = getActivity().getAssets();
             String path = HELP_PATH.replace("%y", locale.getLanguage().toLowerCase());
-            path = path.replace("%z", "_"+locale.getCountry().toLowerCase());
+            path = path.replace("%z", '_'+locale.getCountry().toLowerCase());
             boolean useCountry = true;
             InputStream is = null;
             try {
                 is = am.open(path);
-            } catch (Exception e) {
+            } catch (Exception ignored) {
                 useCountry = false;
             } finally {
                 if (is != null) {
                     try {
                         is.close();
-                    } catch (Exception e) {}
+                    } catch (Exception ignored) {}
                 }
             }
             String url = HELP_URL.replace("%y", locale.getLanguage().toLowerCase());
-            url = url.replace("%z", (useCountry ? "_"+locale.getCountry().toLowerCase() : ""));
+            url = url.replace("%z", useCountry ? '_'+locale.getCountry().toLowerCase() : "");
             if ((mUsbRegexs.length != 0) && (mWifiRegexs.length == 0)) {
                 url = url.replace("%x", USB_HELP_MODIFIER);
             } else if ((mWifiRegexs.length != 0) && (mUsbRegexs.length == 0)) {
@@ -271,10 +266,8 @@
             String[] errored) {
         ConnectivityManager cm =
                 (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
-        boolean usbTethered = false;
         boolean usbAvailable = false;
         int usbError = ConnectivityManager.TETHER_ERROR_NO_ERROR;
-        boolean usbErrored = false;
         boolean massStorageActive =
                 Environment.MEDIA_SHARED.equals(Environment.getExternalStorageState());
         for (String s : available) {
@@ -287,11 +280,13 @@
                 }
             }
         }
+        boolean usbTethered = false;
         for (String s : tethered) {
             for (String regex : mUsbRegexs) {
                 if (s.matches(regex)) usbTethered = true;
             }
         }
+        boolean usbErrored = false;
         for (String s: errored) {
             for (String regex : mUsbRegexs) {
                 if (s.matches(regex)) usbErrored = true;
@@ -329,25 +324,23 @@
             String[] errored) {
         ConnectivityManager cm =
                 (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
-        boolean bluetoothTethered = false;
-        boolean bluetoothAvailable = false;
         int bluetoothError = ConnectivityManager.TETHER_ERROR_NO_ERROR;
-        boolean bluetoothErrored = false;
         for (String s : available) {
             for (String regex : mBluetoothRegexs) {
                 if (s.matches(regex)) {
-                    bluetoothAvailable = true;
                     if (bluetoothError == ConnectivityManager.TETHER_ERROR_NO_ERROR) {
                         bluetoothError = cm.getLastTetherError(s);
                     }
                 }
             }
         }
+        boolean bluetoothTethered = false;
         for (String s : tethered) {
             for (String regex : mBluetoothRegexs) {
                 if (s.matches(regex)) bluetoothTethered = true;
             }
         }
+        boolean bluetoothErrored = false;
         for (String s: errored) {
             for (String regex : mBluetoothRegexs) {
                 if (s.matches(regex)) bluetoothErrored = true;
@@ -458,7 +451,7 @@
         return super.onPreferenceTreeClick(screen, preference);
     }
 
-    private String findIface(String[] ifaces, String[] regexes) {
+    private static String findIface(String[] ifaces, String[] regexes) {
         for (String iface : ifaces) {
             for (String regex : regexes) {
                 if (iface.matches(regex)) {
diff --git a/src/com/android/settings/WirelessSettings.java b/src/com/android/settings/WirelessSettings.java
index b1b7e6e..4b92749 100644
--- a/src/com/android/settings/WirelessSettings.java
+++ b/src/com/android/settings/WirelessSettings.java
@@ -19,6 +19,8 @@
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.telephony.TelephonyProperties;
 import com.android.settings.bluetooth.BluetoothEnabler;
+import com.android.settings.bluetooth.LocalBluetoothAdapter;
+import com.android.settings.bluetooth.LocalBluetoothManager;
 import com.android.settings.wifi.WifiEnabler;
 import com.android.settings.nfc.NfcEnabler;
 
@@ -103,7 +105,8 @@
         mAirplaneModeEnabler = new AirplaneModeEnabler(activity, airplane);
         mAirplaneModePreference = (CheckBoxPreference) findPreference(KEY_TOGGLE_AIRPLANE);
         mWifiEnabler = new WifiEnabler(activity, wifi);
-        mBtEnabler = new BluetoothEnabler(activity, bt);
+        mBtEnabler = new BluetoothEnabler(activity,
+                LocalBluetoothManager.getInstance(activity).getBluetoothAdapter(), bt);
         mNfcEnabler = new NfcEnabler(activity, nfc);
 
         String toggleable = Settings.System.getString(activity.getContentResolver(),
diff --git a/src/com/android/settings/bluetooth/A2dpProfile.java b/src/com/android/settings/bluetooth/A2dpProfile.java
new file mode 100644
index 0000000..96225d8
--- /dev/null
+++ b/src/com/android/settings/bluetooth/A2dpProfile.java
@@ -0,0 +1,166 @@
+/*
+ * 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.bluetooth.BluetoothA2dp;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothClass;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
+import android.bluetooth.BluetoothUuid;
+import android.content.Context;
+import android.os.ParcelUuid;
+
+import com.android.settings.R;
+
+import java.util.List;
+
+/**
+ * A2dpProfile handles Bluetooth A2DP.
+ * TODO: add null checks around calls to mService object.
+ */
+final class A2dpProfile implements LocalBluetoothProfile {
+    private BluetoothA2dp mService;
+
+    static final ParcelUuid[] SINK_UUIDS = {
+        BluetoothUuid.AudioSink,
+        BluetoothUuid.AdvAudioDist,
+    };
+
+    static final String NAME = "A2DP";
+
+    // Order of this profile in device profiles list
+    private static final int ORDINAL = 1;
+
+    // These callbacks run on the main thread.
+    private final class A2dpServiceListener
+            implements BluetoothProfile.ServiceListener {
+
+        public void onServiceConnected(int profile, BluetoothProfile proxy) {
+            mService = (BluetoothA2dp) proxy;
+        }
+
+        public void onServiceDisconnected(int profile) {
+            mService = null;
+        }
+    }
+
+    A2dpProfile(Context context) {
+        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+        adapter.getProfileProxy(context, new A2dpServiceListener(),
+                BluetoothProfile.A2DP);
+    }
+
+    public boolean isConnectable() {
+        return true;
+    }
+
+    public boolean isAutoConnectable() {
+        return true;
+    }
+
+    private List<BluetoothDevice> getConnectedDevices() {
+        return mService.getDevicesMatchingConnectionStates(
+              new int[] {BluetoothProfile.STATE_CONNECTED,
+                         BluetoothProfile.STATE_CONNECTING,
+                         BluetoothProfile.STATE_DISCONNECTING});
+    }
+
+    public boolean connect(BluetoothDevice device) {
+        List<BluetoothDevice> sinks = getConnectedDevices();
+        if (sinks != null) {
+            for (BluetoothDevice sink : sinks) {
+                mService.disconnect(sink);
+            }
+        }
+        return mService.connect(device);
+    }
+
+    public boolean disconnect(BluetoothDevice device) {
+        return mService.disconnect(device);
+    }
+
+    public int getConnectionStatus(BluetoothDevice device) {
+        return mService.getConnectionState(device);
+    }
+
+    public boolean isPreferred(BluetoothDevice device) {
+        return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
+    }
+
+    public int getPreferred(BluetoothDevice device) {
+        return mService.getPriority(device);
+    }
+
+    public void setPreferred(BluetoothDevice device, boolean preferred) {
+        if (preferred) {
+            if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
+                mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
+            }
+        } else {
+            mService.setPriority(device, BluetoothProfile.PRIORITY_OFF);
+        }
+    }
+
+    boolean isA2dpPlaying() {
+        List<BluetoothDevice> sinks = mService.getConnectedDevices();
+        if (!sinks.isEmpty()) {
+            if (mService.isA2dpPlaying(sinks.get(0))) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public boolean isProfileReady() {
+        return mService != null;
+    }
+
+    public String toString() {
+        return NAME;
+    }
+
+    public int getOrdinal() {
+        return ORDINAL;
+    }
+
+    public int getNameResource() {
+        return R.string.bluetooth_profile_a2dp;
+    }
+
+    public int getDisconnectResource() {
+        return R.string.bluetooth_disconnect_a2dp_profile;
+    }
+
+    public int getSummaryResourceForDevice(BluetoothDevice device) {
+        int state = mService.getConnectionState(device);
+        switch (state) {
+            case BluetoothProfile.STATE_DISCONNECTED:
+                return R.string.bluetooth_a2dp_profile_summary_use_for;
+
+            case BluetoothProfile.STATE_CONNECTED:
+                return R.string.bluetooth_a2dp_profile_summary_connected;
+
+            default:
+                return Utils.getConnectionStateSummary(state);
+        }
+    }
+
+    public int getDrawableResource(BluetoothClass btClass) {
+        return R.drawable.ic_bt_headphones_a2dp;
+    }
+}
diff --git a/src/com/android/settings/bluetooth/BluetoothCallback.java b/src/com/android/settings/bluetooth/BluetoothCallback.java
new file mode 100644
index 0000000..3ce9adf
--- /dev/null
+++ b/src/com/android/settings/bluetooth/BluetoothCallback.java
@@ -0,0 +1,29 @@
+/*
+ * 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;
+
+/**
+ * BluetoothCallback provides a callback interface for the settings
+ * UI to receive events from {@link BluetoothEventManager}.
+ */
+interface BluetoothCallback {
+    void onBluetoothStateChanged(int bluetoothState);
+    void onScanningStateChanged(boolean started);
+    void onDeviceAdded(CachedBluetoothDevice cachedDevice);
+    void onDeviceDeleted(CachedBluetoothDevice cachedDevice);
+    void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState);
+}
diff --git a/src/com/android/settings/bluetooth/BluetoothDeviceFilter.java b/src/com/android/settings/bluetooth/BluetoothDeviceFilter.java
new file mode 100644
index 0000000..00e342c
--- /dev/null
+++ b/src/com/android/settings/bluetooth/BluetoothDeviceFilter.java
@@ -0,0 +1,159 @@
+/*
+ * 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.bluetooth.BluetoothClass;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothUuid;
+import android.os.ParcelUuid;
+import android.util.Log;
+
+/**
+ * BluetoothDeviceFilter contains a static method that returns a
+ * Filter object that returns whether or not the BluetoothDevice
+ * passed to it matches the specified filter type constant from
+ * {@link android.bluetooth.BluetoothDevicePicker}.
+ */
+final class BluetoothDeviceFilter {
+    private static final String TAG = "BluetoothDeviceFilter";
+
+    /** The filter interface to external classes. */
+    interface Filter {
+        boolean matches(BluetoothDevice device);
+    }
+
+    /** All filter singleton (referenced directly). */
+    static final Filter ALL_FILTER = new AllFilter();
+
+    /** Bonded devices only filter (referenced directly). */
+    static final Filter BONDED_DEVICE_FILTER = new BondedDeviceFilter();
+
+    /** Table of singleton filter objects. */
+    private static final Filter[] FILTERS = {
+            ALL_FILTER,             // FILTER_TYPE_ALL
+            new AudioFilter(),      // FILTER_TYPE_AUDIO
+            new TransferFilter(),   // FILTER_TYPE_TRANSFER
+            new PanuFilter(),       // FILTER_TYPE_PANU
+            new NapFilter()         // FILTER_TYPE_NAP
+    };
+
+    /** Private constructor. */
+    private BluetoothDeviceFilter() {
+    }
+
+    /**
+     * Returns the singleton {@link Filter} object for the specified type,
+     * or {@link #ALL_FILTER} if the type value is out of range.
+     *
+     * @param filterType a constant from BluetoothDevicePicker
+     * @return a singleton object implementing the {@link Filter} interface.
+     */
+    static Filter getFilter(int filterType) {
+        if (filterType >= 0 && filterType < FILTERS.length) {
+            return FILTERS[filterType];
+        } else {
+            Log.w(TAG, "Invalid filter type " + filterType + " for device picker");
+            return ALL_FILTER;
+        }
+    }
+
+    /** Filter that matches all devices. */
+    private static final class AllFilter implements Filter {
+        public boolean matches(BluetoothDevice device) {
+            return true;
+        }
+    }
+
+    /** Filter that matches only bonded devices. */
+    private static final class BondedDeviceFilter implements Filter {
+        public boolean matches(BluetoothDevice device) {
+            return device.getBondState() == BluetoothDevice.BOND_BONDED;
+        }
+    }
+
+    /** Parent class of filters based on UUID and/or Bluetooth class. */
+    private abstract static class ClassUuidFilter implements Filter {
+        abstract boolean matches(ParcelUuid[] uuids, BluetoothClass btClass);
+
+        public boolean matches(BluetoothDevice device) {
+            return matches(device.getUuids(), device.getBluetoothClass());
+        }
+    }
+
+    /** Filter that matches devices that support AUDIO profiles. */
+    private static final class AudioFilter extends ClassUuidFilter {
+        @Override
+        boolean matches(ParcelUuid[] uuids, BluetoothClass btClass) {
+            if (uuids != null) {
+                if (BluetoothUuid.containsAnyUuid(uuids, A2dpProfile.SINK_UUIDS)) {
+                    return true;
+                }
+                if (BluetoothUuid.containsAnyUuid(uuids, HeadsetProfile.UUIDS)) {
+                    return true;
+                }
+            } else if (btClass != null) {
+                if (btClass.doesClassMatch(BluetoothClass.PROFILE_A2DP) ||
+                        btClass.doesClassMatch(BluetoothClass.PROFILE_HEADSET)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+
+    /** Filter that matches devices that support Object Transfer. */
+    private static final class TransferFilter extends ClassUuidFilter {
+        @Override
+        boolean matches(ParcelUuid[] uuids, BluetoothClass btClass) {
+            if (uuids != null) {
+                if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.ObexObjectPush)) {
+                    return true;
+                }
+            }
+            return btClass != null
+                    && btClass.doesClassMatch(BluetoothClass.PROFILE_OPP);
+        }
+    }
+
+    /** Filter that matches devices that support PAN User (PANU) profile. */
+    private static final class PanuFilter extends ClassUuidFilter {
+        @Override
+        boolean matches(ParcelUuid[] uuids, BluetoothClass btClass) {
+            if (uuids != null) {
+                if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.PANU)) {
+                    return true;
+                }
+            }
+            return btClass != null
+                    && btClass.doesClassMatch(BluetoothClass.PROFILE_PANU);
+        }
+    }
+
+    /** Filter that matches devices that support NAP profile. */
+    private static final class NapFilter extends ClassUuidFilter {
+        @Override
+        boolean matches(ParcelUuid[] uuids, BluetoothClass btClass) {
+            if (uuids != null) {
+                if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.NAP)) {
+                    return true;
+                }
+            }
+            return btClass != null
+                    && btClass.doesClassMatch(BluetoothClass.PROFILE_NAP);
+        }
+    }
+}
diff --git a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
index 6a0b881..5f791d9 100644
--- a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
+++ b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java
@@ -16,27 +16,32 @@
 
 package com.android.settings.bluetooth;
 
-import com.android.settings.R;
-
+import android.app.AlertDialog;
+import android.bluetooth.BluetoothClass;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
 import android.content.Context;
+import android.content.DialogInterface;
 import android.graphics.drawable.Drawable;
 import android.preference.Preference;
+import android.text.TextUtils;
+import android.util.Log;
 import android.util.TypedValue;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.ViewGroup;
 import android.view.View.OnClickListener;
+import android.view.ViewGroup;
 import android.widget.ImageView;
 
-import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
+import com.android.settings.R;
 
-import java.util.Map;
+import java.util.List;
 
 /**
  * BluetoothDevicePreference is the preference type used to display each remote
  * Bluetooth device in the Bluetooth Settings screen.
  */
-public class BluetoothDevicePreference extends Preference implements
+public final class BluetoothDevicePreference extends Preference implements
         CachedBluetoothDevice.Callback, OnClickListener {
     private static final String TAG = "BluetoothDevicePreference";
 
@@ -48,11 +53,7 @@
 
     private OnClickListener mOnSettingsClickListener;
 
-    /**
-     * Cached local copy of whether the device is busy. This is only updated
-     * from {@link #onDeviceAttributesChanged()}.
-     */
-    private boolean mIsBusy;
+    private AlertDialog mDisconnectDialog;
 
     public BluetoothDevicePreference(Context context, CachedBluetoothDevice cachedDevice) {
         super(context);
@@ -60,19 +61,19 @@
         if (sDimAlpha == Integer.MIN_VALUE) {
             TypedValue outValue = new TypedValue();
             context.getTheme().resolveAttribute(android.R.attr.disabledAlpha, outValue, true);
-            sDimAlpha = (int) ((outValue.getFloat() * 255) * 0.5);
+            sDimAlpha = (int) (outValue.getFloat() * 255);
         }
 
         mCachedDevice = cachedDevice;
 
         setWidgetLayoutResource(R.layout.preference_bluetooth);
 
-        cachedDevice.registerCallback(this);
+        mCachedDevice.registerCallback(this);
 
         onDeviceAttributesChanged();
     }
 
-    public CachedBluetoothDevice getCachedDevice() {
+    CachedBluetoothDevice getCachedDevice() {
         return mCachedDevice;
     }
 
@@ -84,42 +85,30 @@
     protected void onPrepareForRemoval() {
         super.onPrepareForRemoval();
         mCachedDevice.unregisterCallback(this);
+        if (mDisconnectDialog != null) {
+            mDisconnectDialog.dismiss();
+            mDisconnectDialog = null;
+        }
     }
 
     public void onDeviceAttributesChanged() {
-
         /*
          * The preference framework takes care of making sure the value has
-         * changed before proceeding.
+         * changed before proceeding. It will also call notifyChanged() if
+         * any preference info has changed from the previous value.
          */
-
         setTitle(mCachedDevice.getName());
 
-        /*
-         * TODO: Showed "Paired" even though it was "Connected". This may be
-         * related to BluetoothHeadset not bound to the actual
-         * BluetoothHeadsetService when we got here.
-         */
-        setSummary(mCachedDevice.getSummary());
+        setSummary(getConnectionSummary());
 
         // Used to gray out the item
-        mIsBusy = mCachedDevice.isBusy();
+        setEnabled(!mCachedDevice.isBusy());
 
-        // Data has changed
-        notifyChanged();
-
-        // This could affect ordering, so notify that also
+        // This could affect ordering, so notify that
         notifyHierarchyChanged();
     }
 
     @Override
-    public boolean isEnabled() {
-        // Temp fix until we have 2053751 fixed in the framework
-        setEnabled(true);
-        return super.isEnabled() && !mIsBusy;
-    }
-
-    @Override
     protected void onBindView(View view) {
         // Disable this view if the bluetooth enable/disable preference view is off
         if (null != findPreferenceInHierarchy("bt_checkbox")) {
@@ -129,17 +118,17 @@
         super.onBindView(view);
 
         ImageView btClass = (ImageView) view.findViewById(android.R.id.icon);
-        btClass.setImageResource(mCachedDevice.getBtClassDrawable());
-        btClass.setAlpha(!mIsBusy ? 255 : sDimAlpha);
+        btClass.setImageResource(getBtClassDrawable());
+        btClass.setAlpha(isEnabled() ? 255 : sDimAlpha);
 
         mDeviceSettings = (ImageView) view.findViewById(R.id.deviceDetails);
         if (mOnSettingsClickListener != null) {
             mDeviceSettings.setOnClickListener(this);
             mDeviceSettings.setTag(mCachedDevice);
-            mDeviceSettings.setAlpha(!mIsBusy ? 255 : sDimAlpha);
+            mDeviceSettings.setAlpha(isEnabled() ? 255 : sDimAlpha);
         } else { // Hide the settings icon and divider
             mDeviceSettings.setVisibility(View.GONE);
-            ImageView divider = (ImageView) view.findViewById(R.id.divider);
+            View divider = view.findViewById(R.id.divider);
             if (divider != null) {
                 divider.setVisibility(View.GONE);
             }
@@ -148,24 +137,40 @@
         LayoutInflater inflater = (LayoutInflater)
                 getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         ViewGroup profilesGroup = (ViewGroup) view.findViewById(R.id.profileIcons);
-        Map<Profile, Drawable> profileIcons = mCachedDevice.getProfileIcons();
-        for (Profile profile : profileIcons.keySet()) {
-            Drawable icon = profileIcons.get(profile);
-            inflater.inflate(R.layout.profile_icon_small, profilesGroup, true);
-            ImageView imageView =
-                    (ImageView) profilesGroup.getChildAt(profilesGroup.getChildCount() - 1);
-            imageView.setImageDrawable(icon);
-            boolean profileEnabled = mCachedDevice.isConnectedProfile(profile);
-            imageView.setAlpha(profileEnabled ? 255 : sDimAlpha);
+        for (LocalBluetoothProfile profile : mCachedDevice.getProfiles()) {
+            int iconResource = profile.getDrawableResource(mCachedDevice.getBtClass());
+            if (iconResource != 0) {
+                Drawable icon = getContext().getResources().getDrawable(iconResource);
+                inflater.inflate(R.layout.profile_icon_small, profilesGroup, true);
+                ImageView imageView =
+                        (ImageView) profilesGroup.getChildAt(profilesGroup.getChildCount() - 1);
+                imageView.setImageDrawable(icon);
+                boolean profileEnabled = mCachedDevice.isConnectedProfile(profile);
+                imageView.setAlpha(profileEnabled ? 255 : sDimAlpha);
+            }
         }
     }
 
     public void onClick(View v) {
         if (v == mDeviceSettings) {
-            if (mOnSettingsClickListener != null) mOnSettingsClickListener.onClick(v);
+            if (mOnSettingsClickListener != null) {
+                mOnSettingsClickListener.onClick(v);
+            }
         }
     }
 
+    public boolean equals(Object o) {
+        if ((o == null) || !(o instanceof BluetoothDevicePreference)) {
+            return false;
+        }
+        return mCachedDevice.equals(
+                ((BluetoothDevicePreference) o).mCachedDevice);
+    }
+
+    public int hashCode() {
+        return mCachedDevice.hashCode();
+    }
+
     @Override
     public int compareTo(Preference another) {
         if (!(another instanceof BluetoothDevicePreference)) {
@@ -173,7 +178,112 @@
             return 1;
         }
 
-        return mCachedDevice.compareTo(((BluetoothDevicePreference) another).mCachedDevice);
+        return mCachedDevice
+                .compareTo(((BluetoothDevicePreference) another).mCachedDevice);
     }
 
+    void onClicked() {
+        int bondState = mCachedDevice.getBondState();
+
+        if (mCachedDevice.isConnected()) {
+            askDisconnect();
+        } else if (bondState == BluetoothDevice.BOND_BONDED) {
+            mCachedDevice.connect(true);
+        } else if (bondState == BluetoothDevice.BOND_NONE) {
+            pair();
+        }
+    }
+
+    // Show disconnect confirmation dialog for a device.
+    private void askDisconnect() {
+        Context context = getContext();
+        String name = mCachedDevice.getName();
+        if (TextUtils.isEmpty(name)) {
+            name = context.getString(R.string.bluetooth_device);
+        }
+        String message = context.getString(R.string.bluetooth_disconnect_blank, name);
+
+        DialogInterface.OnClickListener disconnectListener = new DialogInterface.OnClickListener() {
+            public void onClick(DialogInterface dialog, int which) {
+                mCachedDevice.disconnect();
+            }
+        };
+
+        mDisconnectDialog = Utils.showDisconnectDialog(context,
+                mDisconnectDialog, disconnectListener, name, message);
+    }
+
+    private void pair() {
+        if (!mCachedDevice.startPairing()) {
+            Utils.showError(getContext(), mCachedDevice.getName(),
+                    R.string.bluetooth_pairing_error_message);
+        }
+    }
+
+    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()) {
+            int connectionStatus = profile.getConnectionStatus(device);
+
+            if (connectionStatus != BluetoothProfile.STATE_DISCONNECTED) {
+                return Utils.getConnectionStateSummary(connectionStatus);
+            }
+        }
+
+        switch (cachedDevice.getBondState()) {
+            case BluetoothDevice.BOND_BONDED:
+                return R.string.bluetooth_paired;
+            case BluetoothDevice.BOND_BONDING:
+                return R.string.bluetooth_pairing;
+            case BluetoothDevice.BOND_NONE:
+                return R.string.bluetooth_not_connected;
+            default:
+                return 0;
+        }
+    }
+
+    private int getBtClassDrawable() {
+        BluetoothClass btClass = mCachedDevice.getBtClass();
+        if (btClass != null) {
+            switch (btClass.getMajorDeviceClass()) {
+                case BluetoothClass.Device.Major.COMPUTER:
+                    return R.drawable.ic_bt_laptop;
+
+                case BluetoothClass.Device.Major.PHONE:
+                    return R.drawable.ic_bt_cellphone;
+
+                case BluetoothClass.Device.Major.PERIPHERAL:
+                    return HidProfile.getHidClassDrawable(btClass);
+
+                case BluetoothClass.Device.Major.IMAGING:
+                    return R.drawable.ic_bt_imaging;
+
+                default:
+                    // unrecognized device class; continue
+            }
+        } else {
+            Log.w(TAG, "mBtClass is null");
+        }
+
+        List<LocalBluetoothProfile> profiles = mCachedDevice.getProfiles();
+        for (LocalBluetoothProfile profile : profiles) {
+            int resId = profile.getDrawableResource(btClass);
+            if (resId != 0) {
+                return resId;
+            }
+        }
+        if (btClass != null) {
+            if (btClass.doesClassMatch(BluetoothClass.PROFILE_A2DP)) {
+                return R.drawable.ic_bt_headphones_a2dp;
+
+            }
+            if (btClass.doesClassMatch(BluetoothClass.PROFILE_HEADSET)) {
+                return R.drawable.ic_bt_headset_hfp;
+            }
+        }
+        return 0;
+    }
 }
diff --git a/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java b/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java
index 166e4ae..40bf5bc 100644
--- a/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java
+++ b/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java
@@ -16,41 +16,34 @@
 
 package com.android.settings.bluetooth;
 
-import com.android.settings.R;
-
 import android.bluetooth.BluetoothAdapter;
 import android.content.BroadcastReceiver;
 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.preference.CheckBoxPreference;
-import android.provider.Settings;
-import android.util.Log;
+
+import com.android.settings.R;
 
 /**
  * BluetoothDiscoverableEnabler is a helper to manage the "Discoverable"
  * checkbox. It sets/unsets discoverability and keeps track of how much time
  * until the the discoverability is automatically turned off.
  */
-public class BluetoothDiscoverableEnabler implements Preference.OnPreferenceChangeListener {
-    private static final String TAG = "BluetoothDiscoverableEnabler";
+final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceChangeListener {
 
     private static final String SYSTEM_PROPERTY_DISCOVERABLE_TIMEOUT =
             "debug.bt.discoverable_time";
 
-    static final int DISCOVERABLE_TIMEOUT_TWO_MINUTES = 120;
-    static final int DISCOVERABLE_TIMEOUT_FIVE_MINUTES = 300;
-    static final int DISCOVERABLE_TIMEOUT_ONE_HOUR = 3600;
+    private static final int DISCOVERABLE_TIMEOUT_TWO_MINUTES = 120;
+    private static final int DISCOVERABLE_TIMEOUT_FIVE_MINUTES = 300;
+    private static final int DISCOVERABLE_TIMEOUT_ONE_HOUR = 3600;
     static final int DISCOVERABLE_TIMEOUT_NEVER = 0;
 
-    static final String SHARED_PREFERENCES_KEY_DISCOVERABLE_END_TIMESTAMP =
-        "discoverable_end_timestamp";
-
     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";
@@ -63,7 +56,7 @@
     private final CheckBoxPreference mCheckBoxPreference;
     private final ListPreference mTimeoutListPreference;
 
-    private final LocalBluetoothManager mLocalManager;
+    private final LocalBluetoothAdapter mLocalAdapter;
 
     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
         @Override
@@ -84,7 +77,7 @@
         }
     };
 
-    public BluetoothDiscoverableEnabler(Context context,
+    BluetoothDiscoverableEnabler(Context context, LocalBluetoothAdapter adapter,
             CheckBoxPreference checkBoxPreference, ListPreference timeoutListPreference) {
         mContext = context;
         mUiHandler = new Handler();
@@ -95,15 +88,15 @@
         // we actually want to persist this since can't infer from BT device state
         mTimeoutListPreference.setPersistent(true);
 
-        mLocalManager = LocalBluetoothManager.getInstance(context);
-        if (mLocalManager == null) {
+        mLocalAdapter = adapter;
+        if (adapter == null) {
             // Bluetooth not supported
             checkBoxPreference.setEnabled(false);
         }
     }
 
     public void resume() {
-        if (mLocalManager == null) {
+        if (mLocalAdapter == null) {
             return;
         }
 
@@ -111,11 +104,11 @@
         mContext.registerReceiver(mReceiver, filter);
         mCheckBoxPreference.setOnPreferenceChangeListener(this);
         mTimeoutListPreference.setOnPreferenceChangeListener(this);
-        handleModeChanged(mLocalManager.getBluetoothAdapter().getScanMode());
+        handleModeChanged(mLocalAdapter.getScanMode());
     }
 
     public void pause() {
-        if (mLocalManager == null) {
+        if (mLocalAdapter == null) {
             return;
         }
 
@@ -137,43 +130,37 @@
         return true;
     }
 
-    private void setEnabled(final boolean enable) {
-        BluetoothAdapter manager = mLocalManager.getBluetoothAdapter();
-
+    private void setEnabled(boolean enable) {
         if (enable) {
             int timeout = getDiscoverableTimeout();
-            manager.setDiscoverableTimeout(timeout);
+            mLocalAdapter.setDiscoverableTimeout(timeout);
 
             long endTimestamp = System.currentTimeMillis() + timeout * 1000L;
-            persistDiscoverableEndTimestamp(endTimestamp);
+            LocalBluetoothPreferences.persistDiscoverableEndTimestamp(mContext, endTimestamp);
 
             updateCountdownSummary();
 
-            manager.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, timeout);
+            mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, timeout);
         } else {
-            manager.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE);
+            mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE);
         }
     }
 
     private void updateTimerDisplay(int timeout) {
         if (getDiscoverableTimeout() == DISCOVERABLE_TIMEOUT_NEVER) {
             mCheckBoxPreference.setSummaryOn(
-                mContext.getResources()
-                .getString(R.string.bluetooth_is_discoverable_always));
+                mContext.getString(R.string.bluetooth_is_discoverable_always));
         } else {
             mCheckBoxPreference.setSummaryOn(
-                mContext.getResources()
-                .getString(R.string.bluetooth_is_discoverable, timeout));
+                mContext.getString(R.string.bluetooth_is_discoverable, timeout));
         }
     }
 
     private int getDiscoverableTimeout() {
         int timeout = SystemProperties.getInt(SYSTEM_PROPERTY_DISCOVERABLE_TIMEOUT, -1);
         if (timeout < 0) {
-            String timeoutValue = null;
-            if (mTimeoutListPreference != null && mTimeoutListPreference.getValue() != null) {
-                timeoutValue = mTimeoutListPreference.getValue().toString();
-            } else {
+            String timeoutValue = mTimeoutListPreference.getValue();
+            if (timeoutValue == null) {
                 mTimeoutListPreference.setValue(VALUE_DISCOVERABLE_TIMEOUT_TWO_MINUTES);
                 return DISCOVERABLE_TIMEOUT_TWO_MINUTES;
             }
@@ -192,12 +179,6 @@
         return timeout;
     }
 
-    private void persistDiscoverableEndTimestamp(long endTimestamp) {
-        SharedPreferences.Editor editor = mLocalManager.getSharedPreferences().edit();
-        editor.putLong(SHARED_PREFERENCES_KEY_DISCOVERABLE_END_TIMESTAMP, endTimestamp);
-        editor.apply();
-    }
-
     private void handleModeChanged(int mode) {
         if (mode == BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
             mCheckBoxPreference.setChecked(true);
@@ -208,14 +189,13 @@
     }
 
     private void updateCountdownSummary() {
-        int mode = mLocalManager.getBluetoothAdapter().getScanMode();
+        int mode = mLocalAdapter.getScanMode();
         if (mode != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
             return;
         }
 
         long currentTimestamp = System.currentTimeMillis();
-        long endTimestamp = mLocalManager.getSharedPreferences().getLong(
-                SHARED_PREFERENCES_KEY_DISCOVERABLE_END_TIMESTAMP, 0);
+        long endTimestamp = LocalBluetoothPreferences.getDiscoverableEndTimestamp(mContext);
 
         if (currentTimestamp > endTimestamp) {
             // We're still in discoverable mode, but maybe there isn't a timeout.
@@ -231,6 +211,4 @@
             mUiHandler.postDelayed(mUpdateCountdownSummaryRunnable, 1000);
         }
     }
-
-
 }
diff --git a/src/com/android/settings/bluetooth/BluetoothDiscoveryReceiver.java b/src/com/android/settings/bluetooth/BluetoothDiscoveryReceiver.java
new file mode 100644
index 0000000..fbb6827
--- /dev/null
+++ b/src/com/android/settings/bluetooth/BluetoothDiscoveryReceiver.java
@@ -0,0 +1,47 @@
+/*
+ * 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.bluetooth.BluetoothAdapter;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+/**
+ * BluetoothDiscoveryReceiver updates a timestamp when the
+ * Bluetooth adapter starts or finishes discovery mode. This
+ * is used to decide whether to open an alert dialog or
+ * create a notification when we receive a pairing request.
+ *
+ * <p>Note that the discovery start/finish intents are also handled
+ * by {@link BluetoothEventManager} to update the UI, if visible.
+ */
+public final class BluetoothDiscoveryReceiver extends BroadcastReceiver {
+    private static final String TAG = "BluetoothDiscoveryReceiver";
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        String action = intent.getAction();
+        Log.v(TAG, "Received: " + action);
+
+        if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_STARTED) ||
+                action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {
+            LocalBluetoothPreferences.persistDiscoveringTimestamp(context);
+        }
+    }
+}
diff --git a/src/com/android/settings/bluetooth/BluetoothEnabler.java b/src/com/android/settings/bluetooth/BluetoothEnabler.java
index a7b9d71..9aeb1b9 100644
--- a/src/com/android/settings/bluetooth/BluetoothEnabler.java
+++ b/src/com/android/settings/bluetooth/BluetoothEnabler.java
@@ -34,13 +34,14 @@
  * preference. It turns on/off Bluetooth and ensures the summary of the
  * preference reflects the current state.
  */
-public class BluetoothEnabler implements Preference.OnPreferenceChangeListener {
+public final class BluetoothEnabler implements Preference.OnPreferenceChangeListener {
     private final Context mContext;
     private final CheckBoxPreference mCheckBox;
     private final CharSequence mOriginalSummary;
 
-    private final LocalBluetoothManager mLocalManager;
+    private final LocalBluetoothAdapter mLocalAdapter;
     private final IntentFilter mIntentFilter;
+
     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -49,14 +50,15 @@
         }
     };
 
-    public BluetoothEnabler(Context context, CheckBoxPreference checkBox) {
+    public BluetoothEnabler(Context context, LocalBluetoothAdapter adapter,
+            CheckBoxPreference checkBox) {
         mContext = context;
         mCheckBox = checkBox;
         mOriginalSummary = checkBox.getSummary();
         checkBox.setPersistent(false);
 
-        mLocalManager = LocalBluetoothManager.getInstance(context);
-        if (mLocalManager == null) {
+        mLocalAdapter = adapter;
+        if (adapter == null) {
             // Bluetooth is not supported
             checkBox.setEnabled(false);
         }
@@ -64,19 +66,19 @@
     }
 
     public void resume() {
-        if (mLocalManager == null) {
+        if (mLocalAdapter == null) {
             return;
         }
 
         // Bluetooth state is not sticky, so set it manually
-        handleStateChanged(mLocalManager.getBluetoothState());
+        handleStateChanged(mLocalAdapter.getBluetoothState());
 
         mContext.registerReceiver(mReceiver, mIntentFilter);
         mCheckBox.setOnPreferenceChangeListener(this);
     }
 
     public void pause() {
-        if (mLocalManager == null) {
+        if (mLocalAdapter == null) {
             return;
         }
 
@@ -95,14 +97,14 @@
             return false;
         }
 
-        mLocalManager.setBluetoothEnabled(enable);
+        mLocalAdapter.setBluetoothEnabled(enable);
         mCheckBox.setEnabled(false);
 
         // Don't update UI to opposite state until we're sure
         return false;
     }
 
-    /* package */ void handleStateChanged(int state) {
+    void handleStateChanged(int state) {
         switch (state) {
             case BluetoothAdapter.STATE_TURNING_ON:
                 mCheckBox.setSummary(R.string.wifi_starting);
diff --git a/src/com/android/settings/bluetooth/BluetoothEventManager.java b/src/com/android/settings/bluetooth/BluetoothEventManager.java
new file mode 100644
index 0000000..70e35f9
--- /dev/null
+++ b/src/com/android/settings/bluetooth/BluetoothEventManager.java
@@ -0,0 +1,398 @@
+/*
+ * 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 com.android.settings.R;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothClass;
+import android.bluetooth.BluetoothDevice;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * BluetoothEventManager receives broadcasts and callbacks from the Bluetooth
+ * API and dispatches the event on the UI thread to the right class in the
+ * Settings.
+ */
+final class BluetoothEventManager {
+    private static final String TAG = "BluetoothEventManager";
+
+    private final LocalBluetoothAdapter mLocalAdapter;
+    private final CachedBluetoothDeviceManager mDeviceManager;
+    private LocalBluetoothProfileManager mProfileManager;
+    private final IntentFilter mIntentFilter;
+    private final Map<String, Handler> mHandlerMap;
+
+    private final Collection<BluetoothCallback> mCallbacks =
+            new ArrayList<BluetoothCallback>();
+
+    interface Handler {
+        void onReceive(Context context, Intent intent, BluetoothDevice device);
+    }
+
+    void addHandler(String action, Handler handler) {
+        mHandlerMap.put(action, handler);
+        mIntentFilter.addAction(action);
+    }
+
+    // Set profile manager after construction due to circular dependency
+    void setProfileManager(LocalBluetoothProfileManager manager) {
+        mProfileManager = manager;
+    }
+
+    BluetoothEventManager(LocalBluetoothAdapter adapter,
+            CachedBluetoothDeviceManager deviceManager) {
+        mLocalAdapter = adapter;
+        mDeviceManager = deviceManager;
+        mIntentFilter = new IntentFilter();
+        mHandlerMap = new HashMap<String, Handler>();
+
+        // Bluetooth on/off broadcasts
+        addHandler(BluetoothAdapter.ACTION_STATE_CHANGED, new AdapterStateChangedHandler());
+
+        // Discovery broadcasts
+        addHandler(BluetoothAdapter.ACTION_DISCOVERY_STARTED, new ScanningStateChangedHandler(true));
+        addHandler(BluetoothAdapter.ACTION_DISCOVERY_FINISHED, new ScanningStateChangedHandler(false));
+        addHandler(BluetoothDevice.ACTION_FOUND, new DeviceFoundHandler());
+        addHandler(BluetoothDevice.ACTION_DISAPPEARED, new DeviceDisappearedHandler());
+        addHandler(BluetoothDevice.ACTION_NAME_CHANGED, new NameChangedHandler());
+
+        // Pairing broadcasts
+        addHandler(BluetoothDevice.ACTION_BOND_STATE_CHANGED, new BondStateChangedHandler());
+        addHandler(BluetoothDevice.ACTION_PAIRING_CANCEL, new PairingCancelHandler());
+
+        // Fine-grained state broadcasts
+        addHandler(BluetoothDevice.ACTION_CLASS_CHANGED, new ClassChangedHandler());
+        addHandler(BluetoothDevice.ACTION_UUID, new UuidChangedHandler());
+
+        // Dock event broadcasts
+        addHandler(Intent.ACTION_DOCK_EVENT, new DockEventHandler());
+    }
+
+    /**
+     * A Bluetooth-related activity is now in the foreground. Register to
+     * start receiving Bluetooth events.
+     * @param context a Context object for the current Activity
+     */
+    void resume(Context context) {
+        if (mLocalAdapter.syncBluetoothState()) {
+            // adapter state changed while we were paused: send callbacks
+            int newState = mLocalAdapter.getState();
+            synchronized (mCallbacks) {
+                for (BluetoothCallback callback : mCallbacks) {
+                    callback.onBluetoothStateChanged(newState);
+                }
+            }
+        }
+        context.registerReceiver(mBroadcastReceiver, mIntentFilter);
+    }
+
+    void pause(Context context) {
+        context.unregisterReceiver(mBroadcastReceiver);
+    }
+
+    /** Register to start receiving callbacks for Bluetooth events. */
+    void registerCallback(BluetoothCallback callback) {
+        synchronized (mCallbacks) {
+            mCallbacks.add(callback);
+        }
+    }
+
+    /** Unregister to stop receiving callbacks for Bluetooth events. */
+    void unregisterCallback(BluetoothCallback callback) {
+        synchronized (mCallbacks) {
+            mCallbacks.remove(callback);
+        }
+    }
+
+    // This can't be called from a broadcast receiver where the filter is set in the Manifest.
+    private static String getDockedDeviceAddress(Context context) {
+        // This works only because these broadcast intents are "sticky"
+        Intent i = context.registerReceiver(null, new IntentFilter(Intent.ACTION_DOCK_EVENT));
+        if (i != null) {
+            int state = i.getIntExtra(Intent.EXTRA_DOCK_STATE, Intent.EXTRA_DOCK_STATE_UNDOCKED);
+            if (state != Intent.EXTRA_DOCK_STATE_UNDOCKED) {
+                BluetoothDevice device = i.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+                if (device != null) {
+                    return device.getAddress();
+                }
+            }
+        }
+        return null;
+    }
+
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            Log.v(TAG, "Received " + intent.getAction());
+
+            String action = intent.getAction();
+            BluetoothDevice device = intent
+                    .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+
+            Handler handler = mHandlerMap.get(action);
+            if (handler != null) {
+                handler.onReceive(context, intent, device);
+            }
+        }
+    };
+
+    private class AdapterStateChangedHandler implements Handler {
+        public void onReceive(Context context, Intent intent,
+                BluetoothDevice device) {
+            int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
+                                    BluetoothAdapter.ERROR);
+            // update local profiles and get paired devices
+            mLocalAdapter.setBluetoothStateInt(state);
+            // send callback to update UI and possibly start scanning
+            synchronized (mCallbacks) {
+                for (BluetoothCallback callback : mCallbacks) {
+                    callback.onBluetoothStateChanged(state);
+                }
+            }
+        }
+    }
+
+    private class ScanningStateChangedHandler implements Handler {
+        private final boolean mStarted;
+
+        ScanningStateChangedHandler(boolean started) {
+            mStarted = started;
+        }
+        public void onReceive(Context context, Intent intent,
+                BluetoothDevice device) {
+            synchronized (mCallbacks) {
+                for (BluetoothCallback callback : mCallbacks) {
+                    callback.onScanningStateChanged(mStarted);
+                }
+            }
+            mDeviceManager.onScanningStateChanged(mStarted);
+            LocalBluetoothPreferences.persistDiscoveringTimestamp(context);
+        }
+    }
+
+    private class DeviceFoundHandler implements Handler {
+        public void onReceive(Context context, Intent intent,
+                BluetoothDevice device) {
+            short rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI, Short.MIN_VALUE);
+            BluetoothClass btClass = intent.getParcelableExtra(BluetoothDevice.EXTRA_CLASS);
+            String name = intent.getStringExtra(BluetoothDevice.EXTRA_NAME);
+            // TODO Pick up UUID. They should be available for 2.1 devices.
+            // Skip for now, there's a bluez problem and we are not getting uuids even for 2.1.
+            CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device);
+            if (cachedDevice == null) {
+                cachedDevice = mDeviceManager.addDevice(mLocalAdapter, mProfileManager, device);
+                Log.d(TAG, "DeviceFoundHandler created new CachedBluetoothDevice: "
+                        + cachedDevice);
+                // callback to UI to create Preference for new device
+                dispatchDeviceAdded(cachedDevice);
+            }
+            cachedDevice.setRssi(rssi);
+            cachedDevice.setBtClass(btClass);
+            cachedDevice.setName(name);
+            cachedDevice.setVisible(true);
+        }
+    }
+
+    private void dispatchDeviceAdded(CachedBluetoothDevice cachedDevice) {
+        synchronized (mCallbacks) {
+            for (BluetoothCallback callback : mCallbacks) {
+                callback.onDeviceAdded(cachedDevice);
+            }
+        }
+    }
+
+    private class DeviceDisappearedHandler implements Handler {
+        public void onReceive(Context context, Intent intent,
+                BluetoothDevice device) {
+            CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device);
+            if (cachedDevice == null) {
+                Log.w(TAG, "received ACTION_DISAPPEARED for an unknown device: " + device);
+                return;
+            }
+            if (mDeviceManager.onDeviceDisappeared(cachedDevice)) {
+                synchronized (mCallbacks) {
+                    for (BluetoothCallback callback : mCallbacks) {
+                        callback.onDeviceDeleted(cachedDevice);
+                    }
+                }
+            }
+        }
+    }
+
+    private class NameChangedHandler implements Handler {
+        public void onReceive(Context context, Intent intent,
+                BluetoothDevice device) {
+            mDeviceManager.onDeviceNameUpdated(device);
+        }
+    }
+
+    private class BondStateChangedHandler implements Handler {
+        public void onReceive(Context context, Intent intent,
+                BluetoothDevice device) {
+            if (device == null) {
+                Log.e(TAG, "ACTION_BOND_STATE_CHANGED with no EXTRA_DEVICE");
+                return;
+            }
+            int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
+                                               BluetoothDevice.ERROR);
+            CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device);
+            if (cachedDevice == null) {
+                Log.w(TAG, "CachedBluetoothDevice for device " + device +
+                        " not found, calling readPairedDevices().");
+                if (!readPairedDevices()) {
+                    Log.e(TAG, "Got bonding state changed for " + device +
+                            ", but we have no record of that device.");
+                    return;
+                }
+                cachedDevice = mDeviceManager.findDevice(device);
+                if (cachedDevice == null) {
+                    Log.e(TAG, "Got bonding state changed for " + device +
+                            ", but device not added in cache.");
+                    return;
+                }
+            }
+
+            synchronized (mCallbacks) {
+                for (BluetoothCallback callback : mCallbacks) {
+                    callback.onDeviceBondStateChanged(cachedDevice, bondState);
+                }
+            }
+            cachedDevice.onBondingStateChanged(bondState);
+
+            if (bondState == BluetoothDevice.BOND_NONE) {
+                if (device.isBluetoothDock()) {
+                    // After a dock is unpaired, we will forget the settings
+                    LocalBluetoothPreferences
+                            .removeDockAutoConnectSetting(context, device.getAddress());
+
+                    // if the device is undocked, remove it from the list as well
+                    if (!device.getAddress().equals(getDockedDeviceAddress(context))) {
+                        mDeviceManager.onDeviceDisappeared(cachedDevice);
+                    }
+                }
+                int reason = intent.getIntExtra(BluetoothDevice.EXTRA_REASON,
+                        BluetoothDevice.ERROR);
+
+                showUnbondMessage(context, cachedDevice.getName(), reason);
+            }
+        }
+
+        /**
+         * Called when we have reached the unbonded state.
+         *
+         * @param reason one of the error reasons from
+         *            BluetoothDevice.UNBOND_REASON_*
+         */
+        private void showUnbondMessage(Context context, String name, int reason) {
+            int errorMsg;
+
+            switch(reason) {
+            case BluetoothDevice.UNBOND_REASON_AUTH_FAILED:
+                errorMsg = R.string.bluetooth_pairing_pin_error_message;
+                break;
+            case BluetoothDevice.UNBOND_REASON_AUTH_REJECTED:
+                errorMsg = R.string.bluetooth_pairing_rejected_error_message;
+                break;
+            case BluetoothDevice.UNBOND_REASON_REMOTE_DEVICE_DOWN:
+                errorMsg = R.string.bluetooth_pairing_device_down_error_message;
+                break;
+            case BluetoothDevice.UNBOND_REASON_DISCOVERY_IN_PROGRESS:
+            case BluetoothDevice.UNBOND_REASON_AUTH_TIMEOUT:
+            case BluetoothDevice.UNBOND_REASON_REPEATED_ATTEMPTS:
+            case BluetoothDevice.UNBOND_REASON_REMOTE_AUTH_CANCELED:
+                errorMsg = R.string.bluetooth_pairing_error_message;
+                break;
+            default:
+                Log.w(TAG, "showUnbondMessage: Not displaying any message for reason: " + reason);
+                return;
+            }
+            Utils.showError(context, name, errorMsg);
+        }
+    }
+
+    private class ClassChangedHandler implements Handler {
+        public void onReceive(Context context, Intent intent,
+                BluetoothDevice device) {
+            mDeviceManager.onBtClassChanged(device);
+        }
+    }
+
+    private class UuidChangedHandler implements Handler {
+        public void onReceive(Context context, Intent intent,
+                BluetoothDevice device) {
+            mDeviceManager.onUuidChanged(device);
+        }
+    }
+
+    private class PairingCancelHandler implements Handler {
+        public void onReceive(Context context, Intent intent, BluetoothDevice device) {
+            if (device == null) {
+                Log.e(TAG, "ACTION_PAIRING_CANCEL with no EXTRA_DEVICE");
+                return;
+            }
+            int errorMsg = R.string.bluetooth_pairing_error_message;
+            CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device);
+            Utils.showError(context, cachedDevice.getName(), errorMsg);
+        }
+    }
+
+    private class DockEventHandler implements Handler {
+        public void onReceive(Context context, Intent intent, BluetoothDevice device) {
+            // Remove if unpair device upon undocking
+            int anythingButUnDocked = Intent.EXTRA_DOCK_STATE_UNDOCKED + 1;
+            int state = intent.getIntExtra(Intent.EXTRA_DOCK_STATE, anythingButUnDocked);
+            if (state == Intent.EXTRA_DOCK_STATE_UNDOCKED) {
+                if (device != null && device.getBondState() == BluetoothDevice.BOND_NONE) {
+                    CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device);
+                    if (cachedDevice != null) {
+                        mDeviceManager.onDeviceDisappeared(cachedDevice);
+                    }
+                }
+            }
+        }
+    }
+
+    boolean readPairedDevices() {
+        Set<BluetoothDevice> bondedDevices = mLocalAdapter.getBondedDevices();
+        if (bondedDevices == null) {
+            return false;
+        }
+
+        boolean deviceAdded = false;
+        for (BluetoothDevice device : bondedDevices) {
+            CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device);
+            if (cachedDevice == null) {
+                cachedDevice = mDeviceManager.addDevice(mLocalAdapter, mProfileManager, device);
+                dispatchDeviceAdded(cachedDevice);
+                deviceAdded = true;
+            }
+        }
+
+        return deviceAdded;
+    }
+}
diff --git a/src/com/android/settings/bluetooth/BluetoothEventRedirector.java b/src/com/android/settings/bluetooth/BluetoothEventRedirector.java
deleted file mode 100644
index 3174750..0000000
--- a/src/com/android/settings/bluetooth/BluetoothEventRedirector.java
+++ /dev/null
@@ -1,257 +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 com.android.settings.R;
-import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
-
-import android.bluetooth.BluetoothA2dp;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothClass;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothHeadset;
-import android.bluetooth.BluetoothInputDevice;
-import android.bluetooth.BluetoothPan;
-import android.bluetooth.BluetoothProfile;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.SharedPreferences;
-import android.os.Handler;
-import android.util.Log;
-
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
-/**
- * BluetoothEventRedirector receives broadcasts and callbacks from the Bluetooth
- * API and dispatches the event on the UI thread to the right class in the
- * Settings.
- */
-class BluetoothEventRedirector {
-    private static final String TAG = "BluetoothEventRedirector";
-
-    /* package */ final LocalBluetoothManager mManager;
-
-    private final ThreadPoolExecutor mSerialExecutor = new ThreadPoolExecutor(
-        0, 1, 1000L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
-
-    private final Handler mHandler = new Handler();
-
-    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            Log.v(TAG, "Received " + intent.getAction());
-
-            String action = intent.getAction();
-            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
-
-            if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
-                int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
-                                        BluetoothAdapter.ERROR);
-                mManager.setBluetoothStateInt(state);
-            } else if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_STARTED)) {
-                PendingResult pr = goAsync();  // so loading shared prefs doesn't kill animation
-                persistDiscoveringTimestamp(pr, true);
-            } else if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {
-                PendingResult pr = goAsync();  // so loading shared prefs doesn't kill animation
-                persistDiscoveringTimestamp(pr, false);
-            } else if (action.equals(BluetoothDevice.ACTION_FOUND)) {
-                short rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI, Short.MIN_VALUE);
-                BluetoothClass btClass = intent.getParcelableExtra(BluetoothDevice.EXTRA_CLASS);
-                String name = intent.getStringExtra(BluetoothDevice.EXTRA_NAME);
-                // TODO Pick up UUID. They should be available for 2.1 devices.
-                // Skip for now, there's a bluez problem and we are not getting uuids even for 2.1.
-                mManager.getCachedDeviceManager().onDeviceAppeared(device, rssi, btClass, name);
-
-            } else if (action.equals(BluetoothDevice.ACTION_DISAPPEARED)) {
-                mManager.getCachedDeviceManager().onDeviceDisappeared(device);
-
-            } else if (action.equals(BluetoothDevice.ACTION_NAME_CHANGED)) {
-                mManager.getCachedDeviceManager().onDeviceNameUpdated(device);
-
-            } else if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
-                int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
-                                                   BluetoothDevice.ERROR);
-                CachedBluetoothDeviceManager cachedDeviceMgr = mManager.getCachedDeviceManager();
-                cachedDeviceMgr.onBondingStateChanged(device, bondState);
-                if (bondState == BluetoothDevice.BOND_NONE) {
-                    if (device.isBluetoothDock()) {
-                        // After a dock is unpaired, we will forget the
-                        // settings
-                        mManager.removeDockAutoConnectSetting(device.getAddress());
-
-                        // if the device is undocked, remove it from the list as
-                        // well
-                        if (!device.getAddress().equals(getDockedDeviceAddress(context))) {
-                            cachedDeviceMgr.onDeviceDisappeared(device);
-                        }
-                    }
-                    int reason = intent.getIntExtra(BluetoothDevice.EXTRA_REASON,
-                            BluetoothDevice.ERROR);
-                    cachedDeviceMgr.showUnbondMessage(device, reason);
-                }
-
-            } else if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
-                int newState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, 0);
-                int oldState = intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, 0);
-                if (newState == BluetoothProfile.STATE_DISCONNECTED &&
-                        oldState == BluetoothProfile.STATE_CONNECTING) {
-                    Log.i(TAG, "Failed to connect BT headset");
-                }
-
-                mManager.getCachedDeviceManager().onProfileStateChanged(device,
-                    Profile.HEADSET, newState);
-            } else if (action.equals(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED)) {
-                int newState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, 0);
-                int oldState = intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, 0);
-                if (newState == BluetoothProfile.STATE_DISCONNECTED &&
-                        oldState == BluetoothProfile.STATE_CONNECTING) {
-                    Log.i(TAG, "Failed to connect BT A2DP");
-                }
-
-                mManager.getCachedDeviceManager().onProfileStateChanged(device,
-                        Profile.A2DP, newState);
-            } else if (action.equals(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED)) {
-                final int newState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, 0);
-                final int oldState = intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, 0);
-                if (newState == BluetoothProfile.STATE_DISCONNECTED &&
-                        oldState == BluetoothProfile.STATE_CONNECTING) {
-                    Log.i(TAG, "Failed to connect BT HID");
-                }
-
-                mManager.getCachedDeviceManager().onProfileStateChanged(device,
-                        Profile.HID, newState);
-
-            } else if (action.equals(BluetoothPan.ACTION_CONNECTION_STATE_CHANGED)) {
-                final int role = intent.getIntExtra(
-                        BluetoothPan.EXTRA_LOCAL_ROLE, 0);
-                if (role == BluetoothPan.LOCAL_PANU_ROLE) {
-                    final int newState = intent.getIntExtra(
-                            BluetoothPan.EXTRA_STATE, 0);
-                    final int oldState = intent.getIntExtra(
-                            BluetoothPan.EXTRA_PREVIOUS_STATE, 0);
-                    if (newState == BluetoothPan.STATE_DISCONNECTED &&
-                            oldState == BluetoothPan.STATE_CONNECTING) {
-                        Log.i(TAG, "Failed to connect BT PAN");
-                    }
-                    mManager.getCachedDeviceManager().onProfileStateChanged(device,
-                            Profile.PAN, newState);
-                }
-            } else if (action.equals(BluetoothDevice.ACTION_CLASS_CHANGED)) {
-                mManager.getCachedDeviceManager().onBtClassChanged(device);
-
-            } else if (action.equals(BluetoothDevice.ACTION_UUID)) {
-                mManager.getCachedDeviceManager().onUuidChanged(device);
-
-            } else if (action.equals(BluetoothDevice.ACTION_PAIRING_CANCEL)) {
-                int errorMsg = R.string.bluetooth_pairing_error_message;
-                mManager.showError(device, errorMsg);
-
-            } else if (action.equals(Intent.ACTION_DOCK_EVENT)) {
-                // Remove if unpair device upon undocking
-                int anythingButUnDocked = Intent.EXTRA_DOCK_STATE_UNDOCKED + 1;
-                int state = intent.getIntExtra(Intent.EXTRA_DOCK_STATE, anythingButUnDocked);
-                if (state == Intent.EXTRA_DOCK_STATE_UNDOCKED) {
-                    if (device != null && device.getBondState() == BluetoothDevice.BOND_NONE) {
-                        mManager.getCachedDeviceManager().onDeviceDisappeared(device);
-                    }
-                }
-            }
-        }
-    };
-
-    public BluetoothEventRedirector(LocalBluetoothManager localBluetoothManager) {
-        mManager = localBluetoothManager;
-    }
-
-    public void registerReceiver() {
-        IntentFilter filter = new IntentFilter();
-
-        // Bluetooth on/off broadcasts
-        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
-
-        // Discovery broadcasts
-        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
-        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
-        filter.addAction(BluetoothDevice.ACTION_DISAPPEARED);
-        filter.addAction(BluetoothDevice.ACTION_FOUND);
-        filter.addAction(BluetoothDevice.ACTION_NAME_CHANGED);
-
-        // Pairing broadcasts
-        filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
-        filter.addAction(BluetoothDevice.ACTION_PAIRING_CANCEL);
-
-        // Fine-grained state broadcasts
-        filter.addAction(BluetoothPan.ACTION_CONNECTION_STATE_CHANGED);
-        filter.addAction(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED);
-        filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
-        filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
-        filter.addAction(BluetoothDevice.ACTION_CLASS_CHANGED);
-        filter.addAction(BluetoothDevice.ACTION_UUID);
-
-        // Dock event broadcasts
-        filter.addAction(Intent.ACTION_DOCK_EVENT);
-
-        mManager.getContext().registerReceiver(mBroadcastReceiver, filter);
-    }
-
-    public void stop() {
-        mManager.getContext().unregisterReceiver(mBroadcastReceiver);
-    }
-
-    // This can't be called from a broadcast receiver where the filter is set in the Manifest.
-    /* package */ String getDockedDeviceAddress(Context context) {
-        // This works only because these broadcast intents are "sticky"
-        Intent i = context.registerReceiver(null, new IntentFilter(Intent.ACTION_DOCK_EVENT));
-        if (i != null) {
-            int state = i.getIntExtra(Intent.EXTRA_DOCK_STATE, Intent.EXTRA_DOCK_STATE_UNDOCKED);
-            if (state != Intent.EXTRA_DOCK_STATE_UNDOCKED) {
-                BluetoothDevice device = i.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
-                if (device != null) {
-                    return device.getAddress();
-                }
-            }
-        }
-        return null;
-    }
-
-    /* package */ void persistDiscoveringTimestamp(
-        final BroadcastReceiver.PendingResult pr, final boolean newState) {
-        // Load the shared preferences and edit it on a background
-        // thread (but serialized!), but then post back to the main
-        // thread to run the onScanningStateChanged callbacks which
-        // update the UI...
-        mSerialExecutor.submit(new Runnable() {
-                public void run() {
-                    SharedPreferences.Editor editor = mManager.getSharedPreferences().edit();
-                    editor.putLong(
-                        LocalBluetoothManager.SHARED_PREFERENCES_KEY_DISCOVERING_TIMESTAMP,
-                        System.currentTimeMillis());
-                    editor.apply();
-                    mHandler.post(new Runnable() {
-                            public void run() {
-                                mManager.onScanningStateChanged(newState);
-                                pr.finish();
-                            }
-                        });
-                }
-            });
-    }
-}
diff --git a/src/com/android/settings/bluetooth/BluetoothFindNearby.java b/src/com/android/settings/bluetooth/BluetoothFindNearby.java
index f1b876e..066f4f6 100644
--- a/src/com/android/settings/bluetooth/BluetoothFindNearby.java
+++ b/src/com/android/settings/bluetooth/BluetoothFindNearby.java
@@ -16,21 +16,18 @@
 
 package com.android.settings.bluetooth;
 
-import android.app.Activity;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
-import android.util.Log;
 
 import com.android.settings.R;
 
 /**
  * Fragment to scan and show the discoverable devices.
  */
-public class BluetoothFindNearby extends DeviceListPreferenceFragment {
+public final class BluetoothFindNearby extends DeviceListPreferenceFragment {
 
-    private static final String TAG = "BluetoothFindNearby";
-
-    void addPreferencesForActivity(Activity activity) {
+    @Override
+    void addPreferencesForActivity() {
         addPreferencesFromResource(R.xml.device_picker);
     }
 
@@ -38,35 +35,37 @@
     public void onResume() {
         super.onResume();
         if (mSelectedDevice != null) {
-            CachedBluetoothDevice device =
-                    mLocalManager.getCachedDeviceManager().findDevice(mSelectedDevice);
-            if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
+            CachedBluetoothDeviceManager manager = mLocalManager.getCachedDeviceManager();
+            CachedBluetoothDevice device = manager.findDevice(mSelectedDevice);
+            if (device != null && device.getBondState() == BluetoothDevice.BOND_BONDED) {
                 // selected device was paired, so return from this screen
                 finish();
                 return;
             }
         }
-        mLocalManager.startScanning(true);
+        mLocalAdapter.startScanning(true);
     }
 
+    @Override
     void onDevicePreferenceClick(BluetoothDevicePreference btPreference) {
-        mLocalManager.stopScanning();
+        mLocalAdapter.stopScanning();
         super.onDevicePreferenceClick(btPreference);
     }
 
-    public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice,
-            int bondState) {
+    public void onDeviceBondStateChanged(CachedBluetoothDevice
+            cachedDevice, int bondState) {
         if (bondState == BluetoothDevice.BOND_BONDED) {
             // return from scan screen after successful auto-pairing
             finish();
         }
     }
 
-    void onBluetoothStateChanged(int bluetoothState) {
+    @Override
+    public void onBluetoothStateChanged(int bluetoothState) {
         super.onBluetoothStateChanged(bluetoothState);
 
         if (bluetoothState == BluetoothAdapter.STATE_ON) {
-                mLocalManager.startScanning(false);
+                mLocalAdapter.startScanning(false);
         }
     }
 }
diff --git a/src/com/android/settings/bluetooth/BluetoothNamePreference.java b/src/com/android/settings/bluetooth/BluetoothNamePreference.java
index c99ab4c..f41689e 100644
--- a/src/com/android/settings/bluetooth/BluetoothNamePreference.java
+++ b/src/com/android/settings/bluetooth/BluetoothNamePreference.java
@@ -22,12 +22,12 @@
 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.Spanned;
 import android.text.TextWatcher;
 import android.util.AttributeSet;
 import android.widget.Button;
@@ -38,13 +38,13 @@
  * Bluetooth name. It asks the user for a name, and persists it via the
  * Bluetooth API.
  */
-public class BluetoothNamePreference extends EditTextPreference implements TextWatcher {
-    private static final String TAG = "BluetoothNamePreference";
+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 LocalBluetoothManager mLocalManager;
+    private final LocalBluetoothAdapter mLocalAdapter;
 
-    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
@@ -61,7 +61,7 @@
     public BluetoothNamePreference(Context context, AttributeSet attrs) {
         super(context, attrs);
 
-        mLocalManager = LocalBluetoothManager.getInstance(context);
+        mLocalAdapter = LocalBluetoothManager.getInstance(context).getBluetoothAdapter();
 
         setSummaryToName();
     }
@@ -97,16 +97,17 @@
     }
 
     private void setSummaryToName() {
-        BluetoothAdapter adapter = mLocalManager.getBluetoothAdapter();
-        if (adapter.isEnabled()) {
-            setSummary(adapter.getName());
+        if (mLocalAdapter != null && mLocalAdapter.isEnabled()) {
+            setSummary(mLocalAdapter.getName());
         }
     }
 
     @Override
     protected boolean persistString(String value) {
-        BluetoothAdapter adapter = mLocalManager.getBluetoothAdapter();
-        adapter.setName(value);
+        // Persist with Bluez instead of shared preferences
+        if (mLocalAdapter != null) {
+            mLocalAdapter.setName(value);
+        }
         return true;
     }
 
@@ -116,8 +117,8 @@
 
         // The dialog should be created by now
         EditText et = getEditText();
-        if (et != null) {
-            et.setText(mLocalManager.getBluetoothAdapter().getName());
+        if (et != null && mLocalAdapter != null) {
+            et.setText(mLocalAdapter.getName());
         }
     }
 
@@ -125,7 +126,7 @@
     public void afterTextChanged(Editable s) {
         Dialog d = getDialog();
         if (d instanceof AlertDialog) {
-            ((AlertDialog) d).getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(s.length() > 0);
+            ((AlertDialog) d).getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(s.length() > 0);
         }
     }
 
@@ -139,67 +140,4 @@
         // not used
     }
 
-    /**
-     * This filter will constrain edits so that the text length is not
-     * greater than the specified number of bytes using UTF-8 encoding.
-     * <p>The JNI method used by {@link android.server.BluetoothService}
-     * to convert UTF-16 to UTF-8 doesn't support surrogate pairs,
-     * therefore code points outside of the basic multilingual plane
-     * (0000-FFFF) will be encoded as a pair of 3-byte UTF-8 characters,
-     * rather than a single 4-byte UTF-8 encoding. Dalvik implements this
-     * conversion in {@code convertUtf16ToUtf8()} in
-     * {@code dalvik/vm/UtfString.c}.
-     * <p>This JNI method is unlikely to change in the future due to
-     * backwards compatibility requirements. It's also unclear whether
-     * the installed base of Bluetooth devices would correctly handle the
-     * encoding of surrogate pairs in UTF-8 as 4 bytes rather than 6.
-     * However, this filter will still work in scenarios where surrogate
-     * pairs are encoded as 4 bytes, with the caveat that the maximum
-     * length will be constrained more conservatively than necessary.
-     */
-    public static class Utf8ByteLengthFilter implements InputFilter {
-        private int mMaxBytes;
-
-        public Utf8ByteLengthFilter(int maxBytes) {
-            mMaxBytes = maxBytes;
-        }
-
-        public CharSequence filter(CharSequence source, int start, int end,
-                                   Spanned dest, int dstart, int dend) {
-            int srcByteCount = 0;
-            // count UTF-8 bytes in source substring
-            for (int i = start; i < end; i++) {
-                char c = source.charAt(i);
-                srcByteCount += (c < 0x0080) ? 1 : (c < 0x0800 ? 2 : 3);
-            }
-            int destLen = dest.length();
-            int destByteCount = 0;
-            // count UTF-8 bytes in destination excluding replaced section
-            for (int i = 0; i < destLen; i++) {
-                if (i < dstart || i >= dend) {
-                    char c = dest.charAt(i);
-                    destByteCount += (c < 0x0080) ? 1 : (c < 0x0800 ? 2 : 3);
-                }
-            }
-            int keepBytes = mMaxBytes - destByteCount;
-            if (keepBytes <= 0) {
-                return "";
-            } else if (keepBytes >= srcByteCount) {
-                return null; // use original dest string
-            } else {
-                // find end position of largest sequence that fits in keepBytes
-                for (int i = start; i < end; i++) {
-                    char c = source.charAt(i);
-                    keepBytes -= (c < 0x0080) ? 1 : (c < 0x0800 ? 2 : 3);
-                    if (keepBytes < 0) {
-                        return source.subSequence(start, i);
-                    }
-                }
-                // If the entire substring fits, we should have returned null
-                // above, so this line should not be reached. If for some
-                // reason it is, return null to use the original dest string.
-                return null;
-            }
-        }
-    }
 }
diff --git a/src/com/android/settings/bluetooth/BluetoothPairingDialog.java b/src/com/android/settings/bluetooth/BluetoothPairingDialog.java
index 1822e73..1b443c4 100644
--- a/src/com/android/settings/bluetooth/BluetoothPairingDialog.java
+++ b/src/com/android/settings/bluetooth/BluetoothPairingDialog.java
@@ -42,33 +42,37 @@
  * 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 class BluetoothPairingDialog extends AlertActivity implements DialogInterface.OnClickListener,
+public final class BluetoothPairingDialog extends AlertActivity implements DialogInterface.OnClickListener,
         TextWatcher {
     private static final String TAG = "BluetoothPairingDialog";
 
     private static final int BLUETOOTH_PIN_MAX_LENGTH = 16;
     private static final int BLUETOOTH_PASSKEY_MAX_LENGTH = 6;
-    private LocalBluetoothManager mLocalManager;
     private BluetoothDevice mDevice;
     private int mType;
     private String mPairingKey;
     private EditText mPairingView;
     private Button mOkButton;
 
-    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
+    /**
+     * Dismiss the dialog if the bond state changes to bonded or none,
+     * or if pairing was canceled for {@link #mDevice}.
+     */
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(intent.getAction())) {
+            String action = intent.getAction();
+            if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
                 int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
                                                    BluetoothDevice.ERROR);
                 if (bondState == BluetoothDevice.BOND_BONDED ||
                         bondState == BluetoothDevice.BOND_NONE) {
-                    dismissDialog();
+                    dismiss();
                 }
-            } else if(BluetoothDevice.ACTION_PAIRING_CANCEL.equals(intent.getAction())) {
+            } else if (BluetoothDevice.ACTION_PAIRING_CANCEL.equals(action)) {
                 BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                 if (device == null || device.equals(mDevice)) {
-                    dismissDialog();
+                    dismiss();
                 }
             }
         }
@@ -81,48 +85,63 @@
         Intent intent = getIntent();
         if (!intent.getAction().equals(BluetoothDevice.ACTION_PAIRING_REQUEST))
         {
-            Log.e(TAG,
-                  "Error: this activity may be started only with intent " +
+            Log.e(TAG, "Error: this activity may be started only with intent " +
                   BluetoothDevice.ACTION_PAIRING_REQUEST);
             finish();
+            return;
         }
 
-        mLocalManager = LocalBluetoothManager.getInstance(this);
+        LocalBluetoothManager manager = LocalBluetoothManager.getInstance(this);
+        if (manager == null) {
+            Log.e(TAG, "Error: BluetoothAdapter not supported by system");
+            finish();
+            return;
+        }
+        CachedBluetoothDeviceManager deviceManager = manager.getCachedDeviceManager();
+
         mDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
         mType = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, BluetoothDevice.ERROR);
-        if (mType == BluetoothDevice.PAIRING_VARIANT_PIN) {
-            createUserEntryDialog();
-        } else if (mType == BluetoothDevice.PAIRING_VARIANT_PASSKEY) {
-            createUserEntryDialog();
-        } else if (mType == BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION){
-            int passkey =
-                intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_KEY, BluetoothDevice.ERROR);
-            if (passkey == BluetoothDevice.ERROR) {
-                Log.e(TAG, "Invalid ConfirmationPasskey received, not showing any dialog");
-                return;
-            }
-            mPairingKey = String.format("%06d", passkey);
-            createConfirmationDialog();
-        } else if (mType == BluetoothDevice.PAIRING_VARIANT_CONSENT) {
-            createConsentDialog();
-        } else if (mType == BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY ||
-                   mType == BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN) {
-            int pairingKey =
-                intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_KEY, BluetoothDevice.ERROR);
-            if (pairingKey == BluetoothDevice.ERROR) {
-                Log.e(TAG, "Invalid Confirmation Passkey or PIN received, not showing any dialog");
-                return;
-            }
-            if (mType == BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY) {
-                mPairingKey = String.format("%06d", pairingKey);
-            } else {
-                mPairingKey = String.format("%04d", pairingKey);
-            }
-            createDisplayPasskeyOrPinDialog();
-        } else if (mType == BluetoothDevice.PAIRING_VARIANT_OOB_CONSENT) {
-            createConsentDialog();
-        } else {
-            Log.e(TAG, "Incorrect pairing type received, not showing any dialog");
+
+        switch (mType) {
+            case BluetoothDevice.PAIRING_VARIANT_PIN:
+            case BluetoothDevice.PAIRING_VARIANT_PASSKEY:
+                createUserEntryDialog(deviceManager);
+                break;
+
+            case BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION:
+                int passkey =
+                    intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_KEY, BluetoothDevice.ERROR);
+                if (passkey == BluetoothDevice.ERROR) {
+                    Log.e(TAG, "Invalid Confirmation Passkey received, not showing any dialog");
+                    return;
+                }
+                mPairingKey = String.format("%06d", passkey);
+                createConfirmationDialog(deviceManager);
+                break;
+
+            case BluetoothDevice.PAIRING_VARIANT_CONSENT:
+            case BluetoothDevice.PAIRING_VARIANT_OOB_CONSENT:
+                createConsentDialog(deviceManager);
+                break;
+
+            case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY:
+            case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN:
+                int pairingKey =
+                    intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_KEY, BluetoothDevice.ERROR);
+                if (pairingKey == BluetoothDevice.ERROR) {
+                    Log.e(TAG, "Invalid Confirmation Passkey or PIN received, not showing any dialog");
+                    return;
+                }
+                if (mType == BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY) {
+                    mPairingKey = String.format("%06d", pairingKey);
+                } else {
+                    mPairingKey = String.format("%04d", pairingKey);
+                }
+                createDisplayPasskeyOrPinDialog(deviceManager);
+                break;
+
+            default:
+                Log.e(TAG, "Incorrect pairing type received, not showing any dialog");
         }
 
         /*
@@ -133,67 +152,79 @@
         registerReceiver(mReceiver, new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED));
     }
 
-    private void createUserEntryDialog() {
+    private void createUserEntryDialog(CachedBluetoothDeviceManager deviceManager) {
         final AlertController.AlertParams p = mAlertParams;
         p.mIconId = android.R.drawable.ic_dialog_info;
         p.mTitle = getString(R.string.bluetooth_pairing_request);
-        p.mView = createView();
+        p.mView = createView(deviceManager);
         p.mPositiveButtonText = getString(android.R.string.ok);
         p.mPositiveButtonListener = this;
         p.mNegativeButtonText = getString(android.R.string.cancel);
         p.mNegativeButtonListener = this;
         setupAlert();
 
-        mOkButton = mAlert.getButton(DialogInterface.BUTTON_POSITIVE);
+        mOkButton = mAlert.getButton(BUTTON_POSITIVE);
         mOkButton.setEnabled(false);
     }
 
-    private View createView() {
+    private View createView(CachedBluetoothDeviceManager deviceManager) {
         View view = getLayoutInflater().inflate(R.layout.bluetooth_pin_entry, null);
-
-        String name = mLocalManager.getCachedDeviceManager().getName(mDevice);
+        String name = deviceManager.getName(mDevice);
         TextView messageView = (TextView) view.findViewById(R.id.message);
         mPairingView = (EditText) view.findViewById(R.id.text);
         mPairingView.addTextChangedListener(this);
 
-        if (mType == 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) });
-        } else if (mType == BluetoothDevice.PAIRING_VARIANT_PASSKEY){
-            messageView.setText(getString(R.string.bluetooth_enter_passkey_msg, name));
-            // 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)});
-        } else if (mType == BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION) {
-            mPairingView.setVisibility(View.GONE);
-            messageView.setText(getString(R.string.bluetooth_confirm_passkey_msg, name,
-                    mPairingKey));
-        } else if (mType == BluetoothDevice.PAIRING_VARIANT_CONSENT) {
-            mPairingView.setVisibility(View.GONE);
-            messageView.setText(getString(R.string.bluetooth_incoming_pairing_msg, name));
-        } else if (mType == BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY ||
-                    mType == BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN) {
-            mPairingView.setVisibility(View.GONE);
-            messageView.setText(getString(R.string.bluetooth_display_passkey_pin_msg, name,
-                    mPairingKey));
-        } else if (mType == BluetoothDevice.PAIRING_VARIANT_OOB_CONSENT) {
-            mPairingView.setVisibility(View.GONE);
-            messageView.setText(getString(R.string.bluetooth_incoming_pairing_msg, name));
-        } else {
-            Log.e(TAG, "Incorrect pairing type received, not creating view");
+        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) });
+                break;
+
+            case BluetoothDevice.PAIRING_VARIANT_PASSKEY:
+                messageView.setText(getString(R.string.bluetooth_enter_passkey_msg, name));
+                // 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)});
+                break;
+
+            case BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION:
+                mPairingView.setVisibility(View.GONE);
+                messageView.setText(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));
+                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));
+                break;
+
+            default:
+                Log.e(TAG, "Incorrect pairing type received, not creating view");
         }
         return view;
     }
 
-    private void createConfirmationDialog() {
+    private void createConfirmationDialog(CachedBluetoothDeviceManager deviceManager) {
         final AlertController.AlertParams p = mAlertParams;
         p.mIconId = android.R.drawable.ic_dialog_info;
         p.mTitle = getString(R.string.bluetooth_pairing_request);
-        p.mView = createView();
+        p.mView = createView(deviceManager);
         p.mPositiveButtonText = getString(R.string.bluetooth_pairing_accept);
         p.mPositiveButtonListener = this;
         p.mNegativeButtonText = getString(R.string.bluetooth_pairing_decline);
@@ -201,11 +232,11 @@
         setupAlert();
     }
 
-    private void createConsentDialog() {
+    private void createConsentDialog(CachedBluetoothDeviceManager deviceManager) {
         final AlertController.AlertParams p = mAlertParams;
         p.mIconId = android.R.drawable.ic_dialog_info;
         p.mTitle = getString(R.string.bluetooth_pairing_request);
-        p.mView = createView();
+        p.mView = createView(deviceManager);
         p.mPositiveButtonText = getString(R.string.bluetooth_pairing_accept);
         p.mPositiveButtonListener = this;
         p.mNegativeButtonText = getString(R.string.bluetooth_pairing_decline);
@@ -213,11 +244,12 @@
         setupAlert();
     }
 
-    private void createDisplayPasskeyOrPinDialog() {
+    private void createDisplayPasskeyOrPinDialog(
+            CachedBluetoothDeviceManager deviceManager) {
         final AlertController.AlertParams p = mAlertParams;
         p.mIconId = android.R.drawable.ic_dialog_info;
         p.mTitle = getString(R.string.bluetooth_pairing_request);
-        p.mView = createView();
+        p.mView = createView(deviceManager);
         p.mNegativeButtonText = getString(android.R.string.cancel);
         p.mNegativeButtonListener = this;
         setupAlert();
@@ -244,32 +276,37 @@
         }
     }
 
-    private void dismissDialog() {
-        this.dismiss();
-    }
-
     private void onPair(String value) {
-        if (mType == BluetoothDevice.PAIRING_VARIANT_PIN) {
-            byte[] pinBytes = BluetoothDevice.convertPinToBytes(value);
-            if (pinBytes == null) {
-                return;
-            }
-            mDevice.setPin(pinBytes);
-        } else if (mType == BluetoothDevice.PAIRING_VARIANT_PASSKEY) {
-            int passkey = Integer.parseInt(value);
-            mDevice.setPasskey(passkey);
-        } else if (mType == BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION) {
-            mDevice.setPairingConfirmation(true);
-        } else if (mType ==  BluetoothDevice.PAIRING_VARIANT_CONSENT) {
-            mDevice.setPairingConfirmation(true);
-        } else if (mType == BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY) {
-            // Do Nothing.
-        } else if (mType == BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN) {
-            // Do Nothing
-        } else if (mType == BluetoothDevice.PAIRING_VARIANT_OOB_CONSENT) {
-            mDevice.setRemoteOutOfBandData();
-        } else {
-            Log.e(TAG, "Incorrect pairing type received");
+        switch (mType) {
+            case BluetoothDevice.PAIRING_VARIANT_PIN:
+                byte[] pinBytes = BluetoothDevice.convertPinToBytes(value);
+                if (pinBytes == null) {
+                    return;
+                }
+                mDevice.setPin(pinBytes);
+                break;
+
+            case BluetoothDevice.PAIRING_VARIANT_PASSKEY:
+                int passkey = Integer.parseInt(value);
+                mDevice.setPasskey(passkey);
+                break;
+
+            case BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION:
+            case BluetoothDevice.PAIRING_VARIANT_CONSENT:
+                mDevice.setPairingConfirmation(true);
+                break;
+
+            case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY:
+            case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN:
+                // Do nothing.
+                break;
+
+            case BluetoothDevice.PAIRING_VARIANT_OOB_CONSENT:
+                mDevice.setRemoteOutOfBandData();
+                break;
+
+            default:
+                Log.e(TAG, "Incorrect pairing type received");
         }
     }
 
@@ -279,11 +316,12 @@
 
     public void onClick(DialogInterface dialog, int which) {
         switch (which) {
-            case DialogInterface.BUTTON_POSITIVE:
+            case BUTTON_POSITIVE:
                 onPair(mPairingView.getText().toString());
                 break;
 
-            case DialogInterface.BUTTON_NEGATIVE:
+            case BUTTON_NEGATIVE:
+            default:
                 onCancel();
                 break;
         }
diff --git a/src/com/android/settings/bluetooth/BluetoothPairingRequest.java b/src/com/android/settings/bluetooth/BluetoothPairingRequest.java
index 6037c82..de96d71 100644
--- a/src/com/android/settings/bluetooth/BluetoothPairingRequest.java
+++ b/src/com/android/settings/bluetooth/BluetoothPairingRequest.java
@@ -35,17 +35,15 @@
  * confirmation entry dialog. Otherwise it puts a Notification in the status bar, which can
  * be clicked to bring up the Pairing entry dialog.
  */
-public class BluetoothPairingRequest extends BroadcastReceiver {
+public final class BluetoothPairingRequest extends BroadcastReceiver {
 
-    public static final int NOTIFICATION_ID = android.R.drawable.stat_sys_data_bluetooth;
+    private static final int NOTIFICATION_ID = android.R.drawable.stat_sys_data_bluetooth;
 
     @Override
     public void onReceive(Context context, Intent intent) {
         String action = intent.getAction();
         if (action.equals(BluetoothDevice.ACTION_PAIRING_REQUEST)) {
-
-            LocalBluetoothManager localManager = LocalBluetoothManager.getInstance(context);
-
+            // convert broadcast intent into activity intent (same action string)
             BluetoothDevice device =
                     intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
             int type = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
@@ -68,39 +66,35 @@
                     (PowerManager)context.getSystemService(Context.POWER_SERVICE);
             String deviceAddress = device != null ? device.getAddress() : null;
             if (powerManager.isScreenOn() &&
-                localManager.shouldShowDialogInForeground(deviceAddress)) {
+                    LocalBluetoothPreferences.shouldShowDialogInForeground(context, deviceAddress)) {
                 // Since the screen is on and the BT-related activity is in the foreground,
                 // just open the dialog
                 context.startActivity(pairingIntent);
-
             } else {
-
                 // Put up a notification that leads to the dialog
                 Resources res = context.getResources();
-                Notification notification = new Notification(
-                        android.R.drawable.stat_sys_data_bluetooth,
-                        res.getString(R.string.bluetooth_notif_ticker),
-                        System.currentTimeMillis());
+                Notification.Builder builder = new Notification.Builder(context)
+                        .setSmallIcon(android.R.drawable.stat_sys_data_bluetooth)
+                        .setTicker(res.getString(R.string.bluetooth_notif_ticker));
 
                 PendingIntent pending = PendingIntent.getActivity(context, 0,
                         pairingIntent, PendingIntent.FLAG_ONE_SHOT);
 
                 String name = intent.getStringExtra(BluetoothDevice.EXTRA_NAME);
                 if (TextUtils.isEmpty(name)) {
-                    name = (device != null ? device.getName() :
-                            context.getString(android.R.string.unknownName));
+                    name = device != null ? device.getName() :
+                            context.getString(android.R.string.unknownName);
                 }
 
-                notification.setLatestEventInfo(context,
-                        res.getString(R.string.bluetooth_notif_title),
-                        res.getString(R.string.bluetooth_notif_message, name),
-                        pending);
-                notification.flags |= Notification.FLAG_AUTO_CANCEL;
-                notification.defaults |= Notification.DEFAULT_SOUND;
+                builder.setContentTitle(res.getString(R.string.bluetooth_notif_title))
+                        .setContentText(res.getString(R.string.bluetooth_notif_message, name))
+                        .setContentIntent(pending)
+                        .setAutoCancel(true)
+                        .setDefaults(Notification.DEFAULT_SOUND);
 
                 NotificationManager manager = (NotificationManager)
                         context.getSystemService(Context.NOTIFICATION_SERVICE);
-                manager.notify(NOTIFICATION_ID, notification);
+                manager.notify(NOTIFICATION_ID, builder.getNotification());
             }
 
         } else if (action.equals(BluetoothDevice.ACTION_PAIRING_CANCEL)) {
diff --git a/src/com/android/settings/bluetooth/BluetoothProfilePreference.java b/src/com/android/settings/bluetooth/BluetoothProfilePreference.java
index c74012a..e334867 100644
--- a/src/com/android/settings/bluetooth/BluetoothProfilePreference.java
+++ b/src/com/android/settings/bluetooth/BluetoothProfilePreference.java
@@ -16,9 +16,6 @@
 
 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;
@@ -26,22 +23,24 @@
 import android.view.View.OnClickListener;
 import android.widget.ImageView;
 
+import com.android.settings.R;
+
 /**
  * BluetoothProfilePreference is the preference type used to display each profile for a
  * particular bluetooth device.
  */
-public class BluetoothProfilePreference extends Preference implements OnClickListener {
+final class BluetoothProfilePreference extends Preference implements OnClickListener {
 
-    private static final String TAG = "BluetoothProfilePreference";
+//    private static final String TAG = "BluetoothProfilePreference";
 
     private Drawable mProfileDrawable;
     private boolean mExpanded;
     private ImageView mProfileExpandView;
-    private final Profile mProfile;
+    private final LocalBluetoothProfile mProfile;
 
     private OnClickListener mOnExpandClickListener;
 
-    public BluetoothProfilePreference(Context context, Profile profile) {
+    BluetoothProfilePreference(Context context, LocalBluetoothProfile profile) {
         super(context);
 
         mProfile = profile;
@@ -75,14 +74,14 @@
         btProfile.setImageDrawable(mProfileDrawable);
 
         mProfileExpandView = (ImageView) view.findViewById(R.id.profileExpand);
-        if (mProfile == Profile.PAN) {
-            mProfileExpandView.setVisibility(View.GONE);
-        } else {
+        if (mProfile.isAutoConnectable()) {
             mProfileExpandView.setOnClickListener(this);
             mProfileExpandView.setTag(mProfile);
             mProfileExpandView.setImageResource(mExpanded
                     ? com.android.internal.R.drawable.expander_open_holo_dark
                     : com.android.internal.R.drawable.expander_close_holo_dark);
+        } else {
+            mProfileExpandView.setVisibility(View.GONE);
         }
     }
 
diff --git a/src/com/android/settings/bluetooth/BluetoothSettings.java b/src/com/android/settings/bluetooth/BluetoothSettings.java
index 07121e9..c6ba9af 100644
--- a/src/com/android/settings/bluetooth/BluetoothSettings.java
+++ b/src/com/android/settings/bluetooth/BluetoothSettings.java
@@ -16,15 +16,13 @@
 
 package com.android.settings.bluetooth;
 
-import android.app.Activity;
 import android.bluetooth.BluetoothDevice;
 import android.content.Intent;
 import android.preference.CheckBoxPreference;
 import android.preference.ListPreference;
 import android.preference.Preference;
-import android.preference.PreferenceCategory;
+import android.preference.PreferenceActivity;
 import android.preference.PreferenceScreen;
-import android.text.TextUtils;
 import android.util.Log;
 import android.view.View;
 
@@ -34,9 +32,7 @@
  * BluetoothSettings is the Settings screen for Bluetooth configuration and
  * connection management.
  */
-public class BluetoothSettings extends DeviceListPreferenceFragment
-        implements LocalBluetoothManager.Callback, View.OnClickListener {
-
+public final class BluetoothSettings extends DeviceListPreferenceFragment {
     private static final String TAG = "BluetoothSettings";
 
     private static final String KEY_BT_CHECKBOX = "bt_checkbox";
@@ -53,13 +49,20 @@
     private static final String BTOPP_ACTION_OPEN_RECEIVED_FILES =
             "android.btopp.intent.action.OPEN_RECEIVED_FILES";
 
-    void addPreferencesForActivity(Activity activity) {
+    /** Initialize the filter to show bonded devices only. */
+    public BluetoothSettings() {
+        super(BluetoothDeviceFilter.BONDED_DEVICE_FILTER);
+    }
+
+    @Override
+    void addPreferencesForActivity() {
         addPreferencesFromResource(R.xml.bluetooth_settings);
 
-        mEnabler = new BluetoothEnabler(activity,
+        mEnabler = new BluetoothEnabler(getActivity(), mLocalAdapter,
                 (CheckBoxPreference) findPreference(KEY_BT_CHECKBOX));
 
-        mDiscoverableEnabler = new BluetoothDiscoverableEnabler(activity,
+        mDiscoverableEnabler = new BluetoothDiscoverableEnabler(getActivity(),
+                mLocalAdapter,
                 (CheckBoxPreference) findPreference(KEY_BT_DISCOVERABLE),
                     (ListPreference) findPreference(KEY_BT_DISCOVERABLE_TIMEOUT));
 
@@ -88,6 +91,27 @@
         mEnabler.pause();
     }
 
+    private final View.OnClickListener mListener = new View.OnClickListener() {
+        public void onClick(View v) {
+            // User clicked on advanced options icon for a device in the list
+            if (v.getTag() instanceof CachedBluetoothDevice) {
+                CachedBluetoothDevice
+                        device = (CachedBluetoothDevice) v.getTag();
+
+                Preference pref = new Preference(getActivity());
+                pref.setTitle(device.getName());
+                pref.setFragment(DeviceProfilesSettings.class.getName());
+                pref.getExtras().putParcelable(DeviceProfilesSettings.EXTRA_DEVICE,
+                        device.getDevice());
+                ((PreferenceActivity) getActivity())
+                        .onPreferenceStartFragment(BluetoothSettings.this,
+                                pref);
+            } else {
+                Log.w(TAG, "onClick() called for other View: " + v);
+            }
+        }
+    };
+
     @Override
     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
             Preference preference) {
@@ -105,9 +129,7 @@
         if (bondState == BluetoothDevice.BOND_BONDED) {
             // add to "Paired devices" list after remote-initiated pairing
             if (mDevicePreferenceMap.get(cachedDevice) == null) {
-                if (addDevicePreference(cachedDevice)) {
-                    createDevicePreference(cachedDevice);
-                }
+                createDevicePreference(cachedDevice);
             }
         } else if (bondState == BluetoothDevice.BOND_NONE) {
             // remove unpaired device from paired devices list
@@ -116,21 +138,11 @@
     }
 
     /**
-     * Additional check to only add paired devices to list.
-     */
-    boolean addDevicePreference(CachedBluetoothDevice cachedDevice) {
-        if (cachedDevice.getBondState() == BluetoothDevice.BOND_BONDED) {
-            return super.addDevicePreference(cachedDevice);
-        } else {
-            return false;
-        }
-    }
-
-    /**
      * Add a listener, which enables the advanced settings icon.
      * @param preference the newly added preference
      */
+    @Override
     void initDevicePreference(BluetoothDevicePreference preference) {
-        preference.setOnSettingsClickListener(this);
+        preference.setOnSettingsClickListener(mListener);
     }
 }
diff --git a/src/com/android/settings/bluetooth/CachedBluetoothDevice.java b/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
index 11885ac..0bc816c 100644
--- a/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
+++ b/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
@@ -16,30 +16,18 @@
 
 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.res.Resources;
-import android.graphics.drawable.Drawable;
+import android.bluetooth.BluetoothProfile;
 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 java.util.ArrayList;
-import java.util.HashMap;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
-import java.util.Map;
 
 /**
  * CachedBluetoothDevice represents a remote Bluetooth device. It contains
@@ -47,27 +35,23 @@
  * functionality that can be performed on the device (connect, pair, disconnect,
  * etc.).
  */
-class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> {
+final class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> {
     private static final String TAG = "CachedBluetoothDevice";
-    private static final boolean D = LocalBluetoothManager.D;
-    private static final boolean V = LocalBluetoothManager.V;
-    private static final boolean DEBUG = false;
+    private static final boolean DEBUG = Utils.V;
 
+    private final LocalBluetoothAdapter mLocalAdapter;
+    private final LocalBluetoothProfileManager mProfileManager;
     private final BluetoothDevice mDevice;
     private String mName;
     private short mRssi;
     private BluetoothClass mBtClass;
-    private Context mContext;
 
-    private List<Profile> mProfiles = new ArrayList<Profile>();
+    private final List<LocalBluetoothProfile> mProfiles =
+            new ArrayList<LocalBluetoothProfile>();
 
     private boolean mVisible;
 
-    private final LocalBluetoothManager mLocalManager;
-
-    private AlertDialog mDialog = null;
-
-    private List<Callback> mCallbacks = new ArrayList<Callback>();
+    private final Collection<Callback> mCallbacks = new ArrayList<Callback>();
 
     /**
      * When we connect to multiple profiles, we only want to display a single
@@ -95,186 +79,62 @@
      * @param profile Profile to describe
      * @return Description of the device and profile
      */
-    private String describe(Profile profile) {
+    private String describe(LocalBluetoothProfile profile) {
         StringBuilder sb = new StringBuilder();
         sb.append("Address:").append(mDevice);
         if (profile != null) {
-            sb.append(" Profile:").append(profile.name());
+            sb.append(" Profile:").append(profile);
         }
 
         return sb.toString();
     }
 
-    public void onProfileStateChanged(Profile profile, int newProfileState) {
-        if (D) {
-            Log.d(TAG, "onProfileStateChanged: profile " + profile.toString() +
+    void onProfileStateChanged(LocalBluetoothProfile profile, int newProfileState) {
+        if (Utils.D) {
+            Log.d(TAG, "onProfileStateChanged: profile " + profile +
                     " newProfileState " + newProfileState);
         }
 
-        final LocalBluetoothProfileManager pm =
-                LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
-        if (pm == null) return;
-        int newState = pm.convertState(newProfileState);
-
-        if (newState == SettingsBtStatus.CONNECTION_STATUS_CONNECTED) {
+        if (newProfileState == BluetoothProfile.STATE_CONNECTED) {
             if (!mProfiles.contains(profile)) {
                 mProfiles.add(profile);
             }
         }
     }
 
-    CachedBluetoothDevice(Context context, BluetoothDevice device) {
-        mLocalManager = LocalBluetoothManager.getInstance(context);
-        if (mLocalManager == null) {
-            throw new IllegalStateException(
-                    "Cannot use CachedBluetoothDevice without Bluetooth hardware");
-        }
-
+    CachedBluetoothDevice(LocalBluetoothAdapter adapter,
+            LocalBluetoothProfileManager profileManager,
+            BluetoothDevice device) {
+        mLocalAdapter = adapter;
+        mProfileManager = profileManager;
         mDevice = device;
-        mContext = context;
-
         fillData();
     }
 
-    public void onClicked() {
-        int bondState = getBondState();
-
-        if (isConnected()) {
-            askDisconnect();
-        } else if (bondState == BluetoothDevice.BOND_BONDED) {
-            connect(true);
-        } else if (bondState == BluetoothDevice.BOND_NONE) {
-            pair();
-        }
-    }
-
-    public void disconnect() {
-        for (Profile profile : mProfiles) {
+    void disconnect() {
+        for (LocalBluetoothProfile profile : mProfiles) {
             disconnect(profile);
         }
     }
 
-    public void disconnect(Profile profile) {
-        LocalBluetoothProfileManager profileManager =
-                LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
-        if (profileManager.disconnect(mDevice)) {
-            if (D) {
+    void disconnect(LocalBluetoothProfile profile) {
+        if (profile.disconnect(mDevice)) {
+            if (Utils.D) {
                 Log.d(TAG, "Command sent successfully:DISCONNECT " + describe(profile));
             }
         }
     }
 
-    public void askDisconnect() {
-        Context context = mLocalManager.getForegroundActivity();
-        if (context == null) {
-            // Cannot ask, since we need an activity context
-            disconnect();
+    void connect(boolean connectAllProfiles) {
+        if (!ensurePaired()) {
             return;
         }
 
-        Resources res = context.getResources();
-
-        String name = getName();
-        if (TextUtils.isEmpty(name)) {
-            name = res.getString(R.string.bluetooth_device);
-        }
-        String message = res.getString(R.string.bluetooth_disconnect_blank, name);
-
-        DialogInterface.OnClickListener disconnectListener = new DialogInterface.OnClickListener() {
-            public void onClick(DialogInterface dialog, int which) {
-                disconnect();
-            }
-        };
-
-        showDisconnectDialog(context, disconnectListener, message);
-    }
-
-    public void askDisconnect(final Profile profile) {
-        Context context = mLocalManager.getForegroundActivity();
-        if (context == null) {
-            // Cannot ask, since we need an activity context
-            disconnect(profile);
-            return;
-        }
-
-        Resources res = context.getResources();
-
-        String name = getName();
-        if (TextUtils.isEmpty(name)) {
-            name = res.getString(R.string.bluetooth_device);
-        }
-        int disconnectMessage;
-        switch (profile) {
-            case A2DP:
-                disconnectMessage = R.string.bluetooth_disconnect_a2dp_profile;
-                break;
-            case HEADSET:
-                disconnectMessage = R.string.bluetooth_disconnect_headset_profile;
-                break;
-            case HID:
-                disconnectMessage = R.string.bluetooth_disconnect_hid_profile;
-                break;
-            case PAN:
-                disconnectMessage = R.string.bluetooth_disconnect_pan_profile;
-                break;
-            default:
-                Log.w(TAG, "askDisconnect: unexpected profile " + profile);
-                disconnectMessage = R.string.bluetooth_disconnect_blank;
-                break;
-        }
-        String message = res.getString(disconnectMessage, name);
-
-        DialogInterface.OnClickListener disconnectListener =
-                new DialogInterface.OnClickListener() {
-            public void onClick(DialogInterface dialog, int which) {
-                disconnect(profile);
-            }
-        };
-
-        showDisconnectDialog(context, disconnectListener, message);
-    }
-
-    private void showDisconnectDialog(Context context,
-            DialogInterface.OnClickListener disconnectListener,
-            String message) {
-        if (mDialog == null) {
-            mDialog = new AlertDialog.Builder(context)
-                    .setPositiveButton(android.R.string.ok, disconnectListener)
-                    .setNegativeButton(android.R.string.cancel, null)
-                    .create();
-        } else {
-            if (mDialog.isShowing()) {
-                mDialog.dismiss();
-            }
-            // use disconnectListener for the correct profile(s)
-            CharSequence okText = context.getText(android.R.string.ok);
-            mDialog.setButton(DialogInterface.BUTTON_POSITIVE,
-                    okText, disconnectListener);
-        }
-        mDialog.setTitle(getName());
-        mDialog.setMessage(message);
-        mDialog.show();
-    }
-
-    @Override
-    protected void finalize() throws Throwable {
-        if (mDialog != null) {
-            mDialog.dismiss();
-            mDialog = null;
-        }
-
-        super.finalize();
-    }
-
-    public void connect(boolean connectAllProfiles) {
-        if (!ensurePaired()) return;
-
         mConnectAttempted = SystemClock.elapsedRealtime();
-
         connectWithoutResettingTimer(connectAllProfiles);
     }
 
-    /*package*/ void onBondingDockConnect() {
+    void onBondingDockConnect() {
         // Attempt to connect if UUIDs are available. Otherwise,
         // we will connect when the ACTION_UUID intent arrives.
         connect(false);
@@ -282,7 +142,7 @@
 
     private void connectWithoutResettingTimer(boolean connectAllProfiles) {
         // Try to initialize the profiles if they were not.
-        if (mProfiles.size() == 0) {
+        if (mProfiles.isEmpty()) {
             if (!updateProfiles()) {
                 // If UUIDs are not available yet, connect will be happen
                 // upon arrival of the ACTION_UUID intent.
@@ -295,98 +155,85 @@
         mIsConnectingErrorPossible = true;
 
         int preferredProfiles = 0;
-        for (Profile profile : mProfiles) {
+        for (LocalBluetoothProfile profile : mProfiles) {
             if (connectAllProfiles ? profile.isConnectable() : profile.isAutoConnectable()) {
-                LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
-                        .getProfileManager(mLocalManager, profile);
-                if (profileManager.isPreferred(mDevice)) {
+                if (profile.isPreferred(mDevice)) {
                     ++preferredProfiles;
-                    connectInt(this, profile);
+                    connectInt(profile);
                 }
             }
         }
         if (DEBUG) Log.d(TAG, "Preferred profiles = " + preferredProfiles);
 
         if (preferredProfiles == 0) {
-            connectAllAutoConnectableProfiles();
+            connectAutoConnectableProfiles();
         }
     }
 
-    private void connectAllAutoConnectableProfiles() {
-        if (!ensurePaired()) return;
-
+    private void connectAutoConnectableProfiles() {
+        if (!ensurePaired()) {
+            return;
+        }
         // Reset the only-show-one-error-dialog tracking variable
         mIsConnectingErrorPossible = true;
 
-        for (Profile profile : mProfiles) {
+        for (LocalBluetoothProfile profile : mProfiles) {
             if (profile.isAutoConnectable()) {
-                LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
-                        .getProfileManager(mLocalManager, profile);
-                profileManager.setPreferred(mDevice, true);
-                connectInt(this, profile);
+                profile.setPreferred(mDevice, true);
+                connectInt(profile);
             }
         }
     }
 
-    public void connect(Profile profile) {
+    /**
+     * Connect this device to the specified profile.
+     *
+     * @param profile the profile to use with the remote device
+     */
+    void connectProfile(LocalBluetoothProfile profile) {
         mConnectAttempted = SystemClock.elapsedRealtime();
         // Reset the only-show-one-error-dialog tracking variable
         mIsConnectingErrorPossible = true;
-        connectInt(this, profile);
+        connectInt(profile);
     }
 
-    private boolean connectInt(CachedBluetoothDevice cachedDevice, Profile profile) {
-        if (!cachedDevice.ensurePaired()) return false;
-
-        LocalBluetoothProfileManager profileManager =
-                LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
-
-        if (profileManager.connect(cachedDevice.mDevice)) {
-            if (D) {
+    private void connectInt(LocalBluetoothProfile profile) {
+        if (!ensurePaired()) {
+            return;
+        }
+        if (profile.connect(mDevice)) {
+            if (Utils.D) {
                 Log.d(TAG, "Command sent successfully:CONNECT " + describe(profile));
             }
-            return true;
+            return;
         }
-        Log.i(TAG, "Failed to connect " + profile.toString() + " to " + cachedDevice.mName);
-
-        return false;
-    }
-
-    public void showConnectingError() {
-        if (!mIsConnectingErrorPossible) return;
-        mIsConnectingErrorPossible = false;
-
-        mLocalManager.showError(mDevice,
-                R.string.bluetooth_connecting_error_message);
+        Log.i(TAG, "Failed to connect " + profile.toString() + " to " + mName);
     }
 
     private boolean ensurePaired() {
         if (getBondState() == BluetoothDevice.BOND_NONE) {
-            pair();
+            startPairing();
             return false;
         } else {
             return true;
         }
     }
 
-    public void pair() {
-        BluetoothAdapter adapter = mLocalManager.getBluetoothAdapter();
-
+    boolean startPairing() {
         // Pairing is unreliable while scanning, so cancel discovery
-        if (adapter.isDiscovering()) {
-            adapter.cancelDiscovery();
+        if (mLocalAdapter.isDiscovering()) {
+            mLocalAdapter.cancelDiscovery();
         }
 
         if (!mDevice.createBond()) {
-            mLocalManager.showError(mDevice,
-                    R.string.bluetooth_pairing_error_message);
-            return;
+            return false;
         }
 
         mConnectAfterPairing = true;  // auto-connect after pairing
+        return true;
     }
 
-    public void unpair() {
+    void unpair() {
         disconnect();
 
         int state = getBondState();
@@ -396,14 +243,14 @@
         }
 
         if (state != BluetoothDevice.BOND_NONE) {
-            final BluetoothDevice dev = getDevice();
+            final BluetoothDevice dev = mDevice;
             if (dev != null) {
                 final boolean successful = dev.removeBond();
                 if (successful) {
-                    if (D) {
+                    if (Utils.D) {
                         Log.d(TAG, "Command sent successfully:REMOVE_BOND " + describe(null));
                     }
-                } else if (V) {
+                } else if (Utils.V) {
                     Log.v(TAG, "Framework rejected command immediately:REMOVE_BOND " +
                             describe(null));
                 }
@@ -411,6 +258,7 @@
         }
     }
 
+    // TODO: do any of these need to run async on a background thread?
     private void fillData() {
         fetchName();
         fetchBtClass();
@@ -421,15 +269,15 @@
         dispatchAttributesChanged();
     }
 
-    public BluetoothDevice getDevice() {
+    BluetoothDevice getDevice() {
         return mDevice;
     }
 
-    public String getName() {
+    String getName() {
         return mName;
     }
 
-    public void setName(String name) {
+    void setName(String name) {
         if (!mName.equals(name)) {
             if (TextUtils.isEmpty(name)) {
                 // TODO: use friendly name for unknown device (bug 1181856)
@@ -442,7 +290,7 @@
         }
     }
 
-    public void refreshName() {
+    void refreshName() {
         fetchName();
         dispatchAttributesChanged();
     }
@@ -452,15 +300,15 @@
 
         if (TextUtils.isEmpty(mName)) {
             mName = mDevice.getAddress();
-            if (DEBUG) Log.d(TAG, "Default to address. Device has no name (yet) " + mName);
+            if (DEBUG) Log.d(TAG, "Device has no name (yet), use address: " + mName);
         }
     }
 
-    public void refresh() {
+    void refresh() {
         dispatchAttributesChanged();
     }
 
-    public boolean isVisible() {
+    boolean isVisible() {
         return mVisible;
     }
 
@@ -471,7 +319,7 @@
         }
     }
 
-    public int getBondState() {
+    int getBondState() {
         return mDevice.getBondState();
     }
 
@@ -487,11 +335,10 @@
      *
      * @return Whether it is connected.
      */
-    public boolean isConnected() {
-        for (Profile profile : mProfiles) {
-            int status = LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile)
-                    .getConnectionStatus(mDevice);
-            if (SettingsBtStatus.isConnectionStatusConnected(status)) {
+    boolean isConnected() {
+        for (LocalBluetoothProfile profile : mProfiles) {
+            int status = profile.getConnectionStatus(mDevice);
+            if (status == BluetoothProfile.STATE_CONNECTED) {
                 return true;
             }
         }
@@ -499,81 +346,21 @@
         return false;
     }
 
-    public boolean isConnectedProfile(Profile profile) {
-        int status = LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile)
-                .getConnectionStatus(mDevice);
-        if (SettingsBtStatus.isConnectionStatusConnected(status)) {
-            return true;
-        }
+    boolean isConnectedProfile(LocalBluetoothProfile profile) {
+        int status = profile.getConnectionStatus(mDevice);
+        return status == BluetoothProfile.STATE_CONNECTED;
 
-        return false;
     }
 
-    public boolean isBusy() {
-        for (Profile profile : mProfiles) {
-            int status = LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile)
-                    .getConnectionStatus(mDevice);
-            if (SettingsBtStatus.isConnectionStatusBusy(status)) {
+    boolean isBusy() {
+        for (LocalBluetoothProfile profile : mProfiles) {
+            int status = profile.getConnectionStatus(mDevice);
+            if (status == BluetoothProfile.STATE_CONNECTING
+                    || status == BluetoothProfile.STATE_DISCONNECTING) {
                 return true;
             }
         }
-
-        if (getBondState() == BluetoothDevice.BOND_BONDING) {
-            return true;
-        }
-
-        return false;
-    }
-
-    public int getBtClassDrawable() {
-        if (mBtClass != null) {
-            switch (mBtClass.getMajorDeviceClass()) {
-                case BluetoothClass.Device.Major.COMPUTER:
-                    return R.drawable.ic_bt_laptop;
-
-                case BluetoothClass.Device.Major.PHONE:
-                    return R.drawable.ic_bt_cellphone;
-
-                case BluetoothClass.Device.Major.PERIPHERAL:
-                    return getHidClassDrawable();
-
-                case BluetoothClass.Device.Major.IMAGING:
-                    return R.drawable.ic_bt_imaging;
-            }
-        } else {
-            Log.w(TAG, "mBtClass is null");
-        }
-
-        if (mProfiles.size() > 0) {
-            if (mProfiles.contains(Profile.A2DP)) {
-                return R.drawable.ic_bt_headphones_a2dp;
-            } else if (mProfiles.contains(Profile.HEADSET)) {
-                return R.drawable.ic_bt_headset_hfp;
-            }
-        } else if (mBtClass != null) {
-            if (mBtClass.doesClassMatch(BluetoothClass.PROFILE_A2DP)) {
-                return R.drawable.ic_bt_headphones_a2dp;
-
-            }
-            if (mBtClass.doesClassMatch(BluetoothClass.PROFILE_HEADSET)) {
-                return R.drawable.ic_bt_headset_hfp;
-            }
-        }
-        return 0;
-    }
-
-    private int getHidClassDrawable() {
-        switch (mBtClass.getDeviceClass()) {
-            case BluetoothClass.Device.PERIPHERAL_KEYBOARD:
-            case BluetoothClass.Device.PERIPHERAL_KEYBOARD_POINTING:
-                return R.drawable.ic_bt_keyboard_hid;
-
-            case BluetoothClass.Device.PERIPHERAL_POINTING:
-                return R.drawable.ic_bt_pointing_hid;
-
-            default:
-                return R.drawable.ic_bt_misc_hid;
-        }
+        return getBondState() == BluetoothDevice.BOND_BONDING;
     }
 
     /**
@@ -587,11 +374,10 @@
         ParcelUuid[] uuids = mDevice.getUuids();
         if (uuids == null) return false;
 
-        BluetoothAdapter adapter = mLocalManager.getBluetoothAdapter();
-        ParcelUuid[] localUuids = adapter.getUuids();
+        ParcelUuid[] localUuids = mLocalAdapter.getUuids();
         if (localUuids == null) return false;
 
-        LocalBluetoothProfileManager.updateProfiles(uuids, localUuids, mProfiles);
+        mProfileManager.updateProfiles(uuids, localUuids, mProfiles);
 
         if (DEBUG) {
             Log.e(TAG, "updating profiles for " + mDevice.getName());
@@ -599,8 +385,8 @@
 
             if (bluetoothClass != null) Log.v(TAG, "Class: " + bluetoothClass.toString());
             Log.v(TAG, "UUID:");
-            for (int i = 0; i < uuids.length; i++) {
-                Log.v(TAG, "  " + uuids[i]);
+            for (ParcelUuid uuid : uuids) {
+                Log.v(TAG, "  " + uuid);
             }
         }
         return true;
@@ -610,7 +396,7 @@
      * Refreshes the UI for the BT class, including fetching the latest value
      * for the class.
      */
-    public void refreshBtClass() {
+    void refreshBtClass() {
         fetchBtClass();
         dispatchAttributesChanged();
     }
@@ -618,7 +404,7 @@
     /**
      * Refreshes the UI when framework alerts us of a UUID change.
      */
-    public void onUuidChanged() {
+    void onUuidChanged() {
         updateProfiles();
 
         if (DEBUG) {
@@ -630,7 +416,7 @@
          * If a connect was attempted earlier without any UUID, we will do the
          * connect now.
          */
-        if (mProfiles.size() > 0
+        if (!mProfiles.isEmpty()
                 && (mConnectAttempted + MAX_UUID_DELAY_FOR_AUTO_CONNECT) > SystemClock
                         .elapsedRealtime()) {
             connectWithoutResettingTimer(false);
@@ -638,7 +424,7 @@
         dispatchAttributesChanged();
     }
 
-    public void onBondingStateChanged(int bondState) {
+    void onBondingStateChanged(int bondState) {
         if (bondState == BluetoothDevice.BOND_NONE) {
             mProfiles.clear();
             mConnectAfterPairing = false;  // cancel auto-connect
@@ -656,52 +442,25 @@
         }
     }
 
-    public void setBtClass(BluetoothClass btClass) {
+    void setBtClass(BluetoothClass btClass) {
         if (btClass != null && mBtClass != btClass) {
             mBtClass = btClass;
             dispatchAttributesChanged();
         }
     }
 
-    public int getSummary() {
-        for (Profile profile : mProfiles) {
-            LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
-                    .getProfileManager(mLocalManager, profile);
-            int connectionStatus = profileManager.getConnectionStatus(mDevice);
-
-            if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus) ||
-                    connectionStatus == SettingsBtStatus.CONNECTION_STATUS_CONNECTING ||
-                    connectionStatus == SettingsBtStatus.CONNECTION_STATUS_DISCONNECTING) {
-                return SettingsBtStatus.getConnectionStatusSummary(connectionStatus);
-            }
-        }
-
-        return SettingsBtStatus.getPairingStatusSummary(getBondState());
+    BluetoothClass getBtClass() {
+        return mBtClass;
     }
 
-    public Map<Profile, Drawable> getProfileIcons() {
-        Map<Profile, Drawable> drawables = new HashMap<Profile, Drawable>();
-
-        for (Profile profile : mProfiles) {
-            int iconResource;
-            if (profile == Profile.HID && mBtClass != null) {
-                iconResource = getHidClassDrawable();
-            } else {
-                LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
-                        .getProfileManager(mLocalManager, profile);
-                iconResource = profileManager.getDrawableResource();
-            }
-            if (iconResource != 0) {
-                drawables.put(profile, mContext.getResources().getDrawable(iconResource));
-            }
-        }
-
-        return drawables;
+    List<LocalBluetoothProfile> getProfiles() {
+        return Collections.unmodifiableList(mProfiles);
     }
 
-    public List<Profile> getConnectableProfiles() {
-        ArrayList<Profile> connectableProfiles = new ArrayList<Profile>();
-        for (Profile profile : mProfiles) {
+    List<LocalBluetoothProfile> getConnectableProfiles() {
+        List<LocalBluetoothProfile> connectableProfiles =
+                new ArrayList<LocalBluetoothProfile>();
+        for (LocalBluetoothProfile profile : mProfiles) {
             if (profile.isConnectable()) {
                 connectableProfiles.add(profile);
             }
@@ -709,36 +468,13 @@
         return connectableProfiles;
     }
 
-    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) {
+    void registerCallback(Callback callback) {
         synchronized (mCallbacks) {
             mCallbacks.add(callback);
         }
     }
 
-    public void unregisterCallback(Callback callback) {
+    void unregisterCallback(Callback callback) {
         synchronized (mCallbacks) {
             mCallbacks.remove(callback);
         }
@@ -760,9 +496,8 @@
     @Override
     public boolean equals(Object o) {
         if ((o == null) || !(o instanceof CachedBluetoothDevice)) {
-            throw new ClassCastException();
+            return false;
         }
-
         return mDevice.equals(((CachedBluetoothDevice) o).mDevice);
     }
 
@@ -771,11 +506,12 @@
         return mDevice.getAddress().hashCode();
     }
 
+    // This comparison uses non-final fields so the sort order may change
+    // when device attributes change (such as bonding state). Settings
+    // will completely refresh the device list when this happens.
     public int compareTo(CachedBluetoothDevice another) {
-        int comparison;
-
         // Connected above not connected
-        comparison = (another.isConnected() ? 1 : 0) - (isConnected() ? 1 : 0);
+        int comparison = (another.isConnected() ? 1 : 0) - (isConnected() ? 1 : 0);
         if (comparison != 0) return comparison;
 
         // Paired above not paired
@@ -792,7 +528,7 @@
         if (comparison != 0) return comparison;
 
         // Fallback on name
-        return getName().compareTo(another.getName());
+        return mName.compareTo(another.mName);
     }
 
     public interface Callback {
diff --git a/src/com/android/settings/bluetooth/CachedBluetoothDeviceManager.java b/src/com/android/settings/bluetooth/CachedBluetoothDeviceManager.java
index 3ee8bc2..ab71ece 100644
--- a/src/com/android/settings/bluetooth/CachedBluetoothDeviceManager.java
+++ b/src/com/android/settings/bluetooth/CachedBluetoothDeviceManager.java
@@ -16,122 +16,83 @@
 
 package com.android.settings.bluetooth;
 
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothClass;
 import android.bluetooth.BluetoothDevice;
-import android.util.Log;
-
-import com.android.settings.R;
-import com.android.settings.bluetooth.LocalBluetoothManager.Callback;
-import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
-import java.util.Set;
 
 /**
  * CachedBluetoothDeviceManager manages the set of remote Bluetooth devices.
  */
-class CachedBluetoothDeviceManager {
-    private static final String TAG = "CachedBluetoothDeviceManager";
+final class CachedBluetoothDeviceManager {
+//    private static final String TAG = "CachedBluetoothDeviceManager";
 
-    final LocalBluetoothManager mLocalManager;
-    final List<Callback> mCallbacks;
+    private final List<CachedBluetoothDevice> mCachedDevices =
+            new ArrayList<CachedBluetoothDevice>();
 
-    final List<CachedBluetoothDevice> mCachedDevices = new ArrayList<CachedBluetoothDevice>();
-
-    public CachedBluetoothDeviceManager(LocalBluetoothManager localManager) {
-        mLocalManager = localManager;
-        mCallbacks = localManager.getCallbacks();
-    }
-
-    private synchronized boolean readPairedDevices() {
-        BluetoothAdapter adapter = mLocalManager.getBluetoothAdapter();
-        Set<BluetoothDevice> bondedDevices = adapter.getBondedDevices();
-        if (bondedDevices == null) return false;
-
-        boolean deviceAdded = false;
-        for (BluetoothDevice device : bondedDevices) {
-            CachedBluetoothDevice cachedDevice = findDevice(device);
-            if (cachedDevice == null) {
-                cachedDevice = new CachedBluetoothDevice(mLocalManager.getContext(), device);
-                mCachedDevices.add(cachedDevice);
-                dispatchDeviceAdded(cachedDevice);
-                deviceAdded = true;
-            }
-        }
-
-        return deviceAdded;
-    }
-
-    public synchronized List<CachedBluetoothDevice> getCachedDevicesCopy() {
+    public synchronized Collection<CachedBluetoothDevice> getCachedDevicesCopy() {
         return new ArrayList<CachedBluetoothDevice>(mCachedDevices);
     }
 
-    void onBluetoothStateChanged(boolean enabled) {
-        if (enabled) {
-            readPairedDevices();
-        }
-    }
-
-    public synchronized void onDeviceAppeared(BluetoothDevice device, short rssi,
-            BluetoothClass btClass, String name) {
-        boolean deviceAdded = false;
-
-        CachedBluetoothDevice cachedDevice = findDevice(device);
-        if (cachedDevice == null) {
-            cachedDevice = new CachedBluetoothDevice(mLocalManager.getContext(), device);
-            mCachedDevices.add(cachedDevice);
-            deviceAdded = true;
-        }
-        cachedDevice.setRssi(rssi);
-        cachedDevice.setBtClass(btClass);
-        cachedDevice.setName(name);
-        cachedDevice.setVisible(true);
-
-        if (deviceAdded) {
-            dispatchDeviceAdded(cachedDevice);
-        }
-    }
-
-    public synchronized void onDeviceDisappeared(BluetoothDevice device) {
-        CachedBluetoothDevice cachedDevice = findDevice(device);
-        if (cachedDevice == null) return;
-
+    public boolean onDeviceDisappeared(CachedBluetoothDevice cachedDevice) {
         cachedDevice.setVisible(false);
-        checkForDeviceRemoval(cachedDevice);
+        return checkForDeviceRemoval(cachedDevice);
     }
 
-    private void checkForDeviceRemoval(CachedBluetoothDevice cachedDevice) {
+    private boolean checkForDeviceRemoval(
+            CachedBluetoothDevice cachedDevice) {
         if (cachedDevice.getBondState() == BluetoothDevice.BOND_NONE &&
                 !cachedDevice.isVisible()) {
             // If device isn't paired, remove it altogether
             mCachedDevices.remove(cachedDevice);
-            dispatchDeviceDeleted(cachedDevice);
+            return true;  // dispatch device deleted
         }
+        return false;
     }
 
-    public synchronized void onDeviceNameUpdated(BluetoothDevice device) {
+    public void onDeviceNameUpdated(BluetoothDevice device) {
         CachedBluetoothDevice cachedDevice = findDevice(device);
         if (cachedDevice != null) {
             cachedDevice.refreshName();
         }
     }
 
-    public synchronized CachedBluetoothDevice findDevice(BluetoothDevice device) {
-
-        for (int i = mCachedDevices.size() - 1; i >= 0; i--) {
-            CachedBluetoothDevice cachedDevice = mCachedDevices.get(i);
-
+    /**
+     * Search for existing {@link CachedBluetoothDevice} or return null
+     * if this device isn't in the cache. Use {@link #addDevice}
+     * to create and return a new {@link CachedBluetoothDevice} for
+     * a newly discovered {@link BluetoothDevice}.
+     *
+     * @param device the address of the Bluetooth device
+     * @return the cached device object for this device, or null if it has
+     *   not been previously seen
+     */
+    CachedBluetoothDevice findDevice(BluetoothDevice device) {
+        for (CachedBluetoothDevice cachedDevice : mCachedDevices) {
             if (cachedDevice.getDevice().equals(device)) {
                 return cachedDevice;
             }
         }
-
         return null;
     }
 
     /**
+     * Create and return a new {@link CachedBluetoothDevice}. This assumes
+     * that {@link #findDevice} has already been called and returned null.
+     * @param device the address of the new Bluetooth device
+     * @return the newly created CachedBluetoothDevice object
+     */
+    CachedBluetoothDevice addDevice(LocalBluetoothAdapter adapter,
+            LocalBluetoothProfileManager profileManager,
+            BluetoothDevice device) {
+        CachedBluetoothDevice newDevice = new CachedBluetoothDevice(adapter, profileManager,
+                device);
+        mCachedDevices.add(newDevice);
+        return newDevice;
+    }
+
+    /**
      * Attempts to get the name of a remote device, otherwise returns the address.
      *
      * @param device The remote device.
@@ -139,122 +100,23 @@
      */
     public String getName(BluetoothDevice device) {
         CachedBluetoothDevice cachedDevice = findDevice(device);
-        if (cachedDevice != null) return cachedDevice.getName();
+        if (cachedDevice != null) {
+            return cachedDevice.getName();
+        }
 
         String name = device.getName();
-        if (name != null) return name;
+        if (name != null) {
+            return name;
+        }
 
         return device.getAddress();
     }
 
-    private void dispatchDeviceAdded(CachedBluetoothDevice cachedDevice) {
-        synchronized (mCallbacks) {
-            for (Callback callback : mCallbacks) {
-                callback.onDeviceAdded(cachedDevice);
-            }
-        }
-
-        // TODO: divider between prev paired/connected and scanned
-    }
-
-    private void dispatchDeviceDeleted(CachedBluetoothDevice cachedDevice) {
-        synchronized (mCallbacks) {
-            for (Callback callback : mCallbacks) {
-                callback.onDeviceDeleted(cachedDevice);
-            }
-        }
-    }
-
-    private void dispatchDeviceBondStateChanged(
-            CachedBluetoothDevice cachedDevice, int bondState) {
-        synchronized (mCallbacks) {
-            for (Callback callback : mCallbacks) {
-                callback.onDeviceBondStateChanged(cachedDevice, bondState);
-            }
-        }
-    }
-
-    public synchronized void onBondingStateChanged(BluetoothDevice device, int bondState) {
-        CachedBluetoothDevice cachedDevice = findDevice(device);
-        if (cachedDevice == null) {
-            if (!readPairedDevices()) {
-                Log.e(TAG, "Got bonding state changed for " + device +
-                        ", but we have no record of that device.");
-                return;
-            }
-            cachedDevice = findDevice(device);
-            if (cachedDevice == null) {
-                Log.e(TAG, "Got bonding state changed for " + device +
-                        ", but device not added in cache.");
-                return;
-            }
-        }
-
-        dispatchDeviceBondStateChanged(cachedDevice, bondState);
-        cachedDevice.onBondingStateChanged(bondState);
-    }
-
-    /**
-     * Called when we have reached the un-bond state.
-     *
-     * @param device The remote device.
-     * @param reason The reason, one of the error reasons from
-     *            BluetoothDevice.UNBOND_REASON_*
-     */
-    public synchronized void showUnbondMessage(BluetoothDevice device, int reason) {
-        int errorMsg;
-
-        switch(reason) {
-        case BluetoothDevice.UNBOND_REASON_AUTH_FAILED:
-            errorMsg = R.string.bluetooth_pairing_pin_error_message;
-            mLocalManager.showError(device, errorMsg);
-            break;
-        case BluetoothDevice.UNBOND_REASON_AUTH_REJECTED:
-            errorMsg = R.string.bluetooth_pairing_rejected_error_message;
-            mLocalManager.showError(device, errorMsg);
-            break;
-        case BluetoothDevice.UNBOND_REASON_REMOTE_DEVICE_DOWN:
-            errorMsg = R.string.bluetooth_pairing_device_down_error_message;
-            mLocalManager.showError(device, errorMsg);
-            break;
-        case BluetoothDevice.UNBOND_REASON_DISCOVERY_IN_PROGRESS:
-        case BluetoothDevice.UNBOND_REASON_AUTH_TIMEOUT:
-        case BluetoothDevice.UNBOND_REASON_REPEATED_ATTEMPTS:
-        case BluetoothDevice.UNBOND_REASON_REMOTE_AUTH_CANCELED:
-            errorMsg = R.string.bluetooth_pairing_error_message;
-            mLocalManager.showError(device, errorMsg);
-            break;
-        default:
-            Log.w(TAG, "showUnbondMessage: Not displaying any message for reason:" + reason);
-            break;
-        }
-    }
-
-    public synchronized void onProfileStateChanged(BluetoothDevice device, Profile profile,
-            int newProfileState) {
-        CachedBluetoothDevice cachedDevice = findDevice(device);
-        if (cachedDevice == null) return;
-
-        cachedDevice.onProfileStateChanged(profile, newProfileState);
-        cachedDevice.refresh();
-    }
-
-    public synchronized void onConnectingError(BluetoothDevice device) {
-        CachedBluetoothDevice cachedDevice = findDevice(device);
-        if (cachedDevice == null) return;
-
-        /*
-         * Go through the device's delegate so we don't spam the user with
-         * errors connecting to different profiles, and instead make sure the
-         * user sees a single error for his single 'connect' action.
-         */
-        cachedDevice.showConnectingError();
-    }
-
     public synchronized void onScanningStateChanged(boolean started) {
         if (!started) return;
 
         // If starting a new scan, clear old visibility
+        // Iterate in reverse order since devices may be removed.
         for (int i = mCachedDevices.size() - 1; i >= 0; i--) {
             CachedBluetoothDevice cachedDevice = mCachedDevices.get(i);
             cachedDevice.setVisible(false);
diff --git a/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java b/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java
index 46fff6e..a978e23 100644
--- a/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java
+++ b/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java
@@ -16,28 +16,18 @@
 
 package com.android.settings.bluetooth;
 
-import android.app.Activity;
 import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothClass;
 import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothDevicePicker;
-import android.bluetooth.BluetoothUuid;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
 import android.os.Bundle;
-import android.os.ParcelUuid;
 import android.preference.Preference;
 import android.preference.PreferenceCategory;
 import android.preference.PreferenceScreen;
 import android.util.Log;
-import android.view.View;
 
 import com.android.settings.ProgressCategory;
 import com.android.settings.SettingsPreferenceFragment;
 
-import java.util.List;
+import java.util.Collection;
 import java.util.WeakHashMap;
 
 /**
@@ -48,105 +38,96 @@
  * @see DevicePickerFragment
  * @see BluetoothFindNearby
  */
-public abstract class DeviceListPreferenceFragment extends SettingsPreferenceFragment
-        implements LocalBluetoothManager.Callback, View.OnClickListener {
+public abstract class DeviceListPreferenceFragment extends
+        SettingsPreferenceFragment implements BluetoothCallback {
 
     private static final String TAG = "DeviceListPreferenceFragment";
 
-    static final String KEY_BT_DEVICE_LIST = "bt_device_list";
-    static final String KEY_BT_SCAN = "bt_scan";
+    private static final String KEY_BT_DEVICE_LIST = "bt_device_list";
+    private static final String KEY_BT_SCAN = "bt_scan";
 
-    int mFilterType;
+    private BluetoothDeviceFilter.Filter mFilter;
 
-    BluetoothDevice mSelectedDevice = null;
+    BluetoothDevice mSelectedDevice;
 
+    LocalBluetoothAdapter mLocalAdapter;
     LocalBluetoothManager mLocalManager;
 
     private PreferenceCategory mDeviceList;
 
-    WeakHashMap<CachedBluetoothDevice, BluetoothDevicePreference> mDevicePreferenceMap =
+    final WeakHashMap<CachedBluetoothDevice, BluetoothDevicePreference> mDevicePreferenceMap =
             new WeakHashMap<CachedBluetoothDevice, BluetoothDevicePreference>();
 
-    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (intent.getAction().equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
-                onBluetoothStateChanged(mLocalManager.getBluetoothState());
-            }
-        }
-    };
+    DeviceListPreferenceFragment() {
+        mFilter = BluetoothDeviceFilter.ALL_FILTER;
+    }
+
+    DeviceListPreferenceFragment(BluetoothDeviceFilter.Filter filter) {
+        mFilter = filter;
+    }
+
+    final void setFilter(int filterType) {
+        mFilter = BluetoothDeviceFilter.getFilter(filterType);
+    }
 
     @Override
-    public void onActivityCreated(Bundle savedInstanceState) {
-        // We delay calling super.onActivityCreated(). See WifiSettings.java for more info.
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
 
-        final Activity activity = getActivity();
-        mLocalManager = LocalBluetoothManager.getInstance(activity);
+        mLocalManager = LocalBluetoothManager.getInstance(getActivity());
         if (mLocalManager == null) {
-            finish();
+            Log.e(TAG, "Bluetooth is not supported on this device");
+            return;
         }
+        mLocalAdapter = mLocalManager.getBluetoothAdapter();
 
-        mFilterType = BluetoothDevicePicker.FILTER_TYPE_ALL;
-
-        if (getPreferenceScreen() != null) getPreferenceScreen().removeAll();
-
-        addPreferencesForActivity(activity);
+        addPreferencesForActivity();
 
         mDeviceList = (PreferenceCategory) findPreference(KEY_BT_DEVICE_LIST);
-
-        super.onActivityCreated(savedInstanceState);
+        if (mDeviceList == null) {
+            Log.e(TAG, "Could not find device list preference object!");
+        }
     }
 
     /** Add preferences from the subclass. */
-    abstract void addPreferencesForActivity(Activity activity);
+    abstract void addPreferencesForActivity();
 
     @Override
     public void onResume() {
         super.onResume();
 
-        mLocalManager.registerCallback(this);
-
-        updateProgressUi(mLocalManager.getBluetoothAdapter().isDiscovering());
-
-        IntentFilter intentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
-        getActivity().registerReceiver(mReceiver, intentFilter);
         mLocalManager.setForegroundActivity(getActivity());
+        mLocalManager.getEventManager().registerCallback(this);
+
+        updateProgressUi(mLocalAdapter.isDiscovering());
     }
 
     @Override
     public void onPause() {
         super.onPause();
-        mLocalManager.stopScanning();
+
+        mLocalAdapter.stopScanning();
         mLocalManager.setForegroundActivity(null);
+        mLocalManager.getEventManager().unregisterCallback(this);
+
         mDevicePreferenceMap.clear();
         mDeviceList.removeAll();
-        getActivity().unregisterReceiver(mReceiver);
-
-        mLocalManager.unregisterCallback(this);
     }
 
     void addDevices() {
-        List<CachedBluetoothDevice> cachedDevices =
+        Collection<CachedBluetoothDevice> cachedDevices =
                 mLocalManager.getCachedDeviceManager().getCachedDevicesCopy();
         for (CachedBluetoothDevice cachedDevice : cachedDevices) {
             onDeviceAdded(cachedDevice);
         }
     }
 
-    public void onClick(View v) {
-        // User clicked on advanced options icon for a device in the list
-        if (v.getTag() instanceof CachedBluetoothDevice) {
-            CachedBluetoothDevice device = (CachedBluetoothDevice) v.getTag();
-            device.onClickedAdvancedOptions(this);
-        }
-    }
-
     @Override
     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
             Preference preference) {
 
         if (KEY_BT_SCAN.equals(preference.getKey())) {
-            mLocalManager.startScanning(true);
+            mLocalAdapter.startScanning(true);
             return true;
         }
 
@@ -162,7 +143,7 @@
     }
 
     void onDevicePreferenceClick(BluetoothDevicePreference btPreference) {
-        btPreference.getCachedDevice().onClicked();
+        btPreference.onClicked();
     }
 
     public void onDeviceAdded(CachedBluetoothDevice cachedDevice) {
@@ -171,71 +152,11 @@
             return;
         }
 
-        if (addDevicePreference(cachedDevice)) {
+        if (mFilter.matches(cachedDevice.getDevice())) {
             createDevicePreference(cachedDevice);
         }
      }
 
-    /**
-     * Determine whether to add the new device to the list.
-     * @param cachedDevice the newly discovered device
-     * @return true if the device should be added; false otherwise
-     */
-    boolean addDevicePreference(CachedBluetoothDevice cachedDevice) {
-        ParcelUuid[] uuids = cachedDevice.getDevice().getUuids();
-        BluetoothClass bluetoothClass = cachedDevice.getDevice().getBluetoothClass();
-
-        switch(mFilterType) {
-        case BluetoothDevicePicker.FILTER_TYPE_TRANSFER:
-            if (uuids != null) {
-                if (BluetoothUuid.containsAnyUuid(uuids,
-                        LocalBluetoothProfileManager.OPP_PROFILE_UUIDS))  return true;
-            }
-            if (bluetoothClass != null
-                   && bluetoothClass.doesClassMatch(BluetoothClass.PROFILE_OPP)) {
-                return true;
-            }
-            break;
-        case BluetoothDevicePicker.FILTER_TYPE_AUDIO:
-            if (uuids != null) {
-                if (BluetoothUuid.containsAnyUuid(uuids,
-                        LocalBluetoothProfileManager.A2DP_SINK_PROFILE_UUIDS))  return true;
-
-                if (BluetoothUuid.containsAnyUuid(uuids,
-                        LocalBluetoothProfileManager.HEADSET_PROFILE_UUIDS))  return true;
-            } else if (bluetoothClass != null) {
-                if (bluetoothClass.doesClassMatch(BluetoothClass.PROFILE_A2DP)) return true;
-
-                if (bluetoothClass.doesClassMatch(BluetoothClass.PROFILE_HEADSET)) return true;
-            }
-            break;
-        case BluetoothDevicePicker.FILTER_TYPE_PANU:
-            if (uuids != null) {
-                if (BluetoothUuid.containsAnyUuid(uuids,
-                        LocalBluetoothProfileManager.PANU_PROFILE_UUIDS))  return true;
-
-            }
-            if (bluetoothClass != null
-                   && bluetoothClass.doesClassMatch(BluetoothClass.PROFILE_PANU)) {
-                return true;
-            }
-            break;
-        case BluetoothDevicePicker.FILTER_TYPE_NAP:
-            if (uuids != null) {
-                if (BluetoothUuid.containsAnyUuid(uuids,
-                        LocalBluetoothProfileManager.NAP_PROFILE_UUIDS))  return true;
-            }
-            if (bluetoothClass != null
-                   && bluetoothClass.doesClassMatch(BluetoothClass.PROFILE_NAP)) {
-                return true;
-            }
-            break;
-        default:
-            return true;
-        }
-        return false;
-    }
-
     void createDevicePreference(CachedBluetoothDevice cachedDevice) {
         BluetoothDevicePreference preference = new BluetoothDevicePreference(
                 getActivity(), cachedDevice);
@@ -252,7 +173,8 @@
     void initDevicePreference(BluetoothDevicePreference preference) { }
 
     public void onDeviceDeleted(CachedBluetoothDevice cachedDevice) {
-        BluetoothDevicePreference preference = mDevicePreferenceMap.remove(cachedDevice);
+        BluetoothDevicePreference preference = mDevicePreferenceMap.remove(
+                cachedDevice);
         if (preference != null) {
             mDeviceList.removePreference(preference);
         }
@@ -268,15 +190,9 @@
         }
     }
 
-    void onBluetoothStateChanged(int bluetoothState) {
+    public void onBluetoothStateChanged(int bluetoothState) {
         if (bluetoothState == BluetoothAdapter.STATE_OFF) {
             updateProgressUi(false);
         }
     }
-
-    void sendDevicePickedIntent(BluetoothDevice device) {
-        Intent intent = new Intent(BluetoothDevicePicker.ACTION_DEVICE_SELECTED);
-        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
-        getActivity().sendBroadcast(intent);
-    }
 }
diff --git a/src/com/android/settings/bluetooth/DevicePickerActivity.java b/src/com/android/settings/bluetooth/DevicePickerActivity.java
index c29fafb..8f6e0df 100644
--- a/src/com/android/settings/bluetooth/DevicePickerActivity.java
+++ b/src/com/android/settings/bluetooth/DevicePickerActivity.java
@@ -25,7 +25,7 @@
  * Activity for Bluetooth device picker dialog. The device picker logic
  * is implemented in the {@link BluetoothSettings} fragment.
  */
-public class DevicePickerActivity extends Activity {
+public final class DevicePickerActivity extends Activity {
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
diff --git a/src/com/android/settings/bluetooth/DevicePickerFragment.java b/src/com/android/settings/bluetooth/DevicePickerFragment.java
index d3e3d69..126df02 100644
--- a/src/com/android/settings/bluetooth/DevicePickerFragment.java
+++ b/src/com/android/settings/bluetooth/DevicePickerFragment.java
@@ -16,12 +16,11 @@
 
 package com.android.settings.bluetooth;
 
-import android.app.Activity;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothDevicePicker;
 import android.content.Intent;
-import android.util.Log;
+import android.os.Bundle;
 
 import com.android.settings.R;
 
@@ -29,36 +28,42 @@
  * BluetoothSettings is the Settings screen for Bluetooth configuration and
  * connection management.
  */
-public class DevicePickerFragment extends DeviceListPreferenceFragment {
-
-    private static final String TAG = "BluetoothDevicePicker";
+public final class DevicePickerFragment extends DeviceListPreferenceFragment {
 
     private boolean mNeedAuth;
     private String mLaunchPackage;
     private String mLaunchClass;
 
-    void addPreferencesForActivity(Activity activity) {
-        Intent intent = activity.getIntent();
+    @Override
+    void addPreferencesForActivity() {
+        addPreferencesFromResource(R.xml.device_picker);
+
+        Intent intent = getActivity().getIntent();
         mNeedAuth = intent.getBooleanExtra(BluetoothDevicePicker.EXTRA_NEED_AUTH, false);
-        mFilterType = intent.getIntExtra(BluetoothDevicePicker.EXTRA_FILTER_TYPE,
-                BluetoothDevicePicker.FILTER_TYPE_ALL);
+        setFilter(intent.getIntExtra(BluetoothDevicePicker.EXTRA_FILTER_TYPE,
+                BluetoothDevicePicker.FILTER_TYPE_ALL));
         mLaunchPackage = intent.getStringExtra(BluetoothDevicePicker.EXTRA_LAUNCH_PACKAGE);
         mLaunchClass = intent.getStringExtra(BluetoothDevicePicker.EXTRA_LAUNCH_CLASS);
+    }
 
-        activity.setTitle(activity.getString(R.string.device_picker));
-        addPreferencesFromResource(R.xml.device_picker);
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        getActivity().setTitle(getString(R.string.device_picker));
     }
 
     @Override
     public void onResume() {
         super.onResume();
         addDevices();
-        mLocalManager.startScanning(true);
+        mLocalAdapter.startScanning(true);
     }
 
+    @Override
     void onDevicePreferenceClick(BluetoothDevicePreference btPreference) {
-        mLocalManager.stopScanning();
-        mLocalManager.persistSelectedDeviceInPicker(mSelectedDevice.getAddress());
+        mLocalAdapter.stopScanning();
+        LocalBluetoothPreferences.persistSelectedDeviceInPicker(
+                getActivity(), mSelectedDevice.getAddress());
         if ((btPreference.getCachedDevice().getBondState() ==
                 BluetoothDevice.BOND_BONDED) || !mNeedAuth) {
             sendDevicePickedIntent(mSelectedDevice);
@@ -79,15 +84,16 @@
         }
     }
 
-    void onBluetoothStateChanged(int bluetoothState) {
+    @Override
+    public void onBluetoothStateChanged(int bluetoothState) {
         super.onBluetoothStateChanged(bluetoothState);
 
         if (bluetoothState == BluetoothAdapter.STATE_ON) {
-                mLocalManager.startScanning(false);
+                mLocalAdapter.startScanning(false);
         }
     }
 
-    void sendDevicePickedIntent(BluetoothDevice device) {
+    private void sendDevicePickedIntent(BluetoothDevice device) {
         Intent intent = new Intent(BluetoothDevicePicker.ACTION_DEVICE_SELECTED);
         intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
         if (mLaunchPackage != null && mLaunchClass != null) {
diff --git a/src/com/android/settings/bluetooth/DeviceProfilesSettings.java b/src/com/android/settings/bluetooth/DeviceProfilesSettings.java
index f39eabd..307125c 100644
--- a/src/com/android/settings/bluetooth/DeviceProfilesSettings.java
+++ b/src/com/android/settings/bluetooth/DeviceProfilesSettings.java
@@ -16,15 +16,12 @@
 
 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.BluetoothClass;
+import android.app.AlertDialog;
 import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothUuid;
+import android.bluetooth.BluetoothProfile;
+import android.content.Context;
+import android.content.DialogInterface;
 import android.os.Bundle;
-import android.os.ParcelUuid;
 import android.preference.CheckBoxPreference;
 import android.preference.EditTextPreference;
 import android.preference.Preference;
@@ -34,6 +31,9 @@
 import android.util.Log;
 import android.view.View;
 
+import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
+
 import java.util.HashMap;
 
 /**
@@ -41,7 +41,7 @@
  * for a particular device, and allows them to be individually connected
  * (or disconnected).
  */
-public class DeviceProfilesSettings extends SettingsPreferenceFragment
+public final class DeviceProfilesSettings extends SettingsPreferenceFragment
         implements CachedBluetoothDevice.Callback, Preference.OnPreferenceChangeListener,
                 View.OnClickListener {
     private static final String TAG = "DeviceProfilesSettings";
@@ -56,11 +56,15 @@
 
     private LocalBluetoothManager mManager;
     private CachedBluetoothDevice mCachedDevice;
+    private LocalBluetoothProfileManager mProfileManager;
 
     private PreferenceGroup mProfileContainer;
     private EditTextPreference mDeviceNamePref;
-    private final HashMap<String,CheckBoxPreference> mAutoConnectPrefs
-            = new HashMap<String,CheckBoxPreference>();
+
+    private final HashMap<LocalBluetoothProfile, CheckBoxPreference> mAutoConnectPrefs
+            = new HashMap<LocalBluetoothProfile, CheckBoxPreference>();
+
+    private AlertDialog mDisconnectDialog;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
@@ -74,51 +78,54 @@
             device = args.getParcelable(EXTRA_DEVICE);
         }
 
+        addPreferencesFromResource(R.xml.bluetooth_device_advanced);
+        getPreferenceScreen().setOrderingAsAdded(false);
+        mProfileContainer = (PreferenceGroup) findPreference(KEY_PROFILE_CONTAINER);
+        mDeviceNamePref = (EditTextPreference) findPreference(KEY_RENAME_DEVICE);
+
         if (device == null) {
             Log.w(TAG, "Activity started without a remote Bluetooth device");
             finish();
-            return;
+            return;  // TODO: test this failure path
         }
 
         mManager = LocalBluetoothManager.getInstance(getActivity());
-        mCachedDevice = mManager.getCachedDeviceManager().findDevice(device);
+        CachedBluetoothDeviceManager deviceManager =
+                mManager.getCachedDeviceManager();
+        mProfileManager = mManager.getProfileManager();
+        mCachedDevice = deviceManager.findDevice(device);
         if (mCachedDevice == null) {
             Log.w(TAG, "Device not found, cannot connect to it");
             finish();
-            return;
+            return;  // TODO: test this failure path
         }
 
-        addPreferencesFromResource(R.xml.bluetooth_device_advanced);
-        getPreferenceScreen().setOrderingAsAdded(false);
-
-        mProfileContainer = (PreferenceGroup) findPreference(KEY_PROFILE_CONTAINER);
-
-        mDeviceNamePref = (EditTextPreference) findPreference(KEY_RENAME_DEVICE);
-        mDeviceNamePref.setSummary(mCachedDevice.getName());
-        mDeviceNamePref.setText(mCachedDevice.getName());
+        String deviceName = mCachedDevice.getName();
+        mDeviceNamePref.setSummary(deviceName);
+        mDeviceNamePref.setText(deviceName);
         mDeviceNamePref.setOnPreferenceChangeListener(this);
 
         // Set the title of the screen
-        findPreference(KEY_TITLE).setTitle(getResources()
-                .getString(R.string.bluetooth_device_advanced_title, mCachedDevice.getName()));
+        findPreference(KEY_TITLE).setTitle(
+                getString(R.string.bluetooth_device_advanced_title,
+                        deviceName));
 
         // Add a preference for each profile
         addPreferencesForProfiles();
     }
 
-    private boolean isObjectPushSupported(BluetoothDevice device) {
-        ParcelUuid[] uuids = device.getUuids();
-        BluetoothClass bluetoothClass = device.getBluetoothClass();
-        return (uuids != null && BluetoothUuid.containsAnyUuid(uuids,
-                LocalBluetoothProfileManager.OPP_PROFILE_UUIDS)) ||
-                (bluetoothClass != null && bluetoothClass.doesClassMatch(
-                        BluetoothClass.PROFILE_OPP));
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        if (mDisconnectDialog != null) {
+            mDisconnectDialog.dismiss();
+            mDisconnectDialog = null;
+        }
     }
 
     @Override
     public void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
-
         outState.putParcelable(EXTRA_DEVICE, mCachedDevice.getDevice());
     }
 
@@ -141,7 +148,7 @@
     }
 
     private void addPreferencesForProfiles() {
-        for (Profile profile : mCachedDevice.getConnectableProfiles()) {
+        for (LocalBluetoothProfile profile : mCachedDevice.getConnectableProfiles()) {
             Preference pref = createProfilePreference(profile);
             mProfileContainer.addPreference(pref);
         }
@@ -155,21 +162,18 @@
      * @return A preference that allows the user to choose whether this profile
      *         will be connected to.
      */
-    private Preference createProfilePreference(Profile profile) {
+    private Preference createProfilePreference(LocalBluetoothProfile profile) {
         BluetoothProfilePreference pref = new BluetoothProfilePreference(getActivity(), profile);
         pref.setKey(profile.toString());
-        pref.setTitle(profile.localizedString);
+        pref.setTitle(profile.getNameResource());
         pref.setExpanded(false);
         pref.setPersistent(false);
-        pref.setOrder(getProfilePreferenceIndex(profile));
+        pref.setOrder(getProfilePreferenceIndex(profile.getOrdinal()));
         pref.setOnExpandClickListener(this);
 
-        LocalBluetoothProfileManager profileManager =
-                LocalBluetoothProfileManager.getProfileManager(mManager, profile);
-        int iconResource = profileManager.getDrawableResource();
+        int iconResource = profile.getDrawableResource(null);  // FIXME: get BT class for this?
         if (iconResource != 0) {
-            pref.setProfileDrawable(mManager.getContext()
-                    .getResources().getDrawable(iconResource));
+            pref.setProfileDrawable(getResources().getDrawable(iconResource));
         }
 
         /**
@@ -186,7 +190,7 @@
     public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) {
         String key = preference.getKey();
         if (preference instanceof BluetoothProfilePreference) {
-            onProfileClicked(Profile.valueOf(key));
+            onProfileClicked(mProfileManager.getProfileByName(key));
             return true;
         } else if (key.equals(KEY_UNPAIR)) {
             unpairDevice();
@@ -194,7 +198,7 @@
             return true;
         }
 
-        return false;
+        return super.onPreferenceTreeClick(screen, preference);
     }
 
     public boolean onPreferenceChange(Preference preference, Object newValue) {
@@ -202,10 +206,8 @@
             mCachedDevice.setName((String) newValue);
         } else if (preference instanceof CheckBoxPreference) {
             boolean autoConnect = (Boolean) newValue;
-            Profile prof = getProfileOf(preference);
-            LocalBluetoothProfileManager
-                    .getProfileManager(mManager, prof)
-                    .setPreferred(mCachedDevice.getDevice(),
+            LocalBluetoothProfile prof = getProfileOf(preference);
+            prof.setPreferred(mCachedDevice.getDevice(),
                             autoConnect);
             return true;
         } else {
@@ -215,22 +217,46 @@
         return true;
     }
 
-    private void onProfileClicked(Profile profile) {
+    private void onProfileClicked(LocalBluetoothProfile profile) {
         BluetoothDevice device = mCachedDevice.getDevice();
-        LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
-                .getProfileManager(mManager, profile);
 
-        int status = profileManager.getConnectionStatus(device);
+        int status = profile.getConnectionStatus(device);
         boolean isConnected =
-                SettingsBtStatus.isConnectionStatusConnected(status);
+                status == BluetoothProfile.STATE_CONNECTED;
 
         if (isConnected) {
-            mCachedDevice.askDisconnect(profile);
+            askDisconnect(getActivity(), profile);
         } else {
-            mCachedDevice.connect(profile);
+            mCachedDevice.connectProfile(profile);
         }
     }
 
+    private void askDisconnect(Context context,
+            final LocalBluetoothProfile profile) {
+        // local reference for callback
+        final CachedBluetoothDevice device = mCachedDevice;
+        String name = device.getName();
+        if (TextUtils.isEmpty(name)) {
+            name = context.getString(R.string.bluetooth_device);
+        }
+        int disconnectMessage = profile.getDisconnectResource();
+        if (disconnectMessage == 0) {
+            Log.w(TAG, "askDisconnect: unexpected profile " + profile);
+            disconnectMessage = R.string.bluetooth_disconnect_blank;
+        }
+        String message = context.getString(disconnectMessage, name);
+
+        DialogInterface.OnClickListener disconnectListener =
+                new DialogInterface.OnClickListener() {
+            public void onClick(DialogInterface dialog, int which) {
+                device.disconnect(profile);
+            }
+        };
+
+        mDisconnectDialog = Utils.showDisconnectDialog(context,
+                mDisconnectDialog, disconnectListener, name, message);
+    }
+
     public void onDeviceAttributesChanged() {
         refresh();
     }
@@ -242,7 +268,7 @@
 //        transaction.setBreadCrumbTitle(deviceName);
 //        transaction.commit();
 
-        findPreference(KEY_TITLE).setTitle(getResources().getString(
+        findPreference(KEY_TITLE).setTitle(getString(
                 R.string.bluetooth_device_advanced_title,
                 deviceName));
         mDeviceNamePref = (EditTextPreference) findPreference(KEY_RENAME_DEVICE);
@@ -253,7 +279,7 @@
     }
 
     private void refreshProfiles() {
-        for (Profile profile : mCachedDevice.getConnectableProfiles()) {
+        for (LocalBluetoothProfile profile : mCachedDevice.getConnectableProfiles()) {
             Preference profilePref = findPreference(profile.toString());
             if (profilePref == null) {
                 profilePref = createProfilePreference(profile);
@@ -264,78 +290,43 @@
         }
     }
 
-    private void refreshProfilePreference(Preference profilePref, Profile profile) {
+    private void refreshProfilePreference(Preference profilePref, LocalBluetoothProfile 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));
+        profilePref.setSummary(profile.getSummaryResourceForDevice(device));
     }
 
-    private Profile getProfileOf(Preference pref) {
-        if (!(pref instanceof CheckBoxPreference)) return null;
+    private LocalBluetoothProfile 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 mProfileManager.getProfileByName(pref.getKey());
+        } catch (IllegalArgumentException ignored) {
             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;
-            case PAN:
-                return R.string.bluetooth_pan_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 (v.getTag() instanceof LocalBluetoothProfile) {
+            LocalBluetoothProfile prof = (LocalBluetoothProfile) v.getTag();
+            CheckBoxPreference autoConnectPref = mAutoConnectPrefs.get(prof);
             if (autoConnectPref == null) {
                 autoConnectPref = new CheckBoxPreference(getActivity());
                 autoConnectPref.setLayoutResource(com.android.internal.R.layout.preference_child);
                 autoConnectPref.setKey(prof.toString());
                 autoConnectPref.setTitle(R.string.bluetooth_auto_connect);
-                autoConnectPref.setOrder(getProfilePreferenceIndex(prof) + 1);
+                autoConnectPref.setOrder(getProfilePreferenceIndex(prof.getOrdinal()) + 1);
                 autoConnectPref.setChecked(getAutoConnect(prof));
                 autoConnectPref.setOnPreferenceChangeListener(this);
-                mAutoConnectPrefs.put(prof.name(), autoConnectPref);
+                mAutoConnectPrefs.put(prof, autoConnectPref);
             }
             BluetoothProfilePreference profilePref =
                     (BluetoothProfilePreference) findPreference(prof.toString());
@@ -349,19 +340,14 @@
         }
     }
 
-    private int getProfilePreferenceIndex(Profile prof) {
-        return mProfileContainer.getOrder() + prof.ordinal() * 10;
+    private int getProfilePreferenceIndex(int profIndex) {
+        return mProfileContainer.getOrder() + profIndex * 10;
     }
 
     private void unpairDevice() {
         mCachedDevice.unpair();
     }
 
-    private boolean isDeviceOnline() {
-        // TODO: Verify
-        return mCachedDevice.isConnected() || mCachedDevice.isBusy();
-    }
-
     private void setIncomingFileTransfersAllowed(boolean allow) {
         // TODO: make an IPC call into BluetoothOpp to update
         Log.d(TAG, "Set allow incoming = " + allow);
@@ -372,8 +358,7 @@
         return true;
     }
 
-    private boolean getAutoConnect(Profile prof) {
-        return LocalBluetoothProfileManager.getProfileManager(mManager, prof)
-                .isPreferred(mCachedDevice.getDevice());
+    private boolean getAutoConnect(LocalBluetoothProfile prof) {
+        return prof.isPreferred(mCachedDevice.getDevice());
     }
 }
diff --git a/src/com/android/settings/bluetooth/DockEventReceiver.java b/src/com/android/settings/bluetooth/DockEventReceiver.java
index 0410998..6ecbef6 100644
--- a/src/com/android/settings/bluetooth/DockEventReceiver.java
+++ b/src/com/android/settings/bluetooth/DockEventReceiver.java
@@ -28,7 +28,7 @@
 import android.os.PowerManager;
 import android.util.Log;
 
-public class DockEventReceiver extends BroadcastReceiver {
+public final class DockEventReceiver extends BroadcastReceiver {
 
     private static final boolean DEBUG = DockService.DEBUG;
 
@@ -39,11 +39,9 @@
 
     private static final int EXTRA_INVALID = -1234;
 
-    private static final Object mStartingServiceSync = new Object();
+    private static final Object sStartingServiceSync = new Object();
 
-    private static final long WAKELOCK_TIMEOUT = 5000;
-
-    private static PowerManager.WakeLock mStartingService;
+    private static PowerManager.WakeLock sStartingService;
 
     @Override
     public void onReceive(Context context, Intent intent) {
@@ -75,7 +73,7 @@
                     beginStartingService(context, i);
                     break;
                 default:
-                    if (DEBUG) Log.e(TAG, "Unknown state");
+                    Log.e(TAG, "Unknown state: " + state);
                     break;
             }
         } else if (BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED.equals(intent.getAction()) ||
@@ -118,15 +116,15 @@
      * Start the service to process the current event notifications, acquiring
      * the wake lock before returning to ensure that the service will run.
      */
-    public static void beginStartingService(Context context, Intent intent) {
-        synchronized (mStartingServiceSync) {
-            if (mStartingService == null) {
+    private static void beginStartingService(Context context, Intent intent) {
+        synchronized (sStartingServiceSync) {
+            if (sStartingService == null) {
                 PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
-                mStartingService = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
+                sStartingService = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                         "StartingDockService");
             }
 
-            mStartingService.acquire(WAKELOCK_TIMEOUT);
+            sStartingService.acquire();
 
             if (context.startService(intent) == null) {
                 Log.e(TAG, "Can't start DockService");
@@ -139,10 +137,13 @@
      * releasing the wake lock if the service is now stopping.
      */
     public static void finishStartingService(Service service, int startId) {
-        synchronized (mStartingServiceSync) {
-            if (mStartingService != null) {
-                if (DEBUG) Log.d(TAG, "stopSelf id = "+ startId);
-                service.stopSelfResult(startId);
+        synchronized (sStartingServiceSync) {
+            if (sStartingService != null) {
+                if (DEBUG) Log.d(TAG, "stopSelf id = " + startId);
+                if (service.stopSelfResult(startId)) {
+                    Log.d(TAG, "finishStartingService: stopping service");
+                    sStartingService.release();
+                }
             }
         }
     }
diff --git a/src/com/android/settings/bluetooth/DockService.java b/src/com/android/settings/bluetooth/DockService.java
index 8104652..b457706 100644
--- a/src/com/android/settings/bluetooth/DockService.java
+++ b/src/com/android/settings/bluetooth/DockService.java
@@ -17,7 +17,6 @@
 package com.android.settings.bluetooth;
 
 import com.android.settings.R;
-import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
 import com.android.settings.bluetooth.LocalBluetoothProfileManager.ServiceListener;
 
 import android.app.AlertDialog;
@@ -27,7 +26,7 @@
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothHeadset;
-import android.content.Context;
+import android.bluetooth.BluetoothProfile;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -44,12 +43,11 @@
 import android.widget.CheckBox;
 import android.widget.CompoundButton;
 
+import java.util.Collection;
 import java.util.List;
 import java.util.Set;
 
-public class DockService extends Service implements AlertDialog.OnMultiChoiceClickListener,
-        DialogInterface.OnClickListener, DialogInterface.OnDismissListener,
-        CompoundButton.OnCheckedChangeListener, ServiceListener {
+public final class DockService extends Service implements ServiceListener {
 
     private static final String TAG = "DockService";
 
@@ -82,14 +80,11 @@
 
     private static final String SHARED_PREFERENCES_NAME = "dock_settings";
 
-    private static final String SHARED_PREFERENCES_KEY_DISABLE_BT_WHEN_UNDOCKED =
-        "disable_bt_when_undock";
+    private static final String KEY_DISABLE_BT_WHEN_UNDOCKED = "disable_bt_when_undock";
 
-    private static final String SHARED_PREFERENCES_KEY_DISABLE_BT =
-        "disable_bt";
+    private static final String KEY_DISABLE_BT = "disable_bt";
 
-    private static final String SHARED_PREFERENCES_KEY_CONNECT_RETRY_COUNT =
-        "connect_retry_count";
+    private static final String KEY_CONNECT_RETRY_COUNT = "connect_retry_count";
 
     /*
      * If disconnected unexpectedly, reconnect up to 6 times. Each profile counts
@@ -103,8 +98,9 @@
     private volatile Looper mServiceLooper;
     private volatile ServiceHandler mServiceHandler;
     private Runnable mRunnable;
-    private DockService mContext;
-    private LocalBluetoothManager mBtManager;
+    private LocalBluetoothAdapter mLocalAdapter;
+    private CachedBluetoothDeviceManager mDeviceManager;
+    private LocalBluetoothProfileManager mProfileManager;
 
     // Normally set after getting a docked event and unset when the connection
     // is severed. One exception is that mDevice could be null if the service
@@ -113,7 +109,7 @@
 
     // Created and used for the duration of the dialog
     private AlertDialog mDialog;
-    private Profile[] mProfiles;
+    private LocalBluetoothProfile[] mProfiles;
     private boolean[] mCheckedItems;
     private int mStartIdAssociatedWithDialog;
 
@@ -127,8 +123,19 @@
     public void onCreate() {
         if (DEBUG) Log.d(TAG, "onCreate");
 
-        mBtManager = LocalBluetoothManager.getInstance(this);
-        mContext = this;
+        LocalBluetoothManager manager = LocalBluetoothManager.getInstance(this);
+        if (manager == null) {
+            Log.e(TAG, "Can't get LocalBluetoothManager: exiting");
+            return;
+        }
+
+        mLocalAdapter = manager.getBluetoothAdapter();
+        mDeviceManager = manager.getCachedDeviceManager();
+        mProfileManager = manager.getProfileManager();
+        if (mProfileManager == null) {
+            Log.e(TAG, "Can't get LocalBluetoothProfileManager: exiting");
+            return;
+        }
 
         HandlerThread thread = new HandlerThread("DockService");
         thread.start();
@@ -141,12 +148,22 @@
     public void onDestroy() {
         if (DEBUG) Log.d(TAG, "onDestroy");
         mRunnable = null;
-        LocalBluetoothProfileManager.removeServiceListener(this);
         if (mDialog != null) {
             mDialog.dismiss();
             mDialog = null;
         }
-        mServiceLooper.quit();
+        if (mProfileManager != null) {
+            mProfileManager.removeServiceListener(this);
+        }
+        if (mServiceLooper != null) {
+            mServiceLooper.quit();
+        }
+
+        mLocalAdapter = null;
+        mDeviceManager = null;
+        mProfileManager = null;
+        mServiceLooper = null;
+        mServiceHandler = null;
     }
 
     @Override
@@ -155,9 +172,13 @@
         return null;
     }
 
+    private SharedPreferences getPrefs() {
+        return getSharedPreferences(SHARED_PREFERENCES_NAME, MODE_PRIVATE);
+    }
+
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
-        if (DEBUG) Log.d(TAG, "onStartCommand startId:" + startId + " flags: " + flags);
+        if (DEBUG) Log.d(TAG, "onStartCommand startId: " + startId + " flags: " + flags);
 
         if (intent == null) {
             // Nothing to process, stop.
@@ -178,24 +199,24 @@
          * This assumes that the intent sender has checked that this is a dock
          * and that the intent is for a disconnect
          */
+        final SharedPreferences prefs = getPrefs();
         if (BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED.equals(intent.getAction())) {
             BluetoothDevice disconnectedDevice = intent
                     .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
-
-            int retryCount = getSettingInt(SHARED_PREFERENCES_KEY_CONNECT_RETRY_COUNT, 0);
+            int retryCount = prefs.getInt(KEY_CONNECT_RETRY_COUNT, 0);
             if (retryCount < MAX_CONNECT_RETRY) {
-                setSettingInt(SHARED_PREFERENCES_KEY_CONNECT_RETRY_COUNT, retryCount + 1);
-                handleUnexpectedDisconnect(disconnectedDevice, Profile.HEADSET, startId);
+                prefs.edit().putInt(KEY_CONNECT_RETRY_COUNT, retryCount + 1).apply();
+                handleUnexpectedDisconnect(disconnectedDevice, mProfileManager.getHeadsetProfile(), startId);
             }
             return START_NOT_STICKY;
         } else if (BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED.equals(intent.getAction())) {
             BluetoothDevice disconnectedDevice = intent
                     .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
 
-            int retryCount = getSettingInt(SHARED_PREFERENCES_KEY_CONNECT_RETRY_COUNT, 0);
+            int retryCount = prefs.getInt(KEY_CONNECT_RETRY_COUNT, 0);
             if (retryCount < MAX_CONNECT_RETRY) {
-                setSettingInt(SHARED_PREFERENCES_KEY_CONNECT_RETRY_COUNT, retryCount + 1);
-                handleUnexpectedDisconnect(disconnectedDevice, Profile.A2DP, startId);
+                prefs.edit().putInt(KEY_CONNECT_RETRY_COUNT, retryCount + 1).apply();
+                handleUnexpectedDisconnect(disconnectedDevice, mProfileManager.getA2dpProfile(), startId);
             }
             return START_NOT_STICKY;
         }
@@ -209,7 +230,7 @@
         }
 
         if (msg.what == MSG_TYPE_DOCKED) {
-            removeSetting(SHARED_PREFERENCES_KEY_CONNECT_RETRY_COUNT);
+            prefs.edit().remove(KEY_CONNECT_RETRY_COUNT).apply();
         }
 
         msg.arg2 = startId;
@@ -219,7 +240,7 @@
     }
 
     private final class ServiceHandler extends Handler {
-        public ServiceHandler(Looper looper) {
+        private ServiceHandler(Looper looper) {
             super(looper);
         }
 
@@ -234,7 +255,6 @@
         int msgType = msg.what;
         final int state = msg.arg1;
         final int startId = msg.arg2;
-        boolean deferFinishCall = false;
         BluetoothDevice device = null;
         if (msg.obj != null) {
             device = (BluetoothDevice) msg.obj;
@@ -243,102 +263,27 @@
         if(DEBUG) Log.d(TAG, "processMessage: " + msgType + " state: " + state + " device = "
                 + (device == null ? "null" : device.toString()));
 
+        boolean deferFinishCall = false;
+
         switch (msgType) {
             case MSG_TYPE_SHOW_UI:
-                if (mDialog != null) {
-                    // Shouldn't normally happen
-                    mDialog.dismiss();
-                    mDialog = null;
-                }
-                mDevice = device;
-                createDialog(mContext, mDevice, state, startId);
+                createDialog(device, state, startId);
                 break;
 
             case MSG_TYPE_DOCKED:
-                if (DEBUG) {
-                    // TODO figure out why hasMsg always returns false if device
-                    // is supplied
-                    Log.d(TAG, "1 Has undock perm msg = "
-                            + mServiceHandler.hasMessages(MSG_TYPE_UNDOCKED_PERMANENT, mDevice));
-                    Log.d(TAG, "2 Has undock perm msg = "
-                            + mServiceHandler.hasMessages(MSG_TYPE_UNDOCKED_PERMANENT, device));
-                }
-
-                mServiceHandler.removeMessages(MSG_TYPE_UNDOCKED_PERMANENT);
-                mServiceHandler.removeMessages(MSG_TYPE_DISABLE_BT);
-                removeSetting(SHARED_PREFERENCES_KEY_DISABLE_BT);
-
-                if (!device.equals(mDevice)) {
-                    if (mDevice != null) {
-                        // Not expected. Cleanup/undock existing
-                        handleUndocked(mContext, mBtManager, mDevice);
-                    }
-
-                    mDevice = device;
-
-                    // Register first in case LocalBluetoothProfileManager
-                    // becomes ready after isManagerReady is called and it
-                    // would be too late to register a service listener.
-                    LocalBluetoothProfileManager.addServiceListener(this);
-                    if (LocalBluetoothProfileManager.isManagerReady()) {
-                        handleDocked(device, state, startId);
-                        // Not needed after all
-                        LocalBluetoothProfileManager.removeServiceListener(this);
-                    } else {
-                        final BluetoothDevice d = device;
-                        mRunnable = new Runnable() {
-                            public void run() {
-                                handleDocked(d, state, startId);
-                            }
-                        };
-                        deferFinishCall = true;
-                    }
-                }
+                deferFinishCall = msgTypeDocked(device, state, startId);
                 break;
 
             case MSG_TYPE_UNDOCKED_PERMANENT:
-                // Grace period passed. Disconnect.
-                handleUndocked(mContext, mBtManager, device);
-
-                if (DEBUG) {
-                    Log.d(TAG, "DISABLE_BT_WHEN_UNDOCKED = "
-                            + getSettingBool(SHARED_PREFERENCES_KEY_DISABLE_BT_WHEN_UNDOCKED));
-                }
-
-                if (getSettingBool(SHARED_PREFERENCES_KEY_DISABLE_BT_WHEN_UNDOCKED)) {
-                    // BT was disabled when we first docked
-                    if (!hasOtherConnectedDevices(device)) {
-                        if(DEBUG) Log.d(TAG, "QUEUED BT DISABLE");
-                        // Queue a delayed msg to disable BT
-                        Message newMsg = mServiceHandler.obtainMessage(MSG_TYPE_DISABLE_BT, 0,
-                                startId, null);
-                        mServiceHandler.sendMessageDelayed(newMsg, DISABLE_BT_GRACE_PERIOD);
-                        deferFinishCall = true;
-                    } else {
-                        // Don't disable BT if something is connected
-                        removeSetting(SHARED_PREFERENCES_KEY_DISABLE_BT_WHEN_UNDOCKED);
-                    }
-                }
+                deferFinishCall = msgTypeUndockedPermanent(device, startId);
                 break;
 
             case MSG_TYPE_UNDOCKED_TEMPORARY:
-                // Undocked event received. Queue a delayed msg to sever connection
-                Message newMsg = mServiceHandler.obtainMessage(MSG_TYPE_UNDOCKED_PERMANENT, state,
-                        startId, device);
-                mServiceHandler.sendMessageDelayed(newMsg, UNDOCKED_GRACE_PERIOD);
+                msgTypeUndockedTemporary(device, state, startId);
                 break;
 
             case MSG_TYPE_DISABLE_BT:
-                if(DEBUG) Log.d(TAG, "BT DISABLE");
-                if (mBtManager.getBluetoothAdapter().disable()) {
-                    removeSetting(SHARED_PREFERENCES_KEY_DISABLE_BT_WHEN_UNDOCKED);
-                } else {
-                    // disable() returned an error. Persist a flag to disable BT later
-                    setSettingBool(SHARED_PREFERENCES_KEY_DISABLE_BT, true);
-                    mPendingTurnOffStartId = startId;
-                    deferFinishCall = true;
-                    if(DEBUG) Log.d(TAG, "disable failed. try again later " + startId);
-                }
+                deferFinishCall = msgTypeDisableBluetooth(startId);
                 break;
         }
 
@@ -346,24 +291,127 @@
                 && !deferFinishCall) {
             // NOTE: We MUST not call stopSelf() directly, since we need to
             // make sure the wake lock acquired by the Receiver is released.
-            DockEventReceiver.finishStartingService(DockService.this, startId);
+            DockEventReceiver.finishStartingService(this, startId);
         }
     }
 
-    public synchronized boolean hasOtherConnectedDevices(BluetoothDevice dock) {
-        List<CachedBluetoothDevice> cachedDevices = mBtManager.getCachedDeviceManager()
-                .getCachedDevicesCopy();
-        Set<BluetoothDevice> btDevices = mBtManager.getBluetoothAdapter().getBondedDevices();
-        if (btDevices == null || cachedDevices == null || btDevices.size() == 0) {
+    private boolean msgTypeDisableBluetooth(int startId) {
+        if (DEBUG) {
+            Log.d(TAG, "BT DISABLE");
+        }
+        final SharedPreferences prefs = getPrefs();
+        if (mLocalAdapter.disable()) {
+            prefs.edit().remove(KEY_DISABLE_BT_WHEN_UNDOCKED).apply();
+            return false;
+        } else {
+            // disable() returned an error. Persist a flag to disable BT later
+            prefs.edit().putBoolean(KEY_DISABLE_BT, true).apply();
+            mPendingTurnOffStartId = startId;
+            if(DEBUG) {
+                Log.d(TAG, "disable failed. try again later " + startId);
+            }
+            return true;
+        }
+    }
+
+    private void msgTypeUndockedTemporary(BluetoothDevice device, int state,
+            int startId) {
+        // Undocked event received. Queue a delayed msg to sever connection
+        Message newMsg = mServiceHandler.obtainMessage(MSG_TYPE_UNDOCKED_PERMANENT, state,
+                startId, device);
+        mServiceHandler.sendMessageDelayed(newMsg, UNDOCKED_GRACE_PERIOD);
+    }
+
+    private boolean msgTypeUndockedPermanent(BluetoothDevice device, int startId) {
+        // Grace period passed. Disconnect.
+        handleUndocked(device);
+        final SharedPreferences prefs = getPrefs();
+
+        if (DEBUG) {
+            Log.d(TAG, "DISABLE_BT_WHEN_UNDOCKED = "
+                    + prefs.getBoolean(KEY_DISABLE_BT_WHEN_UNDOCKED, false));
+        }
+
+        if (prefs.getBoolean(KEY_DISABLE_BT_WHEN_UNDOCKED, false)) {
+            if (hasOtherConnectedDevices(device)) {
+                // Don't disable BT if something is connected
+                prefs.edit().remove(KEY_DISABLE_BT_WHEN_UNDOCKED).apply();
+            } else {
+                // BT was disabled when we first docked
+                if (DEBUG) {
+                    Log.d(TAG, "QUEUED BT DISABLE");
+                }
+                // Queue a delayed msg to disable BT
+                Message newMsg = mServiceHandler.obtainMessage(
+                        MSG_TYPE_DISABLE_BT, 0, startId, null);
+                mServiceHandler.sendMessageDelayed(newMsg,
+                        DISABLE_BT_GRACE_PERIOD);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean msgTypeDocked(BluetoothDevice device, final int state,
+            final int startId) {
+        if (DEBUG) {
+            // TODO figure out why hasMsg always returns false if device
+            // is supplied
+            Log.d(TAG, "1 Has undock perm msg = "
+                    + mServiceHandler.hasMessages(MSG_TYPE_UNDOCKED_PERMANENT, mDevice));
+            Log.d(TAG, "2 Has undock perm msg = "
+                    + mServiceHandler.hasMessages(MSG_TYPE_UNDOCKED_PERMANENT, device));
+        }
+
+        mServiceHandler.removeMessages(MSG_TYPE_UNDOCKED_PERMANENT);
+        mServiceHandler.removeMessages(MSG_TYPE_DISABLE_BT);
+        getPrefs().edit().remove(KEY_DISABLE_BT).apply();
+
+        if (device != null && !device.equals(mDevice)) {
+            if (mDevice != null) {
+                // Not expected. Cleanup/undock existing
+                handleUndocked(mDevice);
+            }
+
+            mDevice = device;
+
+            // Register first in case LocalBluetoothProfileManager
+            // becomes ready after isManagerReady is called and it
+            // would be too late to register a service listener.
+            mProfileManager.addServiceListener(this);
+            if (mProfileManager.isManagerReady()) {
+                handleDocked(device, state, startId);
+                // Not needed after all
+                mProfileManager.removeServiceListener(this);
+            } else {
+                final BluetoothDevice d = device;
+                mRunnable = new Runnable() {
+                    public void run() {
+                        handleDocked(d, state, startId);  // FIXME: WTF runnable here?
+                    }
+                };
+                return true;
+            }
+        }
+        return false;
+    }
+
+    synchronized boolean hasOtherConnectedDevices(BluetoothDevice dock) {
+        Collection<CachedBluetoothDevice> cachedDevices = mDeviceManager.getCachedDevicesCopy();
+        Set<BluetoothDevice> btDevices = mLocalAdapter.getBondedDevices();
+        if (btDevices == null || cachedDevices == null || btDevices.isEmpty()) {
             return false;
         }
-        if(DEBUG) Log.d(TAG, "btDevices = " + btDevices.size());
-        if(DEBUG) Log.d(TAG, "cachedDevices = " + cachedDevices.size());
+        if(DEBUG) {
+            Log.d(TAG, "btDevices = " + btDevices.size());
+            Log.d(TAG, "cachedDeviceUIs = " + cachedDevices.size());
+        }
 
-        for (CachedBluetoothDevice device : cachedDevices) {
-            BluetoothDevice btDevice = device.getDevice();
-            if (!btDevice.equals(dock) && btDevices.contains(btDevice) && device.isConnected()) {
-                if(DEBUG) Log.d(TAG, "connected device = " + device.getName());
+        for (CachedBluetoothDevice deviceUI : cachedDevices) {
+            BluetoothDevice btDevice = deviceUI.getDevice();
+            if (!btDevice.equals(dock) && btDevices.contains(btDevice) && deviceUI
+                    .isConnected()) {
+                if(DEBUG) Log.d(TAG, "connected deviceUI = " + deviceUI.getName());
                 return true;
             }
         }
@@ -404,96 +452,128 @@
         return mServiceHandler.obtainMessage(msgType, state, 0, device);
     }
 
-    private boolean createDialog(DockService service, BluetoothDevice device, int state,
-            int startId) {
+    private void createDialog(BluetoothDevice device,
+            int state, int startId) {
+        if (mDialog != null) {
+            // Shouldn't normally happen
+            mDialog.dismiss();
+            mDialog = null;
+        }
+        mDevice = device;
         switch (state) {
             case Intent.EXTRA_DOCK_STATE_CAR:
             case Intent.EXTRA_DOCK_STATE_DESK:
                 break;
             default:
-                return false;
+                return;
         }
 
         startForeground(0, new Notification());
 
         // Device in a new dock.
-        boolean firstTime = !mBtManager.hasDockAutoConnectSetting(device.getAddress());
+        boolean firstTime = !LocalBluetoothPreferences.hasDockAutoConnectSetting(this, device.getAddress());
 
-        CharSequence[] items = initBtSettings(service, device, state, firstTime);
+        CharSequence[] items = initBtSettings(device, state, firstTime);
 
-        final AlertDialog.Builder ab = new AlertDialog.Builder(service);
-        ab.setTitle(service.getString(R.string.bluetooth_dock_settings_title));
+        final AlertDialog.Builder ab = new AlertDialog.Builder(this);
+        ab.setTitle(getString(R.string.bluetooth_dock_settings_title));
 
         // Profiles
-        ab.setMultiChoiceItems(items, mCheckedItems, service);
+        ab.setMultiChoiceItems(items, mCheckedItems, mMultiClickListener);
 
         // Remember this settings
-        LayoutInflater inflater = (LayoutInflater) service
-                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-        float pixelScaleFactor = service.getResources().getDisplayMetrics().density;
+        LayoutInflater inflater = (LayoutInflater)
+                getSystemService(LAYOUT_INFLATER_SERVICE);
+        float pixelScaleFactor = getResources().getDisplayMetrics().density;
         View view = inflater.inflate(R.layout.remember_dock_setting, null);
         CheckBox rememberCheckbox = (CheckBox) view.findViewById(R.id.remember);
 
         // check "Remember setting" by default if no value was saved
-        boolean checked = firstTime || mBtManager.getDockAutoConnectSetting(device.getAddress());
+        boolean checked = firstTime || LocalBluetoothPreferences.getDockAutoConnectSetting(this, device.getAddress());
         rememberCheckbox.setChecked(checked);
-        rememberCheckbox.setOnCheckedChangeListener(this);
+        rememberCheckbox.setOnCheckedChangeListener(mCheckedChangeListener);
         int viewSpacingLeft = (int) (14 * pixelScaleFactor);
         int viewSpacingRight = (int) (14 * pixelScaleFactor);
         ab.setView(view, viewSpacingLeft, 0 /* top */, viewSpacingRight, 0 /* bottom */);
         if (DEBUG) {
             Log.d(TAG, "Auto connect = "
-                    + mBtManager.getDockAutoConnectSetting(device.getAddress()));
+                    + LocalBluetoothPreferences.getDockAutoConnectSetting(this, device.getAddress()));
         }
 
         // Ok Button
-        ab.setPositiveButton(service.getString(android.R.string.ok), service);
+        ab.setPositiveButton(getString(android.R.string.ok), mClickListener);
 
         mStartIdAssociatedWithDialog = startId;
         mDialog = ab.create();
         mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
-        mDialog.setOnDismissListener(service);
+        mDialog.setOnDismissListener(mDismissListener);
         mDialog.show();
-        return true;
     }
 
     // Called when the individual bt profiles are clicked.
-    public void onClick(DialogInterface dialog, int which, boolean isChecked) {
-        if (DEBUG) Log.d(TAG, "Item " + which + " changed to " + isChecked);
-        mCheckedItems[which] = isChecked;
-    }
+    private final DialogInterface.OnMultiChoiceClickListener mMultiClickListener =
+            new DialogInterface.OnMultiChoiceClickListener() {
+                public void onClick(DialogInterface dialog, int which, boolean isChecked) {
+                    if (DEBUG) {
+                        Log.d(TAG, "Item " + which + " changed to " + isChecked);
+                    }
+                    mCheckedItems[which] = isChecked;
+                }
+            };
+
 
     // Called when the "Remember" Checkbox is clicked
-    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
-        if (DEBUG) Log.d(TAG, "onCheckedChanged: Remember Settings = " + isChecked);
-        if (mDevice != null) {
-            mBtManager.saveDockAutoConnectSetting(mDevice.getAddress(), isChecked);
-        }
-    }
+    private final CompoundButton.OnCheckedChangeListener mCheckedChangeListener =
+            new CompoundButton.OnCheckedChangeListener() {
+                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+                    if (DEBUG) {
+                        Log.d(TAG, "onCheckedChanged: Remember Settings = " + isChecked);
+                    }
+                    if (mDevice != null) {
+                        LocalBluetoothPreferences.saveDockAutoConnectSetting(
+                                DockService.this, mDevice.getAddress(), isChecked);
+                    }
+                }
+            };
+
 
     // Called when the dialog is dismissed
-    public void onDismiss(DialogInterface dialog) {
-        // NOTE: We MUST not call stopSelf() directly, since we need to
-        // make sure the wake lock acquired by the Receiver is released.
-        if (mPendingDevice == null) {
-            DockEventReceiver.finishStartingService(mContext, mStartIdAssociatedWithDialog);
-        }
-        mContext.stopForeground(true);
-    }
+    private final DialogInterface.OnDismissListener mDismissListener =
+            new DialogInterface.OnDismissListener() {
+                public void onDismiss(DialogInterface dialog) {
+                    // NOTE: We MUST not call stopSelf() directly, since we need to
+                    // make sure the wake lock acquired by the Receiver is released.
+                    if (mPendingDevice == null) {
+                        DockEventReceiver.finishStartingService(
+                                DockService.this, mStartIdAssociatedWithDialog);
+                    }
+                    stopForeground(true);
+                }
+            };
 
     // Called when clicked on the OK button
-    public void onClick(DialogInterface dialog, int which) {
-        if (which == DialogInterface.BUTTON_POSITIVE && mDevice != null) {
-            if (!mBtManager.hasDockAutoConnectSetting(mDevice.getAddress())) {
-                mBtManager.saveDockAutoConnectSetting(mDevice.getAddress(), true);
-            }
+    private final DialogInterface.OnClickListener mClickListener =
+            new DialogInterface.OnClickListener() {
+                public void onClick(DialogInterface dialog, int which) {
+                    if (which == DialogInterface.BUTTON_POSITIVE
+                            && mDevice != null) {
+                        if (!LocalBluetoothPreferences
+                                .hasDockAutoConnectSetting(
+                                        DockService.this,
+                                        mDevice.getAddress())) {
+                            LocalBluetoothPreferences
+                                    .saveDockAutoConnectSetting(
+                                            DockService.this,
+                                            mDevice.getAddress(), true);
+                        }
 
-            applyBtSettings(mDevice, mStartIdAssociatedWithDialog);
-        }
-    }
+                        applyBtSettings(mDevice, mStartIdAssociatedWithDialog);
+                    }
+                }
+            };
 
-    private CharSequence[] initBtSettings(DockService service, BluetoothDevice device, int state,
-            boolean firstTime) {
+    private CharSequence[] initBtSettings(BluetoothDevice device,
+            int state, boolean firstTime) {
         // TODO Avoid hardcoding dock and profiles. Read from system properties
         int numOfProfiles;
         switch (state) {
@@ -507,96 +587,54 @@
                 return null;
         }
 
-        mProfiles = new Profile[numOfProfiles];
+        mProfiles = new LocalBluetoothProfile[numOfProfiles];
         mCheckedItems = new boolean[numOfProfiles];
         CharSequence[] items = new CharSequence[numOfProfiles];
 
+        // FIXME: convert switch to something else
         switch (state) {
             case Intent.EXTRA_DOCK_STATE_CAR:
-                items[0] = service.getString(R.string.bluetooth_dock_settings_headset);
-                items[1] = service.getString(R.string.bluetooth_dock_settings_a2dp);
-                mProfiles[0] = Profile.HEADSET;
-                mProfiles[1] = Profile.A2DP;
+                items[0] = getString(R.string.bluetooth_dock_settings_headset);
+                items[1] = getString(R.string.bluetooth_dock_settings_a2dp);
+                mProfiles[0] = mProfileManager.getHeadsetProfile();
+                mProfiles[1] = mProfileManager.getA2dpProfile();
                 if (firstTime) {
                     // Enable by default for car dock
                     mCheckedItems[0] = true;
                     mCheckedItems[1] = true;
                 } else {
-                    mCheckedItems[0] = LocalBluetoothProfileManager.getProfileManager(mBtManager,
-                            Profile.HEADSET).isPreferred(device);
-                    mCheckedItems[1] = LocalBluetoothProfileManager.getProfileManager(mBtManager,
-                            Profile.A2DP).isPreferred(device);
+                    mCheckedItems[0] = mProfiles[0].isPreferred(device);
+                    mCheckedItems[1] = mProfiles[1].isPreferred(device);
                 }
                 break;
 
             case Intent.EXTRA_DOCK_STATE_DESK:
-                items[0] = service.getString(R.string.bluetooth_dock_settings_a2dp);
-                mProfiles[0] = Profile.A2DP;
+                items[0] = getString(R.string.bluetooth_dock_settings_a2dp);
+                mProfiles[0] = mProfileManager.getA2dpProfile();
                 if (firstTime) {
                     // Disable by default for desk dock
                     mCheckedItems[0] = false;
                 } else {
-                    mCheckedItems[0] = LocalBluetoothProfileManager.getProfileManager(mBtManager,
-                            Profile.A2DP).isPreferred(device);
+                    mCheckedItems[0] = mProfiles[0].isPreferred(device);
                 }
                 break;
         }
         return items;
     }
 
+    // TODO: move to background thread to fix strict mode warnings
     private void handleBtStateChange(Intent intent, int startId) {
         int btState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
         synchronized (this) {
             if(DEBUG) Log.d(TAG, "BtState = " + btState + " mPendingDevice = " + mPendingDevice);
             if (btState == BluetoothAdapter.STATE_ON) {
-                if (mPendingDevice != null) {
-                    if (mPendingDevice.equals(mDevice)) {
-                        if(DEBUG) Log.d(TAG, "applying settings");
-                        applyBtSettings(mPendingDevice, mPendingStartId);
-                    } else if(DEBUG) {
-                        Log.d(TAG, "mPendingDevice  (" + mPendingDevice + ") != mDevice ("
-                                + mDevice + ")");
-                    }
-
-                    mPendingDevice = null;
-                    DockEventReceiver.finishStartingService(mContext, mPendingStartId);
-                } else {
-                    if (DEBUG) {
-                        Log.d(TAG, "A DISABLE_BT_WHEN_UNDOCKED = "
-                                + getSettingBool(SHARED_PREFERENCES_KEY_DISABLE_BT_WHEN_UNDOCKED));
-                    }
-                    // Reconnect if docked and bluetooth was enabled by user.
-                    Intent i = registerReceiver(null, new IntentFilter(Intent.ACTION_DOCK_EVENT));
-                    if (i != null) {
-                        int state = i.getIntExtra(Intent.EXTRA_DOCK_STATE,
-                                Intent.EXTRA_DOCK_STATE_UNDOCKED);
-                        if (state != Intent.EXTRA_DOCK_STATE_UNDOCKED) {
-                            BluetoothDevice device = i
-                                    .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
-                            if (device != null) {
-                                connectIfEnabled(device);
-                            }
-                        } else if (getSettingBool(SHARED_PREFERENCES_KEY_DISABLE_BT)
-                                && mBtManager.getBluetoothAdapter().disable()) {
-                            mPendingTurnOffStartId = startId;
-                            removeSetting(SHARED_PREFERENCES_KEY_DISABLE_BT);
-                            return;
-                        }
-                    }
-                }
-
-                if (mPendingTurnOnStartId != INVALID_STARTID) {
-                    DockEventReceiver.finishStartingService(this, mPendingTurnOnStartId);
-                    mPendingTurnOnStartId = INVALID_STARTID;
-                }
-
-                DockEventReceiver.finishStartingService(this, startId);
+                handleBluetoothStateOn(startId);
             } else if (btState == BluetoothAdapter.STATE_TURNING_OFF) {
                 // Remove the flag to disable BT if someone is turning off bt.
                 // The rational is that:
                 // a) if BT is off at undock time, no work needs to be done
                 // b) if BT is on at undock time, the user wants it on.
-                removeSetting(SHARED_PREFERENCES_KEY_DISABLE_BT_WHEN_UNDOCKED);
+                getPrefs().edit().remove(KEY_DISABLE_BT_WHEN_UNDOCKED).apply();
                 DockEventReceiver.finishStartingService(this, startId);
             } else if (btState == BluetoothAdapter.STATE_OFF) {
                 // Bluetooth was turning off as we were trying to turn it on.
@@ -605,12 +643,12 @@
 
                 if (mPendingTurnOffStartId != INVALID_STARTID) {
                     DockEventReceiver.finishStartingService(this, mPendingTurnOffStartId);
-                    removeSetting(SHARED_PREFERENCES_KEY_DISABLE_BT);
+                    getPrefs().edit().remove(KEY_DISABLE_BT).apply();
                     mPendingTurnOffStartId = INVALID_STARTID;
                 }
 
                 if (mPendingDevice != null) {
-                    mBtManager.getBluetoothAdapter().enable();
+                    mLocalAdapter.enable();
                     mPendingTurnOnStartId = startId;
                 } else {
                     DockEventReceiver.finishStartingService(this, startId);
@@ -619,86 +657,124 @@
         }
     }
 
-    private void handleUnexpectedDisconnect(BluetoothDevice disconnectedDevice, Profile profile,
-            int startId) {
-        synchronized (this) {
-            if (DEBUG) Log.d(TAG, "handling failed connect for " + disconnectedDevice);
+    private void handleBluetoothStateOn(int startId) {
+        if (mPendingDevice != null) {
+            if (mPendingDevice.equals(mDevice)) {
+                if(DEBUG) {
+                    Log.d(TAG, "applying settings");
+                }
+                applyBtSettings(mPendingDevice, mPendingStartId);
+            } else if(DEBUG) {
+                Log.d(TAG, "mPendingDevice  (" + mPendingDevice + ") != mDevice ("
+                        + mDevice + ')');
+            }
+
+            mPendingDevice = null;
+            DockEventReceiver.finishStartingService(this, mPendingStartId);
+        } else {
+            final SharedPreferences prefs = getPrefs();
+            if (DEBUG) {
+                Log.d(TAG, "A DISABLE_BT_WHEN_UNDOCKED = "
+                        + prefs.getBoolean(KEY_DISABLE_BT_WHEN_UNDOCKED, false));
+            }
+            // Reconnect if docked and bluetooth was enabled by user.
+            Intent i = registerReceiver(null, new IntentFilter(Intent.ACTION_DOCK_EVENT));
+            if (i != null) {
+                int state = i.getIntExtra(Intent.EXTRA_DOCK_STATE,
+                        Intent.EXTRA_DOCK_STATE_UNDOCKED);
+                if (state != Intent.EXTRA_DOCK_STATE_UNDOCKED) {
+                    BluetoothDevice device = i
+                            .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+                    if (device != null) {
+                        connectIfEnabled(device);
+                    }
+                } else if (prefs.getBoolean(KEY_DISABLE_BT, false)
+                        && mLocalAdapter.disable()) {
+                    mPendingTurnOffStartId = startId;
+                    prefs.edit().remove(KEY_DISABLE_BT).apply();
+                    return;
+                }
+            }
+        }
+
+        if (mPendingTurnOnStartId != INVALID_STARTID) {
+            DockEventReceiver.finishStartingService(this, mPendingTurnOnStartId);
+            mPendingTurnOnStartId = INVALID_STARTID;
+        }
+
+        DockEventReceiver.finishStartingService(this, startId);
+    }
+
+    private synchronized void handleUnexpectedDisconnect(BluetoothDevice disconnectedDevice,
+            LocalBluetoothProfile profile, int startId) {
+        if (DEBUG) {
+            Log.d(TAG, "handling failed connect for " + disconnectedDevice);
+        }
 
             // Reconnect if docked.
             if (disconnectedDevice != null) {
                 // registerReceiver can't be called from a BroadcastReceiver
-                Intent i = registerReceiver(null, new IntentFilter(Intent.ACTION_DOCK_EVENT));
-                if (i != null) {
-                    int state = i.getIntExtra(Intent.EXTRA_DOCK_STATE,
+                Intent intent = registerReceiver(null, new IntentFilter(Intent.ACTION_DOCK_EVENT));
+                if (intent != null) {
+                    int state = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
                             Intent.EXTRA_DOCK_STATE_UNDOCKED);
                     if (state != Intent.EXTRA_DOCK_STATE_UNDOCKED) {
-                        BluetoothDevice dockedDevice = i
+                        BluetoothDevice dockedDevice = intent
                                 .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                         if (dockedDevice != null && dockedDevice.equals(disconnectedDevice)) {
-                            CachedBluetoothDevice cachedDevice = getCachedBluetoothDevice(mContext,
-                                    mBtManager, dockedDevice);
-                            cachedDevice.connect(profile);
+                            CachedBluetoothDevice cachedDevice = getCachedBluetoothDevice(
+                                    dockedDevice);
+                            cachedDevice.connectProfile(profile);
                         }
                     }
                 }
             }
 
             DockEventReceiver.finishStartingService(this, startId);
-        }
     }
 
     private synchronized void connectIfEnabled(BluetoothDevice device) {
-        CachedBluetoothDevice cachedDevice = getCachedBluetoothDevice(mContext, mBtManager, device);
-        List<Profile> profiles = cachedDevice.getConnectableProfiles();
-        for (int i = 0; i < profiles.size(); i++) {
-            LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
-                    .getProfileManager(mBtManager, profiles.get(i));
-            int auto;
-            if (Profile.A2DP == profiles.get(i)) {
-                auto = BluetoothA2dp.PRIORITY_AUTO_CONNECT;
-            } else if (Profile.HEADSET == profiles.get(i)) {
-                auto = BluetoothHeadset.PRIORITY_AUTO_CONNECT;
-            } else {
-                continue;
-            }
-
-            if (profileManager.getPreferred(device) == auto) {
+        CachedBluetoothDevice cachedDevice = getCachedBluetoothDevice(
+                device);
+        List<LocalBluetoothProfile> profiles = cachedDevice.getConnectableProfiles();
+        for (LocalBluetoothProfile profile : profiles) {
+            if (profile.getPreferred(device) == BluetoothProfile.PRIORITY_AUTO_CONNECT) {
                 cachedDevice.connect(false);
-                break;
+                return;
             }
         }
     }
 
-    private synchronized void applyBtSettings(final BluetoothDevice device, int startId) {
-        if (device == null || mProfiles == null || mCheckedItems == null)
+    private synchronized void applyBtSettings(BluetoothDevice device, int startId) {
+        if (device == null || mProfiles == null || mCheckedItems == null
+                || mLocalAdapter == null) {
             return;
+        }
 
         // Turn on BT if something is enabled
-        synchronized (this) {
-            for (boolean enable : mCheckedItems) {
-                if (enable) {
-                    int btState = mBtManager.getBluetoothState();
-                    if(DEBUG) Log.d(TAG, "BtState = " + btState);
-                    // May have race condition as the phone comes in and out and in the dock.
-                    // Always turn on BT
-                    mBtManager.getBluetoothAdapter().enable();
+        for (boolean enable : mCheckedItems) {
+            if (enable) {
+                int btState = mLocalAdapter.getBluetoothState();
+                if (DEBUG) {
+                    Log.d(TAG, "BtState = " + btState);
+                }
+                // May have race condition as the phone comes in and out and in the dock.
+                // Always turn on BT
+                mLocalAdapter.enable();
 
-                    switch (btState) {
-                        case BluetoothAdapter.STATE_OFF:
-                        case BluetoothAdapter.STATE_TURNING_OFF:
-                        case BluetoothAdapter.STATE_TURNING_ON:
-                            if (mPendingDevice != null && mPendingDevice.equals(mDevice)) {
-                                return;
-                            }
-
-                            mPendingDevice = device;
-                            mPendingStartId = startId;
-                            if (btState != BluetoothAdapter.STATE_TURNING_ON) {
-                                setSettingBool(SHARED_PREFERENCES_KEY_DISABLE_BT_WHEN_UNDOCKED,
-                                        true);
-                            }
-                            return;
+                // if adapter was previously OFF, TURNING_OFF, or TURNING_ON
+                if (btState != BluetoothAdapter.STATE_ON) {
+                    if (mPendingDevice != null && mPendingDevice.equals(mDevice)) {
+                        return;
                     }
+
+                    mPendingDevice = device;
+                    mPendingStartId = startId;
+                    if (btState != BluetoothAdapter.STATE_TURNING_ON) {
+                        getPrefs().edit().putBoolean(
+                                KEY_DISABLE_BT_WHEN_UNDOCKED, true).apply();
+                    }
+                    return;
                 }
             }
         }
@@ -706,28 +782,26 @@
         mPendingDevice = null;
 
         boolean callConnect = false;
-        CachedBluetoothDevice cachedDevice = getCachedBluetoothDevice(mContext, mBtManager,
+        CachedBluetoothDevice cachedDevice = getCachedBluetoothDevice(
                 device);
         for (int i = 0; i < mProfiles.length; i++) {
-            LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
-                    .getProfileManager(mBtManager, mProfiles[i]);
-
-            if (DEBUG) Log.d(TAG, mProfiles[i].toString() + " = " + mCheckedItems[i]);
+            LocalBluetoothProfile profile = mProfiles[i];
+            if (DEBUG) Log.d(TAG, profile.toString() + " = " + mCheckedItems[i]);
 
             if (mCheckedItems[i]) {
                 // Checked but not connected
                 callConnect = true;
             } else if (!mCheckedItems[i]) {
                 // Unchecked, may or may not be connected.
-                int status = profileManager.getConnectionStatus(cachedDevice.getDevice());
-                if (SettingsBtStatus.isConnectionStatusConnected(status)) {
+                int status = profile.getConnectionStatus(cachedDevice.getDevice());
+                if (status == BluetoothProfile.STATE_CONNECTED) {
                     if (DEBUG) Log.d(TAG, "applyBtSettings - Disconnecting");
                     cachedDevice.disconnect(mProfiles[i]);
                 }
             }
-            profileManager.setPreferred(device, mCheckedItems[i]);
+            profile.setPreferred(device, mCheckedItems[i]);
             if (DEBUG) {
-                if (mCheckedItems[i] != profileManager.isPreferred(device)) {
+                if (mCheckedItems[i] != profile.isPreferred(device)) {
                     Log.e(TAG, "Can't save preferred value");
                 }
             }
@@ -739,84 +813,47 @@
         }
     }
 
-    private synchronized void handleDocked(final BluetoothDevice device, final int state,
-            final int startId) {
-        if (mBtManager.getDockAutoConnectSetting(device.getAddress())) {
+    private synchronized void handleDocked(BluetoothDevice device, int state,
+            int startId) {
+        if (LocalBluetoothPreferences.getDockAutoConnectSetting(this, device.getAddress())) {
             // Setting == auto connect
-            initBtSettings(mContext, device, state, false);
+            initBtSettings(device, state, false);
             applyBtSettings(mDevice, startId);
         } else {
-            createDialog(mContext, device, state, startId);
+            createDialog(device, state, startId);
         }
     }
 
-    private synchronized void handleUndocked(Context context, LocalBluetoothManager localManager,
-            BluetoothDevice device) {
+    private synchronized void handleUndocked(BluetoothDevice device) {
         mRunnable = null;
-        LocalBluetoothProfileManager.removeServiceListener(this);
+        mProfileManager.removeServiceListener(this);
         if (mDialog != null) {
             mDialog.dismiss();
             mDialog = null;
         }
         mDevice = null;
         mPendingDevice = null;
-        CachedBluetoothDevice cachedBluetoothDevice = getCachedBluetoothDevice(context,
-                localManager, device);
-        cachedBluetoothDevice.disconnect();
+        CachedBluetoothDevice cachedDevice = getCachedBluetoothDevice(device);
+        cachedDevice.disconnect();
     }
 
-    private static CachedBluetoothDevice getCachedBluetoothDevice(Context context,
-            LocalBluetoothManager localManager, BluetoothDevice device) {
-        CachedBluetoothDeviceManager cachedDeviceManager = localManager.getCachedDeviceManager();
-        CachedBluetoothDevice cachedBluetoothDevice = cachedDeviceManager.findDevice(device);
-        if (cachedBluetoothDevice == null) {
-            cachedBluetoothDevice = new CachedBluetoothDevice(context, device);
+    private CachedBluetoothDevice getCachedBluetoothDevice(BluetoothDevice device) {
+        CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device);
+        if (cachedDevice == null) {
+            cachedDevice = mDeviceManager.addDevice(mLocalAdapter, mProfileManager, device);
         }
-        return cachedBluetoothDevice;
-    }
-
-    private boolean getSettingBool(String key) {
-        SharedPreferences sharedPref = getSharedPreferences(SHARED_PREFERENCES_NAME,
-                Context.MODE_PRIVATE);
-        return sharedPref.getBoolean(key, false);
-    }
-
-    private int getSettingInt(String key, int defaultValue) {
-        SharedPreferences sharedPref = getSharedPreferences(SHARED_PREFERENCES_NAME,
-                Context.MODE_PRIVATE);
-        return sharedPref.getInt(key, defaultValue);
-    }
-
-    private void setSettingBool(String key, boolean bool) {
-        SharedPreferences.Editor editor = getSharedPreferences(SHARED_PREFERENCES_NAME,
-                Context.MODE_PRIVATE).edit();
-        editor.putBoolean(key, bool);
-        editor.apply();
-    }
-
-    private void setSettingInt(String key, int value) {
-        SharedPreferences.Editor editor = getSharedPreferences(SHARED_PREFERENCES_NAME,
-                Context.MODE_PRIVATE).edit();
-        editor.putInt(key, value);
-        editor.apply();
-    }
-
-    private void removeSetting(String key) {
-        SharedPreferences sharedPref = getSharedPreferences(SHARED_PREFERENCES_NAME,
-                Context.MODE_PRIVATE);
-        SharedPreferences.Editor editor = sharedPref.edit();
-        editor.remove(key);
-        editor.apply();
+        return cachedDevice;
     }
 
     public synchronized void onServiceConnected() {
         if (mRunnable != null) {
             mRunnable.run();
             mRunnable = null;
-            LocalBluetoothProfileManager.removeServiceListener(this);
+            mProfileManager.removeServiceListener(this);
         }
     }
 
     public void onServiceDisconnected() {
+        // FIXME: shouldn't I do something on service disconnected too?
     }
 }
diff --git a/src/com/android/settings/bluetooth/HeadsetProfile.java b/src/com/android/settings/bluetooth/HeadsetProfile.java
new file mode 100644
index 0000000..dac47b7
--- /dev/null
+++ b/src/com/android/settings/bluetooth/HeadsetProfile.java
@@ -0,0 +1,198 @@
+/*
+ * 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.bluetooth.BluetoothClass;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHeadset;
+import android.bluetooth.BluetoothProfile;
+import android.bluetooth.BluetoothUuid;
+import android.content.Context;
+import android.os.Handler;
+import android.os.ParcelUuid;
+import android.util.Log;
+
+import com.android.settings.R;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * HeadsetProfile handles Bluetooth HFP and Headset profiles.
+ */
+final class HeadsetProfile implements LocalBluetoothProfile {
+    private static final String TAG = "HeadsetProfile";
+
+    private BluetoothHeadset mService;
+    private boolean mProfileReady;
+
+    private final LocalBluetoothAdapter mLocalAdapter;
+    private final CachedBluetoothDeviceManager mDeviceManager;
+    private final LocalBluetoothProfileManager mProfileManager;
+
+    static final ParcelUuid[] UUIDS = {
+        BluetoothUuid.HSP,
+        BluetoothUuid.Handsfree,
+    };
+
+    static final String NAME = "HEADSET";
+
+    // Order of this profile in device profiles list
+    private static final int ORDINAL = 0;
+
+    // These callbacks run on the main thread.
+    private final class HeadsetServiceListener
+            implements BluetoothProfile.ServiceListener {
+
+        public void onServiceConnected(int profile, BluetoothProfile proxy) {
+            mService = (BluetoothHeadset) proxy;
+            mProfileReady = true;
+            // We just bound to the service, so refresh the UI of the
+            // headset device.
+            List<BluetoothDevice> deviceList = mService.getConnectedDevices();
+            if (deviceList.isEmpty()) {
+                return;
+            }
+            BluetoothDevice firstDevice = deviceList.get(0);
+            CachedBluetoothDevice device = mDeviceManager.findDevice(firstDevice);
+            // we may add a new device here, but generally this should not happen
+            if (device == null) {
+                Log.w(TAG, "HeadsetProfile found new device: " + firstDevice);
+                device = mDeviceManager.addDevice(mLocalAdapter, mProfileManager, firstDevice);
+            }
+            device.onProfileStateChanged(HeadsetProfile.this,
+                    BluetoothProfile.STATE_CONNECTED);
+
+            mProfileManager.callServiceConnectedListeners();
+        }
+
+        public void onServiceDisconnected(int profile) {
+            mProfileReady = false;
+            mService = null;
+            mProfileManager.callServiceDisconnectedListeners();
+        }
+    }
+
+    // TODO(): The calls must get queued if mService becomes null.
+    // It can happen when the phone app crashes for some reason.
+    // All callers should have service listeners. Dock Service is the only
+    // one right now.
+    HeadsetProfile(Context context, LocalBluetoothAdapter adapter,
+            CachedBluetoothDeviceManager deviceManager,
+            LocalBluetoothProfileManager profileManager) {
+        mLocalAdapter = adapter;
+        mDeviceManager = deviceManager;
+        mProfileManager = profileManager;
+        mLocalAdapter.getProfileProxy(context, new HeadsetServiceListener(),
+                BluetoothProfile.HEADSET);
+    }
+
+    public boolean isConnectable() {
+        return true;
+    }
+
+    public boolean isAutoConnectable() {
+        return true;
+    }
+
+    public boolean connect(BluetoothDevice device) {
+        List<BluetoothDevice> sinks = mService.getConnectedDevices();
+        if (sinks != null) {
+            for (BluetoothDevice sink : sinks) {
+                mService.disconnect(sink);
+            }
+        }
+        return mService.connect(device);
+    }
+
+    public boolean disconnect(BluetoothDevice device) {
+        List<BluetoothDevice> deviceList = mService.getConnectedDevices();
+        if (!deviceList.isEmpty() && deviceList.get(0).equals(device)) {
+            // Downgrade priority as user is disconnecting the headset.
+            if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) {
+                mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
+            }
+            return mService.disconnect(device);
+        } else {
+            return false;
+        }
+    }
+
+    public int getConnectionStatus(BluetoothDevice device) {
+        List<BluetoothDevice> deviceList = mService.getConnectedDevices();
+
+        return !deviceList.isEmpty() && deviceList.get(0).equals(device)
+                ? mService.getConnectionState(device)
+                : BluetoothProfile.STATE_DISCONNECTED;
+    }
+
+    public boolean isPreferred(BluetoothDevice device) {
+        return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
+    }
+
+    public int getPreferred(BluetoothDevice device) {
+        return mService.getPriority(device);
+    }
+
+    public void setPreferred(BluetoothDevice device, boolean preferred) {
+        if (preferred) {
+            if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
+                mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
+            }
+        } else {
+            mService.setPriority(device, BluetoothProfile.PRIORITY_OFF);
+        }
+    }
+
+    public synchronized boolean isProfileReady() {
+        return mProfileReady;
+    }
+
+    public String toString() {
+        return NAME;
+    }
+
+    public int getOrdinal() {
+        return ORDINAL;
+    }
+
+    public int getNameResource() {
+        return R.string.bluetooth_profile_headset;
+    }
+
+    public int getDisconnectResource() {
+        return R.string.bluetooth_disconnect_headset_profile;
+    }
+
+    public int getSummaryResourceForDevice(BluetoothDevice device) {
+        int state = mService.getConnectionState(device);
+        switch (state) {
+            case BluetoothProfile.STATE_DISCONNECTED:
+                return R.string.bluetooth_headset_profile_summary_use_for;
+
+            case BluetoothProfile.STATE_CONNECTED:
+                return R.string.bluetooth_headset_profile_summary_connected;
+
+            default:
+                return Utils.getConnectionStateSummary(state);
+        }
+    }
+
+    public int getDrawableResource(BluetoothClass btClass) {
+        return R.drawable.ic_bt_headset_hfp;
+    }
+}
diff --git a/src/com/android/settings/bluetooth/HidProfile.java b/src/com/android/settings/bluetooth/HidProfile.java
new file mode 100644
index 0000000..9185059
--- /dev/null
+++ b/src/com/android/settings/bluetooth/HidProfile.java
@@ -0,0 +1,155 @@
+/*
+ * 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.bluetooth.BluetoothClass;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothInputDevice;
+import android.bluetooth.BluetoothProfile;
+import android.content.Context;
+
+import com.android.settings.R;
+
+import java.util.List;
+
+/**
+ * HidProfile handles Bluetooth HID profile.
+ */
+final class HidProfile implements LocalBluetoothProfile {
+    private BluetoothInputDevice mService;
+    private boolean mProfileReady;
+
+    static final String NAME = "HID";
+
+    // Order of this profile in device profiles list
+    private static final int ORDINAL = 3;
+
+    // These callbacks run on the main thread.
+    private final class InputDeviceServiceListener
+            implements BluetoothProfile.ServiceListener {
+
+        public void onServiceConnected(int profile, BluetoothProfile proxy) {
+            mService = (BluetoothInputDevice) proxy;
+            mProfileReady = true;
+        }
+
+        public void onServiceDisconnected(int profile) {
+            mProfileReady = false;
+            mService = null;
+        }
+    }
+
+    HidProfile(Context context, LocalBluetoothAdapter adapter) {
+        adapter.getProfileProxy(context, new InputDeviceServiceListener(),
+                BluetoothProfile.INPUT_DEVICE);
+    }
+
+    public boolean isConnectable() {
+        return true;
+    }
+
+    public boolean isAutoConnectable() {
+        return true;
+    }
+
+    public boolean connect(BluetoothDevice device) {
+        return mService.connect(device);
+    }
+
+    public boolean disconnect(BluetoothDevice device) {
+        return mService.disconnect(device);
+    }
+
+    public int getConnectionStatus(BluetoothDevice device) {
+        List<BluetoothDevice> deviceList = mService.getConnectedDevices();
+
+        return !deviceList.isEmpty() && deviceList.get(0).equals(device)
+                ? mService.getConnectionState(device)
+                : BluetoothProfile.STATE_DISCONNECTED;
+    }
+
+    public boolean isPreferred(BluetoothDevice device) {
+        return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
+    }
+
+    public int getPreferred(BluetoothDevice device) {
+        return mService.getPriority(device);
+    }
+
+    public void setPreferred(BluetoothDevice device, boolean preferred) {
+        if (preferred) {
+            if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
+                mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
+            }
+        } else {
+            mService.setPriority(device, BluetoothProfile.PRIORITY_OFF);
+        }
+    }
+
+    public boolean isProfileReady() {
+        return mProfileReady;
+    }
+
+    public String toString() {
+        return NAME;
+    }
+
+    public int getOrdinal() {
+        return ORDINAL;
+    }
+
+    public int getNameResource() {
+        return R.string.bluetooth_profile_hid;
+    }
+
+    public int getDisconnectResource() {
+        return R.string.bluetooth_disconnect_hid_profile;
+    }
+
+    public int getSummaryResourceForDevice(BluetoothDevice device) {
+        int state = mService.getConnectionState(device);
+        switch (state) {
+            case BluetoothProfile.STATE_DISCONNECTED:
+                return R.string.bluetooth_hid_profile_summary_use_for;
+
+            case BluetoothProfile.STATE_CONNECTED:
+                return R.string.bluetooth_hid_profile_summary_connected;
+
+            default:
+                return Utils.getConnectionStateSummary(state);
+        }
+    }
+
+    public int getDrawableResource(BluetoothClass btClass) {
+        if (btClass == null) {
+            return R.drawable.ic_bt_keyboard_hid;
+        }
+        return getHidClassDrawable(btClass);
+    }
+
+    static int getHidClassDrawable(BluetoothClass btClass) {
+        switch (btClass.getDeviceClass()) {
+            case BluetoothClass.Device.PERIPHERAL_KEYBOARD:
+            case BluetoothClass.Device.PERIPHERAL_KEYBOARD_POINTING:
+                return R.drawable.ic_bt_keyboard_hid;
+            case BluetoothClass.Device.PERIPHERAL_POINTING:
+                return R.drawable.ic_bt_pointing_hid;
+            default:
+                return R.drawable.ic_bt_misc_hid;
+        }
+    }
+}
diff --git a/src/com/android/settings/bluetooth/LocalBluetoothAdapter.java b/src/com/android/settings/bluetooth/LocalBluetoothAdapter.java
new file mode 100644
index 0000000..013171c
--- /dev/null
+++ b/src/com/android/settings/bluetooth/LocalBluetoothAdapter.java
@@ -0,0 +1,216 @@
+/*
+ * 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.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
+import android.content.Context;
+import android.os.ParcelUuid;
+import android.util.Log;
+
+import java.util.Set;
+
+/**
+ * LocalBluetoothAdapter provides an interface between the Settings app
+ * and the functionality of the local {@link BluetoothAdapter}, specifically
+ * those related to state transitions of the adapter itself.
+ *
+ * <p>Connection and bonding state changes affecting specific devices
+ * are handled by {@link CachedBluetoothDeviceManager},
+ * {@link BluetoothEventManager}, and {@link LocalBluetoothProfileManager}.
+ */
+public final class LocalBluetoothAdapter {
+    private static final String TAG = "LocalBluetoothAdapter";
+
+    /** This class does not allow direct access to the BluetoothAdapter. */
+    private final BluetoothAdapter mAdapter;
+
+    private LocalBluetoothProfileManager mProfileManager;
+
+    private static LocalBluetoothAdapter sInstance;
+
+    private int mState = BluetoothAdapter.ERROR;
+
+    private static final int SCAN_EXPIRATION_MS = 5 * 60 * 1000; // 5 mins
+
+    private long mLastScan;
+
+    private LocalBluetoothAdapter(BluetoothAdapter adapter) {
+        mAdapter = adapter;
+    }
+
+    void setProfileManager(LocalBluetoothProfileManager manager) {
+        mProfileManager = manager;
+    }
+
+    /**
+     * Get the singleton instance of the LocalBluetoothAdapter. If this device
+     * doesn't support Bluetooth, then null will be returned. Callers must be
+     * prepared to handle a null return value.
+     * @return the LocalBluetoothAdapter object, or null if not supported
+     */
+    static synchronized LocalBluetoothAdapter getInstance() {
+        if (sInstance == null) {
+            BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+            if (adapter != null) {
+                sInstance = new LocalBluetoothAdapter(adapter);
+            }
+        }
+
+        return sInstance;
+    }
+
+    // Pass-through BluetoothAdapter methods that we can intercept if necessary
+
+    void cancelDiscovery() {
+        mAdapter.cancelDiscovery();
+    }
+
+    boolean enable() {
+        return mAdapter.enable();
+    }
+
+    boolean disable() {
+        return mAdapter.disable();
+    }
+
+    void getProfileProxy(Context context,
+            BluetoothProfile.ServiceListener listener, int profile) {
+        mAdapter.getProfileProxy(context, listener, profile);
+    }
+
+    Set<BluetoothDevice> getBondedDevices() {
+        return mAdapter.getBondedDevices();
+    }
+
+    String getName() {
+        return mAdapter.getName();
+    }
+
+    int getScanMode() {
+        return mAdapter.getScanMode();
+    }
+
+    int getState() {
+        return mAdapter.getState();
+    }
+
+    ParcelUuid[] getUuids() {
+        return mAdapter.getUuids();
+    }
+
+    boolean isDiscovering() {
+        return mAdapter.isDiscovering();
+    }
+
+    boolean isEnabled() {
+        return mAdapter.isEnabled();
+    }
+
+    void setDiscoverableTimeout(int timeout) {
+        mAdapter.setDiscoverableTimeout(timeout);
+    }
+
+    void setName(String name) {
+        mAdapter.setName(name);
+    }
+
+    void setScanMode(int mode) {
+        mAdapter.setScanMode(mode);
+    }
+
+    boolean setScanMode(int mode, int duration) {
+        return mAdapter.setScanMode(mode, duration);
+    }
+
+    void startScanning(boolean force) {
+        // Only start if we're not already scanning
+        if (!mAdapter.isDiscovering()) {
+            if (!force) {
+                // Don't scan more than frequently than SCAN_EXPIRATION_MS,
+                // unless forced
+                if (mLastScan + SCAN_EXPIRATION_MS > System.currentTimeMillis()) {
+                    return;
+                }
+
+                // If we are playing music, don't scan unless forced.
+                A2dpProfile a2dp = mProfileManager.getA2dpProfile();
+                if (a2dp != null && a2dp.isA2dpPlaying()) {
+                    return;
+                }
+            }
+
+            if (mAdapter.startDiscovery()) {
+                mLastScan = System.currentTimeMillis();
+            }
+        }
+    }
+
+    void stopScanning() {
+        if (mAdapter.isDiscovering()) {
+            mAdapter.cancelDiscovery();
+        }
+    }
+
+    public synchronized int getBluetoothState() {
+        // Always sync state, in case it changed while paused
+        syncBluetoothState();
+        return mState;
+    }
+
+    synchronized void setBluetoothStateInt(int state) {
+        mState = state;
+
+        if (state == BluetoothAdapter.STATE_ON) {
+            // if mProfileManager hasn't been constructed yet, it will
+            // get the adapter UUIDs in its constructor when it is.
+            if (mProfileManager != null) {
+                mProfileManager.setBluetoothStateOn();
+            }
+        }
+    }
+
+    // Returns true if the state changed; false otherwise.
+    boolean syncBluetoothState() {
+        int currentState = mAdapter.getState();
+        if (currentState != mState) {
+            setBluetoothStateInt(mAdapter.getState());
+            return true;
+        }
+        return false;
+    }
+
+    public void setBluetoothEnabled(boolean enabled) {
+        boolean success = enabled
+                ? mAdapter.enable()
+                : mAdapter.disable();
+
+        if (success) {
+            setBluetoothStateInt(enabled
+                ? BluetoothAdapter.STATE_TURNING_ON
+                : BluetoothAdapter.STATE_TURNING_OFF);
+        } else {
+            if (Utils.V) {
+                Log.v(TAG, "setBluetoothEnabled call, manager didn't return " +
+                        "success for enabled: " + enabled);
+            }
+
+            syncBluetoothState();
+        }
+    }
+}
diff --git a/src/com/android/settings/bluetooth/LocalBluetoothManager.java b/src/com/android/settings/bluetooth/LocalBluetoothManager.java
index f3c5e6f..0c04e22 100644
--- a/src/com/android/settings/bluetooth/LocalBluetoothManager.java
+++ b/src/com/android/settings/bluetooth/LocalBluetoothManager.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 The Android Open Source Project
+ * 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.
@@ -16,376 +16,96 @@
 
 package com.android.settings.bluetooth;
 
-import com.android.settings.R;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.bluetooth.BluetoothA2dp;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothProfile;
 import android.content.Context;
-import android.content.SharedPreferences;
-import android.os.ParcelUuid;
-import android.util.Config;
 import android.util.Log;
-import android.widget.Toast;
 
-import java.util.ArrayList;
-import java.util.List;
-
-// TODO: have some notion of shutting down.  Maybe a minute after they leave BT settings?
 /**
  * LocalBluetoothManager provides a simplified interface on top of a subset of
- * the Bluetooth API.
+ * the Bluetooth API. Note that {@link #getInstance} will return null
+ * if there is no Bluetooth adapter on this device, and callers must be
+ * prepared to handle this case.
  */
-public class LocalBluetoothManager {
+public final class LocalBluetoothManager {
     private static final String TAG = "LocalBluetoothManager";
-    static final boolean V = Config.LOGV;
-    static final boolean D = Config.LOGD;
-
-    private static final String SHARED_PREFERENCES_NAME = "bluetooth_settings";
 
     /** Singleton instance. */
     private static LocalBluetoothManager sInstance;
 
-    private Context mContext;
+    private final Context mContext;
+
     /** If a BT-related activity is in the foreground, this will be it. */
-    private Activity mForegroundActivity;
-    private AlertDialog mErrorDialog = null;
+    private Context mForegroundActivity;
 
-    private BluetoothAdapter mAdapter;
+    private final LocalBluetoothAdapter mLocalAdapter;
 
-    private CachedBluetoothDeviceManager mCachedDeviceManager;
-    private BluetoothA2dp mBluetoothA2dp;
+    private final CachedBluetoothDeviceManager mCachedDeviceManager;
 
-    private int mState = BluetoothAdapter.ERROR;
+    /** The Bluetooth profile manager. */
+    private final LocalBluetoothProfileManager mProfileManager;
 
-    private final List<Callback> mCallbacks = new ArrayList<Callback>();
+    /** The broadcast receiver event manager. */
+    private final BluetoothEventManager mEventManager;
 
-    private static final int SCAN_EXPIRATION_MS = 5 * 60 * 1000; // 5 mins
-
-    // If a device was picked from the device picker or was in discoverable mode
-    // in the last 60 seconds, show the pairing dialogs in foreground instead
-    // of raising notifications
-    private static final int GRACE_PERIOD_TO_SHOW_DIALOGS_IN_FOREGROUND = 60 * 1000;
-
-    public static final String SHARED_PREFERENCES_KEY_DISCOVERING_TIMESTAMP =
-        "last_discovering_time";
-
-    private static final String SHARED_PREFERENCES_KEY_LAST_SELECTED_DEVICE =
-        "last_selected_device";
-
-    private static final String SHARED_PREFERENCES_KEY_LAST_SELECTED_DEVICE_TIME =
-        "last_selected_device_time";
-
-    private static final String SHARED_PREFERENCES_KEY_DOCK_AUTO_CONNECT = "auto_connect_to_dock";
-
-    private long mLastScan;
-
-    private LocalBluetoothManager() { }
-
-    public static LocalBluetoothManager getInstance(Context context) {
-        synchronized (LocalBluetoothManager.class) {
-            if (sInstance == null) {
-                sInstance = new LocalBluetoothManager();
-                if (!sInstance.init(context)) {
-                    return null;
-                }
-                LocalBluetoothProfileManager.init(sInstance);
+    public static synchronized LocalBluetoothManager getInstance(Context context) {
+        if (sInstance == null) {
+            LocalBluetoothAdapter adapter = LocalBluetoothAdapter.getInstance();
+            if (adapter == null) {
+                return null;
             }
-
-            return sInstance;
+            // This will be around as long as this process is
+            Context appContext = context.getApplicationContext();
+            sInstance = new LocalBluetoothManager(adapter, appContext);
         }
+
+        return sInstance;
     }
 
-    private boolean init(Context context) {
-        // This will be around as long as this process is
-        mContext = context.getApplicationContext();
+    private LocalBluetoothManager(LocalBluetoothAdapter adapter, Context context) {
+        mContext = context;
+        mLocalAdapter = adapter;
 
-        mAdapter = BluetoothAdapter.getDefaultAdapter();
-        if (mAdapter == null) {
-            return false;
-        }
-
-        mCachedDeviceManager = new CachedBluetoothDeviceManager(this);
-
-        new BluetoothEventRedirector(this).registerReceiver();
-
-        mAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.A2DP);
-
-        return true;
+        mCachedDeviceManager = new CachedBluetoothDeviceManager();
+        mEventManager = new BluetoothEventManager(mLocalAdapter,
+                mCachedDeviceManager);
+        mProfileManager = new LocalBluetoothProfileManager(context,
+                mLocalAdapter, mCachedDeviceManager, mEventManager);
     }
 
-    private final BluetoothProfile.ServiceListener mProfileListener =
-      new BluetoothProfile.ServiceListener() {
-        public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            mBluetoothA2dp = (BluetoothA2dp) proxy;
-        }
-        public void onServiceDisconnected(int profile) {
-            mBluetoothA2dp = null;
-        }
-    };
-
-    public BluetoothAdapter getBluetoothAdapter() {
-        return mAdapter;
+    public LocalBluetoothAdapter getBluetoothAdapter() {
+        return mLocalAdapter;
     }
 
     public Context getContext() {
         return mContext;
     }
 
-    public Activity getForegroundActivity() {
-        return mForegroundActivity;
+    boolean isForegroundActivity() {
+        return mForegroundActivity != null;
     }
 
-    public void setForegroundActivity(Activity activity) {
-        if (mErrorDialog != null) {
-            mErrorDialog.dismiss();
-            mErrorDialog = null;
+    synchronized void setForegroundActivity(Context context) {
+        if (context != null) {
+            Log.d(TAG, "setting foreground activity to non-null context");
+            mForegroundActivity = context;
+            mEventManager.resume(context);
+        } else {
+            if (mForegroundActivity != null) {
+                Log.d(TAG, "setting foreground activity to null");
+                mEventManager.pause(mForegroundActivity);
+                mForegroundActivity = null;
+            }
         }
-        mForegroundActivity = activity;
     }
 
-    public SharedPreferences getSharedPreferences() {
-        return mContext.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
-    }
-
-    public CachedBluetoothDeviceManager getCachedDeviceManager() {
+    CachedBluetoothDeviceManager getCachedDeviceManager() {
         return mCachedDeviceManager;
     }
 
-    List<Callback> getCallbacks() {
-        return mCallbacks;
+    BluetoothEventManager getEventManager() {
+        return mEventManager;
     }
 
-    public void registerCallback(Callback callback) {
-        synchronized (mCallbacks) {
-            mCallbacks.add(callback);
-        }
-    }
-
-    public void unregisterCallback(Callback callback) {
-        synchronized (mCallbacks) {
-            mCallbacks.remove(callback);
-        }
-    }
-
-    public void startScanning(boolean force) {
-        if (mAdapter.isDiscovering()) {
-            /*
-             * Already discovering, but give the callback that information.
-             * Note: we only call the callbacks, not the same path as if the
-             * scanning state had really changed (in that case the device
-             * manager would clear its list of unpaired scanned devices).
-             */
-            dispatchScanningStateChanged(true);
-        } else {
-            if (!force) {
-                // Don't scan more than frequently than SCAN_EXPIRATION_MS,
-                // unless forced
-                if (mLastScan + SCAN_EXPIRATION_MS > System.currentTimeMillis()) {
-                    return;
-                }
-
-                // If we are playing music, don't scan unless forced.
-                if (mBluetoothA2dp != null) {
-                    List<BluetoothDevice> sinks = mBluetoothA2dp.getConnectedDevices();
-                    if (sinks.size() > 0) {
-                        if (mBluetoothA2dp.isA2dpPlaying(sinks.get(0))) return;
-                    }
-                }
-            }
-
-            if (mAdapter.startDiscovery()) {
-                mLastScan = System.currentTimeMillis();
-            }
-        }
-    }
-
-    public void stopScanning() {
-        if (mAdapter.isDiscovering()) {
-            mAdapter.cancelDiscovery();
-        }
-    }
-
-    public int getBluetoothState() {
-
-        if (mState == BluetoothAdapter.ERROR) {
-            syncBluetoothState();
-        }
-
-        return mState;
-    }
-
-    void setBluetoothStateInt(int state) {
-        mState = state;
-
-        if (state == BluetoothAdapter.STATE_ON) {
-            ParcelUuid[] uuids = mAdapter.getUuids();
-            LocalBluetoothProfileManager.updateLocalProfiles(getInstance(mContext), uuids);
-        }
-
-        if (state == BluetoothAdapter.STATE_ON ||
-            state == BluetoothAdapter.STATE_OFF) {
-            mCachedDeviceManager.onBluetoothStateChanged(state ==
-                    BluetoothAdapter.STATE_ON);
-        }
-    }
-
-    private void syncBluetoothState() {
-        int bluetoothState;
-
-        if (mAdapter != null) {
-            bluetoothState = mAdapter.isEnabled()
-                    ? BluetoothAdapter.STATE_ON
-                    : BluetoothAdapter.STATE_OFF;
-        } else {
-            bluetoothState = BluetoothAdapter.ERROR;
-        }
-
-        setBluetoothStateInt(bluetoothState);
-    }
-
-    public void setBluetoothEnabled(boolean enabled) {
-        boolean wasSetStateSuccessful = enabled
-                ? mAdapter.enable()
-                : mAdapter.disable();
-
-        if (wasSetStateSuccessful) {
-            setBluetoothStateInt(enabled
-                ? BluetoothAdapter.STATE_TURNING_ON
-                : BluetoothAdapter.STATE_TURNING_OFF);
-        } else {
-            if (V) {
-                Log.v(TAG,
-                        "setBluetoothEnabled call, manager didn't return success for enabled: "
-                                + enabled);
-            }
-
-            syncBluetoothState();
-        }
-    }
-
-    /**
-     * @param started True if scanning started, false if scanning finished.
-     */
-    void onScanningStateChanged(boolean started) {
-        // TODO: have it be a callback (once we switch bluetooth state changed to callback)
-        mCachedDeviceManager.onScanningStateChanged(started);
-        dispatchScanningStateChanged(started);
-    }
-
-    private void dispatchScanningStateChanged(boolean started) {
-        synchronized (mCallbacks) {
-            for (Callback callback : mCallbacks) {
-                callback.onScanningStateChanged(started);
-            }
-        }
-    }
-
-    public void showError(BluetoothDevice device, int messageResId) {
-        CachedBluetoothDevice cachedDevice = mCachedDeviceManager.findDevice(device);
-        String name = null;
-        if (cachedDevice == null) {
-            if (device != null) name = device.getName();
-
-            if (name == null) {
-                name = mContext.getString(R.string.bluetooth_remote_device);
-            }
-        } else {
-            name = cachedDevice.getName();
-        }
-        String message = mContext.getString(messageResId, name);
-
-        if (mForegroundActivity != null) {
-            // Need an activity context to show a dialog
-            mErrorDialog = new AlertDialog.Builder(mForegroundActivity)
-                .setIcon(android.R.drawable.ic_dialog_alert)
-                .setTitle(R.string.bluetooth_error_title)
-                .setMessage(message)
-                .setPositiveButton(android.R.string.ok, null)
-                .show();
-        } else {
-            // Fallback on a toast
-            Toast.makeText(mContext, message, Toast.LENGTH_LONG).show();
-        }
-    }
-
-    public interface Callback {
-        void onScanningStateChanged(boolean started);
-        void onDeviceAdded(CachedBluetoothDevice cachedDevice);
-        void onDeviceDeleted(CachedBluetoothDevice cachedDevice);
-        void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState);
-    }
-
-    public boolean shouldShowDialogInForeground(String deviceAddress) {
-        // If Bluetooth Settings is visible
-        if (mForegroundActivity != null) return true;
-
-        long currentTimeMillis = System.currentTimeMillis();
-        SharedPreferences sharedPreferences = getSharedPreferences();
-
-        // If the device was in discoverABLE mode recently
-        long lastDiscoverableEndTime = sharedPreferences.getLong(
-                BluetoothDiscoverableEnabler.SHARED_PREFERENCES_KEY_DISCOVERABLE_END_TIMESTAMP, 0);
-        if ((lastDiscoverableEndTime + GRACE_PERIOD_TO_SHOW_DIALOGS_IN_FOREGROUND)
-                > currentTimeMillis) {
-            return true;
-        }
-
-        // If the device was discoverING recently
-        if (mAdapter != null && mAdapter.isDiscovering()) {
-            return true;
-        } else if ((sharedPreferences.getLong(SHARED_PREFERENCES_KEY_DISCOVERING_TIMESTAMP, 0) +
-                GRACE_PERIOD_TO_SHOW_DIALOGS_IN_FOREGROUND) > currentTimeMillis) {
-            return true;
-        }
-
-        // If the device was picked in the device picker recently
-        if (deviceAddress != null) {
-            String lastSelectedDevice = sharedPreferences.getString(
-                    SHARED_PREFERENCES_KEY_LAST_SELECTED_DEVICE, null);
-
-            if (deviceAddress.equals(lastSelectedDevice)) {
-                long lastDeviceSelectedTime = sharedPreferences.getLong(
-                        SHARED_PREFERENCES_KEY_LAST_SELECTED_DEVICE_TIME, 0);
-                if ((lastDeviceSelectedTime + GRACE_PERIOD_TO_SHOW_DIALOGS_IN_FOREGROUND)
-                        > currentTimeMillis) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    void persistSelectedDeviceInPicker(String deviceAddress) {
-        SharedPreferences.Editor editor = getSharedPreferences().edit();
-        editor.putString(LocalBluetoothManager.SHARED_PREFERENCES_KEY_LAST_SELECTED_DEVICE,
-                deviceAddress);
-        editor.putLong(LocalBluetoothManager.SHARED_PREFERENCES_KEY_LAST_SELECTED_DEVICE_TIME,
-                System.currentTimeMillis());
-        editor.apply();
-    }
-
-    public boolean hasDockAutoConnectSetting(String addr) {
-        return getSharedPreferences().contains(SHARED_PREFERENCES_KEY_DOCK_AUTO_CONNECT + addr);
-    }
-
-    public boolean getDockAutoConnectSetting(String addr) {
-        return getSharedPreferences().getBoolean(SHARED_PREFERENCES_KEY_DOCK_AUTO_CONNECT + addr,
-                false);
-    }
-
-    public void saveDockAutoConnectSetting(String addr, boolean autoConnect) {
-        SharedPreferences.Editor editor = getSharedPreferences().edit();
-        editor.putBoolean(SHARED_PREFERENCES_KEY_DOCK_AUTO_CONNECT + addr, autoConnect);
-        editor.apply();
-    }
-
-    public void removeDockAutoConnectSetting(String addr) {
-        SharedPreferences.Editor editor = getSharedPreferences().edit();
-        editor.remove(SHARED_PREFERENCES_KEY_DOCK_AUTO_CONNECT + addr);
-        editor.apply();
+    LocalBluetoothProfileManager getProfileManager() {
+        return mProfileManager;
     }
 }
diff --git a/src/com/android/settings/bluetooth/LocalBluetoothPreferences.java b/src/com/android/settings/bluetooth/LocalBluetoothPreferences.java
new file mode 100644
index 0000000..7e62b0e
--- /dev/null
+++ b/src/com/android/settings/bluetooth/LocalBluetoothPreferences.java
@@ -0,0 +1,157 @@
+/*
+ * 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.QueuedWork;
+import android.content.Context;
+import android.content.SharedPreferences;
+
+/**
+ * LocalBluetoothPreferences provides an interface to the preferences
+ * related to Bluetooth.
+ */
+final class LocalBluetoothPreferences {
+//    private static final String TAG = "LocalBluetoothPreferences";
+
+    private static final String SHARED_PREFERENCES_NAME = "bluetooth_settings";
+
+    // If a device was picked from the device picker or was in discoverable mode
+    // in the last 60 seconds, show the pairing dialogs in foreground instead
+    // of raising notifications
+    private static final int GRACE_PERIOD_TO_SHOW_DIALOGS_IN_FOREGROUND = 60 * 1000;
+
+    private static final String KEY_DISCOVERING_TIMESTAMP = "last_discovering_time";
+
+    private static final String KEY_LAST_SELECTED_DEVICE = "last_selected_device";
+
+    private static final String KEY_LAST_SELECTED_DEVICE_TIME = "last_selected_device_time";
+
+    private static final String KEY_DOCK_AUTO_CONNECT = "auto_connect_to_dock";
+
+    private static final String KEY_DISCOVERABLE_END_TIMESTAMP = "discoverable_end_timestamp";
+
+    private LocalBluetoothPreferences() {
+    }
+
+    private static SharedPreferences getSharedPreferences(Context context) {
+        return context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
+    }
+
+    static long getDiscoverableEndTimestamp(Context context) {
+        return getSharedPreferences(context).getLong(
+                KEY_DISCOVERABLE_END_TIMESTAMP, 0);
+    }
+
+    static boolean shouldShowDialogInForeground(Context context,
+            String deviceAddress) {
+        LocalBluetoothManager manager = LocalBluetoothManager.getInstance(context);
+        if (manager == null) {
+            return false;
+        }
+
+        // If Bluetooth Settings is visible
+        if (manager.isForegroundActivity()) {
+            return true;
+        }
+
+        long currentTimeMillis = System.currentTimeMillis();
+        SharedPreferences sharedPreferences = getSharedPreferences(context);
+
+        // If the device was in discoverABLE mode recently
+        long lastDiscoverableEndTime = sharedPreferences.getLong(
+                KEY_DISCOVERABLE_END_TIMESTAMP, 0);
+        if ((lastDiscoverableEndTime + GRACE_PERIOD_TO_SHOW_DIALOGS_IN_FOREGROUND)
+                > currentTimeMillis) {
+            return true;
+        }
+
+        // If the device was discoverING recently
+        LocalBluetoothAdapter adapter = manager.getBluetoothAdapter();
+        if (adapter != null && adapter.isDiscovering()) {
+            return true;
+        } else if ((sharedPreferences.getLong(KEY_DISCOVERING_TIMESTAMP, 0) +
+                GRACE_PERIOD_TO_SHOW_DIALOGS_IN_FOREGROUND) > currentTimeMillis) {
+            return true;
+        }
+
+        // If the device was picked in the device picker recently
+        if (deviceAddress != null) {
+            String lastSelectedDevice = sharedPreferences.getString(
+                    KEY_LAST_SELECTED_DEVICE, null);
+
+            if (deviceAddress.equals(lastSelectedDevice)) {
+                long lastDeviceSelectedTime = sharedPreferences.getLong(
+                        KEY_LAST_SELECTED_DEVICE_TIME, 0);
+                if ((lastDeviceSelectedTime + GRACE_PERIOD_TO_SHOW_DIALOGS_IN_FOREGROUND)
+                        > currentTimeMillis) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    static void persistSelectedDeviceInPicker(Context context, String deviceAddress) {
+        SharedPreferences.Editor editor = getSharedPreferences(context).edit();
+        editor.putString(KEY_LAST_SELECTED_DEVICE,
+                deviceAddress);
+        editor.putLong(KEY_LAST_SELECTED_DEVICE_TIME,
+                System.currentTimeMillis());
+        editor.apply();
+    }
+
+    static void persistDiscoverableEndTimestamp(Context context, long endTimestamp) {
+        SharedPreferences.Editor editor = getSharedPreferences(context).edit();
+        editor.putLong(KEY_DISCOVERABLE_END_TIMESTAMP, endTimestamp);
+        editor.apply();
+    }
+
+    static void persistDiscoveringTimestamp(final Context context) {
+        // Load the shared preferences and edit it on a background
+        // thread (but serialized!).
+        QueuedWork.singleThreadExecutor().submit(new Runnable() {
+                public void run() {
+                    SharedPreferences.Editor editor = getSharedPreferences(context).edit();
+                    editor.putLong(
+                            KEY_DISCOVERING_TIMESTAMP,
+                        System.currentTimeMillis());
+                    editor.apply();
+                }
+            });
+    }
+
+    static boolean hasDockAutoConnectSetting(Context context, String addr) {
+        return getSharedPreferences(context).contains(KEY_DOCK_AUTO_CONNECT + addr);
+    }
+
+    static boolean getDockAutoConnectSetting(Context context, String addr) {
+        return getSharedPreferences(context).getBoolean(KEY_DOCK_AUTO_CONNECT + addr,
+                false);
+    }
+
+    static void saveDockAutoConnectSetting(Context context, String addr, boolean autoConnect) {
+        SharedPreferences.Editor editor = getSharedPreferences(context).edit();
+        editor.putBoolean(KEY_DOCK_AUTO_CONNECT + addr, autoConnect);
+        editor.apply();
+    }
+
+    static void removeDockAutoConnectSetting(Context context, String addr) {
+        SharedPreferences.Editor editor = getSharedPreferences(context).edit();
+        editor.remove(KEY_DOCK_AUTO_CONNECT + addr);
+        editor.apply();
+    }
+}
diff --git a/src/com/android/settings/bluetooth/LocalBluetoothProfile.java b/src/com/android/settings/bluetooth/LocalBluetoothProfile.java
new file mode 100644
index 0000000..936231a
--- /dev/null
+++ b/src/com/android/settings/bluetooth/LocalBluetoothProfile.java
@@ -0,0 +1,76 @@
+/*
+ * 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.bluetooth.BluetoothClass;
+import android.bluetooth.BluetoothDevice;
+
+/**
+ * LocalBluetoothProfile is an interface defining the basic
+ * functionality related to a Bluetooth profile.
+ */
+interface LocalBluetoothProfile {
+
+    /**
+     * Returns true if the user can initiate a connection, false otherwise.
+     */
+    boolean isConnectable();
+
+    /**
+     * Returns true if the user can enable auto connection for this profile.
+     */
+    boolean isAutoConnectable();
+
+    boolean connect(BluetoothDevice device);
+
+    boolean disconnect(BluetoothDevice device);
+
+    int getConnectionStatus(BluetoothDevice device);
+
+    boolean isPreferred(BluetoothDevice device);
+
+    int getPreferred(BluetoothDevice device);
+
+    void setPreferred(BluetoothDevice device, boolean preferred);
+
+    boolean isProfileReady();
+
+    /** Display order for device profile settings. */
+    int getOrdinal();
+
+    /**
+     * Returns the string resource ID for the localized name for this profile.
+     */
+    int getNameResource();
+
+    /**
+     * Returns the string resource ID for the disconnect confirmation text
+     * for this profile.
+     */
+    int getDisconnectResource();
+
+    /**
+     * Returns the string resource ID for the summary text for this profile
+     * for the specified device, e.g. "Use for media audio" or
+     * "Connected to media audio".
+     * @param device the device to query for profile connection status
+     * @return a string resource ID for the profile summary text
+     */
+    int getSummaryResourceForDevice(BluetoothDevice device);
+
+    int getDrawableResource(BluetoothClass btClass);
+}
diff --git a/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java b/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java
index 164d2da..0bb6f11 100644
--- a/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java
+++ b/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 The Android Open Source Project
+ * 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.
@@ -16,67 +16,37 @@
 
 package com.android.settings.bluetooth;
 
-import com.android.settings.R;
-
 import android.bluetooth.BluetoothA2dp;
-import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothHeadset;
 import android.bluetooth.BluetoothInputDevice;
 import android.bluetooth.BluetoothPan;
 import android.bluetooth.BluetoothProfile;
 import android.bluetooth.BluetoothUuid;
-import android.os.Handler;
+import android.content.Context;
+import android.content.Intent;
 import android.os.ParcelUuid;
 import android.util.Log;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
 import java.util.Map;
 
 /**
- * LocalBluetoothProfileManager is an abstract class defining the basic
- * functionality related to a profile.
+ * LocalBluetoothProfileManager provides access to the LocalBluetoothProfile
+ * objects for the available Bluetooth profiles.
  */
-abstract class LocalBluetoothProfileManager {
+final class LocalBluetoothProfileManager {
     private static final String TAG = "LocalBluetoothProfileManager";
 
-    /* package */ static final ParcelUuid[] HEADSET_PROFILE_UUIDS = new ParcelUuid[] {
-        BluetoothUuid.HSP,
-        BluetoothUuid.Handsfree,
-    };
-
-    /* package */ static final ParcelUuid[] A2DP_SINK_PROFILE_UUIDS = new ParcelUuid[] {
-        BluetoothUuid.AudioSink,
-        BluetoothUuid.AdvAudioDist,
-    };
-
-    /* package */ static final ParcelUuid[] A2DP_SRC_PROFILE_UUIDS = new ParcelUuid[] {
-        BluetoothUuid.AudioSource
-    };
-
-    /* package */ static final ParcelUuid[] OPP_PROFILE_UUIDS = new ParcelUuid[] {
-        BluetoothUuid.ObexObjectPush
-    };
-
-    /* package */ static final ParcelUuid[] HID_PROFILE_UUIDS = new ParcelUuid[] {
-        BluetoothUuid.Hid
-    };
-
-    /* package */ static final ParcelUuid[] PANU_PROFILE_UUIDS = new ParcelUuid[] {
-        BluetoothUuid.PANU
-    };
-
-    /* package */ static final ParcelUuid[] NAP_PROFILE_UUIDS = new ParcelUuid[] {
-        BluetoothUuid.NAP
-    };
+    /** Singleton instance. */
+    private static LocalBluetoothProfileManager sInstance;
 
     /**
      * An interface for notifying BluetoothHeadset IPC clients when they have
      * been connected to the BluetoothHeadset service.
+     * Only used by {@link DockService}.
      */
     public interface ServiceListener {
         /**
@@ -85,7 +55,7 @@
          * this callback before making IPC calls on the BluetoothHeadset
          * service.
          */
-        public void onServiceConnected();
+        void onServiceConnected();
 
         /**
          * Called to notify the client that this proxy object has been
@@ -94,743 +64,246 @@
          * This callback will currently only occur if the application hosting
          * the BluetoothHeadset service, but may be called more often in future.
          */
-        public void onServiceDisconnected();
+        void onServiceDisconnected();
     }
 
-    // TODO: close profiles when we're shutting down
-    private static final Map<Profile, LocalBluetoothProfileManager> sProfileMap =
-            new HashMap<Profile, LocalBluetoothProfileManager>();
+    private final Context mContext;
+    private final LocalBluetoothAdapter mLocalAdapter;
+    private final CachedBluetoothDeviceManager mDeviceManager;
+    private final BluetoothEventManager mEventManager;
 
-    protected final LocalBluetoothManager mLocalManager;
+    private A2dpProfile mA2dpProfile;
+    private HeadsetProfile mHeadsetProfile;
+    private final HidProfile mHidProfile;
+    private OppProfile mOppProfile;
+    private final PanProfile mPanProfile;
 
-    public static void init(LocalBluetoothManager localManager) {
-        synchronized (sProfileMap) {
-            if (sProfileMap.size() == 0) {
-                LocalBluetoothProfileManager profileManager;
+    /**
+     * Mapping from profile name, e.g. "HEADSET" to profile object.
+     */
+    private final Map<String, LocalBluetoothProfile>
+            mProfileNameMap = new HashMap<String, LocalBluetoothProfile>();
 
-                profileManager = new A2dpProfileManager(localManager);
-                sProfileMap.put(Profile.A2DP, profileManager);
+    LocalBluetoothProfileManager(Context context,
+            LocalBluetoothAdapter adapter,
+            CachedBluetoothDeviceManager deviceManager,
+            BluetoothEventManager eventManager) {
+        mContext = context;
 
-                profileManager = new HeadsetProfileManager(localManager);
-                sProfileMap.put(Profile.HEADSET, profileManager);
+        mLocalAdapter = adapter;
+        mDeviceManager = deviceManager;
+        mEventManager = eventManager;
+        // pass this reference to adapter and event manager (circular dependency)
+        mLocalAdapter.setProfileManager(this);
+        mEventManager.setProfileManager(this);
 
-                profileManager = new OppProfileManager(localManager);
-                sProfileMap.put(Profile.OPP, profileManager);
+        ParcelUuid[] uuids = adapter.getUuids();
 
-                profileManager = new HidProfileManager(localManager);
-                sProfileMap.put(Profile.HID, profileManager);
+        // uuids may be null if Bluetooth is turned off
+        if (uuids != null) {
+            updateLocalProfiles(uuids);
+        }
 
-                profileManager = new PanProfileManager(localManager);
-                sProfileMap.put(Profile.PAN, profileManager);
+        // Always add HID and PAN profiles
+        mHidProfile = new HidProfile(context, mLocalAdapter);
+        addProfile(mHidProfile, HidProfile.NAME,
+                BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED);
+
+        mPanProfile = new PanProfile(context);
+        addProfile(mPanProfile, PanProfile.NAME, BluetoothPan.ACTION_CONNECTION_STATE_CHANGED);
+        Log.d(TAG, "LocalBluetoothProfileManager construction complete");
+    }
+
+    /**
+     * Initialize or update the local profile objects. If a UUID was previously
+     * present but has been removed, we print a warning but don't remove the
+     * profile object as it might be referenced elsewhere, or the UUID might
+     * come back and we don't want multiple copies of the profile objects.
+     * @param uuids
+     */
+    void updateLocalProfiles(ParcelUuid[] uuids) {
+        // A2DP
+        if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.AudioSource)) {
+            if (mA2dpProfile == null) {
+                Log.d(TAG, "Adding local A2DP profile");
+                mA2dpProfile = new A2dpProfile(mContext);
+                addProfile(mA2dpProfile, A2dpProfile.NAME,
+                        BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
             }
-        }
-    }
-
-    // TODO(): Combine the init and updateLocalProfiles codes.
-    // init can get called from various paths, it makes no sense to add and then delete.
-    public static void updateLocalProfiles(LocalBluetoothManager localManager, ParcelUuid[] uuids) {
-        if (!BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Handsfree_AG) &&
-            !BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.HSP_AG)) {
-            sProfileMap.remove(Profile.HEADSET);
+        } else if (mA2dpProfile != null) {
+            Log.w(TAG, "Warning: A2DP profile was previously added but the UUID is now missing.");
         }
 
-        if (!BluetoothUuid.containsAnyUuid(uuids, A2DP_SRC_PROFILE_UUIDS)) {
-            sProfileMap.remove(Profile.A2DP);
+        // Headset / Handsfree
+        if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Handsfree_AG) ||
+            BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.HSP_AG)) {
+            if (mHeadsetProfile == null) {
+                Log.d(TAG, "Adding local HEADSET profile");
+                mHeadsetProfile = new HeadsetProfile(mContext, mLocalAdapter,
+                        mDeviceManager, this);
+                addProfile(mHeadsetProfile, HeadsetProfile.NAME,
+                        BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
+            }
+        } else if (mHeadsetProfile != null) {
+            Log.w(TAG, "Warning: HEADSET profile was previously added but the UUID is now missing.");
         }
 
-        if (!BluetoothUuid.containsAnyUuid(uuids, OPP_PROFILE_UUIDS)) {
-            sProfileMap.remove(Profile.OPP);
+        // OPP
+        if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.ObexObjectPush)) {
+            if (mOppProfile == null) {
+                Log.d(TAG, "Adding local OPP profile");
+                mOppProfile = new OppProfile();
+                // Note: no event handler for OPP, only name map.
+                mProfileNameMap.put(OppProfile.NAME, mOppProfile);
+            }
+        } else if (mOppProfile != null) {
+            Log.w(TAG, "Warning: OPP profile was previously added but the UUID is now missing.");
         }
 
         // There is no local SDP record for HID and Settings app doesn't control PBAP
     }
 
-    private static final LinkedList<ServiceListener> mServiceListeners =
-            new LinkedList<ServiceListener>();
+    private final Collection<ServiceListener> mServiceListeners =
+            new ArrayList<ServiceListener>();
 
-    public static void addServiceListener(ServiceListener l) {
-        mServiceListeners.add(l);
+    private void addProfile(LocalBluetoothProfile profile,
+            String profileName, String stateChangedAction) {
+        mEventManager.addHandler(stateChangedAction, new StateChangedHandler(profile));
+        mProfileNameMap.put(profileName, profile);
     }
 
-    public static void removeServiceListener(ServiceListener l) {
-        mServiceListeners.remove(l);
+    LocalBluetoothProfile getProfileByName(String name) {
+        return mProfileNameMap.get(name);
     }
 
-    public static boolean isManagerReady() {
-        // Getting just the headset profile is fine for now. Will need to deal with A2DP
-        // and others if they aren't always in a ready state.
-        LocalBluetoothProfileManager profileManager = sProfileMap.get(Profile.HEADSET);
-        if (profileManager == null) {
-            return sProfileMap.size() > 0;
+    // Called from LocalBluetoothAdapter when state changes to ON
+    void setBluetoothStateOn() {
+        ParcelUuid[] uuids = mLocalAdapter.getUuids();
+        if (uuids != null) {
+            updateLocalProfiles(uuids);
         }
-        return profileManager.isProfileReady();
-    }
-
-    public static LocalBluetoothProfileManager getProfileManager(LocalBluetoothManager localManager,
-            Profile profile) {
-        // Note: This code assumes that "localManager" is same as the
-        // LocalBluetoothManager that was used to initialize the sProfileMap.
-        // If that every changes, we can't just keep one copy of sProfileMap.
-        synchronized (sProfileMap) {
-            LocalBluetoothProfileManager profileManager = sProfileMap.get(profile);
-            if (profileManager == null) {
-                Log.e(TAG, "profileManager can't be found for " + profile.toString());
-            }
-            return profileManager;
-        }
+        mEventManager.readPairedDevices();
     }
 
     /**
-     * Temporary method to fill profiles based on a device's class.
+     * Generic handler for connection state change events for the specified profile.
+     */
+    private class StateChangedHandler implements BluetoothEventManager.Handler {
+        private final LocalBluetoothProfile mProfile;
+
+        StateChangedHandler(LocalBluetoothProfile profile) {
+            mProfile = profile;
+        }
+
+        public void onReceive(Context context, Intent intent, BluetoothDevice device) {
+            CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(device);
+            if (cachedDevice == null) {
+                Log.w(TAG, "StateChangedHandler found new device: " + device);
+                cachedDevice = mDeviceManager.addDevice(mLocalAdapter,
+                        LocalBluetoothProfileManager.this, device);
+            }
+            int newState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, 0);
+            int oldState = intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, 0);
+            if (newState == BluetoothProfile.STATE_DISCONNECTED &&
+                    oldState == BluetoothProfile.STATE_CONNECTING) {
+                Log.i(TAG, "Failed to connect " + mProfile + " device");
+            }
+
+            cachedDevice.onProfileStateChanged(mProfile, newState);
+            cachedDevice.refresh();
+        }
+    }
+
+    // called from DockService
+    void addServiceListener(ServiceListener l) {
+        mServiceListeners.add(l);
+    }
+
+    // called from DockService
+    void removeServiceListener(ServiceListener l) {
+        mServiceListeners.remove(l);
+    }
+
+    // not synchronized: use only from UI thread! (TODO: verify)
+    void callServiceConnectedListeners() {
+        for (ServiceListener l : mServiceListeners) {
+            l.onServiceConnected();
+        }
+    }
+
+    // not synchronized: use only from UI thread! (TODO: verify)
+    void callServiceDisconnectedListeners() {
+        for (ServiceListener listener : mServiceListeners) {
+            listener.onServiceDisconnected();
+        }
+    }
+
+    // This is called by DockService, so check Headset and A2DP.
+    public synchronized boolean isManagerReady() {
+        // Getting just the headset profile is fine for now. Will need to deal with A2DP
+        // and others if they aren't always in a ready state.
+        LocalBluetoothProfile profile = mHeadsetProfile;
+        if (profile != null) {
+            return profile.isProfileReady();
+        }
+        profile = mA2dpProfile;
+        if (profile != null) {
+            return profile.isProfileReady();
+        }
+        return false;
+    }
+
+    A2dpProfile getA2dpProfile() {
+        return mA2dpProfile;
+    }
+
+    HeadsetProfile getHeadsetProfile() {
+        return mHeadsetProfile;
+    }
+
+    /**
+     * Fill in a list of LocalBluetoothProfile objects that are supported by
+     * the local device and the remote device.
      *
-     * NOTE: This list happens to define the connection order. We should put this logic in a more
-     * well known place when this method is no longer temporary.
      * @param uuids of the remote device
      * @param localUuids UUIDs of the local device
      * @param profiles The list of profiles to fill
      */
-    public static void updateProfiles(ParcelUuid[] uuids, ParcelUuid[] localUuids,
-        List<Profile> profiles) {
+    synchronized void updateProfiles(ParcelUuid[] uuids, ParcelUuid[] localUuids,
+        Collection<LocalBluetoothProfile> profiles) {
         profiles.clear();
 
         if (uuids == null) {
             return;
         }
 
-        if (sProfileMap.containsKey(Profile.HEADSET)) {
+        if (mHeadsetProfile != null) {
             if ((BluetoothUuid.isUuidPresent(localUuids, BluetoothUuid.HSP_AG) &&
                 BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.HSP)) ||
                 (BluetoothUuid.isUuidPresent(localUuids, BluetoothUuid.Handsfree_AG) &&
                 BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Handsfree))) {
-                    profiles.add(Profile.HEADSET);
+                    profiles.add(mHeadsetProfile);
             }
         }
 
-
-        if (BluetoothUuid.containsAnyUuid(uuids, A2DP_SINK_PROFILE_UUIDS) &&
-            sProfileMap.containsKey(Profile.A2DP)) {
-            profiles.add(Profile.A2DP);
+        if (BluetoothUuid.containsAnyUuid(uuids, A2dpProfile.SINK_UUIDS) &&
+            mA2dpProfile != null) {
+            profiles.add(mA2dpProfile);
         }
 
-        if (BluetoothUuid.containsAnyUuid(uuids, OPP_PROFILE_UUIDS) &&
-            sProfileMap.containsKey(Profile.OPP)) {
-            profiles.add(Profile.OPP);
+        if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.ObexObjectPush) &&
+            mOppProfile != null) {
+            profiles.add(mOppProfile);
         }
 
-        if (BluetoothUuid.containsAnyUuid(uuids, HID_PROFILE_UUIDS) &&
-            sProfileMap.containsKey(Profile.HID)) {
-            profiles.add(Profile.HID);
+        if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Hid) &&
+            mHidProfile != null) {
+            profiles.add(mHidProfile);
         }
 
-        if (BluetoothUuid.containsAnyUuid(uuids, NAP_PROFILE_UUIDS) &&
-            sProfileMap.containsKey(Profile.PAN)) {
-            profiles.add(Profile.PAN);
-        }
-    }
-
-    protected LocalBluetoothProfileManager(LocalBluetoothManager localManager) {
-        mLocalManager = localManager;
-    }
-
-    public abstract List<BluetoothDevice> getConnectedDevices();
-
-    public abstract boolean connect(BluetoothDevice device);
-
-    public abstract boolean disconnect(BluetoothDevice device);
-
-    public abstract int getConnectionStatus(BluetoothDevice device);
-
-    public abstract int getSummary(BluetoothDevice device);
-
-    public abstract int convertState(int a2dpState);
-
-    public abstract boolean isPreferred(BluetoothDevice device);
-
-    public abstract int getPreferred(BluetoothDevice device);
-
-    public abstract void setPreferred(BluetoothDevice device, boolean preferred);
-
-    public boolean isConnected(BluetoothDevice device) {
-        return SettingsBtStatus.isConnectionStatusConnected(getConnectionStatus(device));
-    }
-
-    public abstract boolean isProfileReady();
-
-    public abstract int getDrawableResource();
-
-    public static enum Profile {
-        HEADSET(R.string.bluetooth_profile_headset, true, true),
-        A2DP(R.string.bluetooth_profile_a2dp, true, true),
-        OPP(R.string.bluetooth_profile_opp, false, false),
-        HID(R.string.bluetooth_profile_hid, true, true),
-        PAN(R.string.bluetooth_profile_pan, true, false);
-
-        public final int localizedString;
-        private final boolean mConnectable;
-        private final boolean mAutoConnectable;
-
-        private Profile(int localizedString, boolean connectable,
-                boolean autoConnectable) {
-            this.localizedString = localizedString;
-            this.mConnectable = connectable;
-            this.mAutoConnectable = autoConnectable;
-        }
-
-        public boolean isConnectable() {
-            return mConnectable;
-        }
-
-        public boolean isAutoConnectable() {
-            return mAutoConnectable;
-        }
-    }
-
-    /**
-     * A2dpProfileManager is an abstraction for the {@link BluetoothA2dp} service.
-     */
-    private static class A2dpProfileManager extends LocalBluetoothProfileManager
-          implements BluetoothProfile.ServiceListener {
-        private BluetoothA2dp mService;
-
-        // TODO(): The calls must wait for mService. Its not null just
-        // because it runs in the system server.
-        public A2dpProfileManager(LocalBluetoothManager localManager) {
-            super(localManager);
-            BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-            adapter.getProfileProxy(localManager.getContext(), this, BluetoothProfile.A2DP);
-
-        }
-
-        public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            mService = (BluetoothA2dp) proxy;
-        }
-
-        public void onServiceDisconnected(int profile) {
-            mService = null;
-        }
-
-        @Override
-        public List<BluetoothDevice> getConnectedDevices() {
-            return mService.getDevicesMatchingConnectionStates(
-                  new int[] {BluetoothProfile.STATE_CONNECTED,
-                             BluetoothProfile.STATE_CONNECTING,
-                             BluetoothProfile.STATE_DISCONNECTING});
-        }
-
-        @Override
-        public boolean connect(BluetoothDevice device) {
-            List<BluetoothDevice> sinks = getConnectedDevices();
-            if (sinks != null) {
-                for (BluetoothDevice sink : sinks) {
-                    mService.disconnect(sink);
-                }
-            }
-            return mService.connect(device);
-        }
-
-        @Override
-        public boolean disconnect(BluetoothDevice device) {
-            // Downgrade priority as user is disconnecting the sink.
-            if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) {
-                mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
-            }
-            return mService.disconnect(device);
-        }
-
-        @Override
-        public int getConnectionStatus(BluetoothDevice device) {
-            return convertState(mService.getConnectionState(device));
-        }
-
-        @Override
-        public int getSummary(BluetoothDevice device) {
-            int connectionStatus = getConnectionStatus(device);
-
-            if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus)) {
-                return R.string.bluetooth_a2dp_profile_summary_connected;
-            } else {
-                return SettingsBtStatus.getConnectionStatusSummary(connectionStatus);
-            }
-        }
-
-        @Override
-        public boolean isPreferred(BluetoothDevice device) {
-            return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
-        }
-
-        @Override
-        public int getPreferred(BluetoothDevice device) {
-            return mService.getPriority(device);
-        }
-
-        @Override
-        public void setPreferred(BluetoothDevice device, boolean preferred) {
-            if (preferred) {
-                if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
-                    mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
-                }
-            } else {
-                mService.setPriority(device, BluetoothProfile.PRIORITY_OFF);
-            }
-        }
-
-        @Override
-        public int convertState(int a2dpState) {
-            switch (a2dpState) {
-            case BluetoothProfile.STATE_CONNECTED:
-                return SettingsBtStatus.CONNECTION_STATUS_CONNECTED;
-            case BluetoothProfile.STATE_CONNECTING:
-                return SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
-            case BluetoothProfile.STATE_DISCONNECTED:
-                return SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED;
-            case BluetoothProfile.STATE_DISCONNECTING:
-                return SettingsBtStatus.CONNECTION_STATUS_DISCONNECTING;
-            case BluetoothA2dp.STATE_PLAYING:
-                return SettingsBtStatus.CONNECTION_STATUS_ACTIVE;
-            default:
-                return SettingsBtStatus.CONNECTION_STATUS_UNKNOWN;
-            }
-        }
-
-        @Override
-        public boolean isProfileReady() {
-            return true;
-        }
-
-        @Override
-        public int getDrawableResource() {
-            return R.drawable.ic_bt_headphones_a2dp;
-        }
-    }
-
-    /**
-     * HeadsetProfileManager is an abstraction for the {@link BluetoothHeadset} service.
-     */
-    private static class HeadsetProfileManager extends LocalBluetoothProfileManager
-            implements BluetoothProfile.ServiceListener {
-        private BluetoothHeadset mService;
-        private final Handler mUiHandler = new Handler();
-        private boolean profileReady = false;
-
-        // TODO(): The calls must get queued if mService becomes null.
-        // It can happen  when phone app crashes for some reason.
-        // All callers should have service listeners. Dock Service is the only
-        // one right now.
-        public HeadsetProfileManager(LocalBluetoothManager localManager) {
-            super(localManager);
-            BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-            adapter.getProfileProxy(localManager.getContext(), this, BluetoothProfile.HEADSET);
-        }
-
-        public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            mService = (BluetoothHeadset) proxy;
-            profileReady = true;
-            // This could be called on a non-UI thread, funnel to UI thread.
-            mUiHandler.post(new Runnable() {
-                public void run() {
-                    /*
-                     * We just bound to the service, so refresh the UI of the
-                     * headset device.
-                     */
-                    List<BluetoothDevice> deviceList = mService.getConnectedDevices();
-                    if (deviceList.size() == 0) return;
-
-                    mLocalManager.getCachedDeviceManager()
-                            .onProfileStateChanged(deviceList.get(0), Profile.HEADSET,
-                                                   BluetoothProfile.STATE_CONNECTED);
-                }
-            });
-
-            if (mServiceListeners.size() > 0) {
-                Iterator<ServiceListener> it = mServiceListeners.iterator();
-                while(it.hasNext()) {
-                    it.next().onServiceConnected();
-                }
-            }
-        }
-
-        public void onServiceDisconnected(int profile) {
-            mService = null;
-            profileReady = false;
-            if (mServiceListeners.size() > 0) {
-                Iterator<ServiceListener> it = mServiceListeners.iterator();
-                while(it.hasNext()) {
-                    it.next().onServiceDisconnected();
-                }
-            }
-        }
-
-        @Override
-        public boolean isProfileReady() {
-            return profileReady;
-        }
-
-        @Override
-        public List<BluetoothDevice> getConnectedDevices() {
-            if (mService != null) {
-                return mService.getConnectedDevices();
-            } else {
-                return new ArrayList<BluetoothDevice>();
-            }
-        }
-
-        @Override
-        public boolean connect(BluetoothDevice device) {
-            List<BluetoothDevice> sinks = getConnectedDevices();
-            if (sinks != null) {
-                for (BluetoothDevice sink : sinks) {
-                    mService.disconnect(sink);
-                }
-            }
-            return mService.connect(device);
-        }
-
-        @Override
-        public boolean disconnect(BluetoothDevice device) {
-            List<BluetoothDevice> deviceList = getConnectedDevices();
-            if (deviceList.size() != 0 && deviceList.get(0).equals(device)) {
-                // Downgrade priority as user is disconnecting the headset.
-                if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) {
-                    mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
-                }
-                return mService.disconnect(device);
-            } else {
-                return false;
-            }
-        }
-
-        @Override
-        public int getConnectionStatus(BluetoothDevice device) {
-            List<BluetoothDevice> deviceList = getConnectedDevices();
-
-            return deviceList.size() > 0 && deviceList.get(0).equals(device)
-                    ? convertState(mService.getConnectionState(device))
-                    : SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED;
-        }
-
-        @Override
-        public int getSummary(BluetoothDevice device) {
-            int connectionStatus = getConnectionStatus(device);
-
-            if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus)) {
-                return R.string.bluetooth_headset_profile_summary_connected;
-            } else {
-                return SettingsBtStatus.getConnectionStatusSummary(connectionStatus);
-            }
-        }
-
-        @Override
-        public boolean isPreferred(BluetoothDevice device) {
-            return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
-        }
-
-        @Override
-        public int getPreferred(BluetoothDevice device) {
-            return mService.getPriority(device);
-        }
-
-        @Override
-        public void setPreferred(BluetoothDevice device, boolean preferred) {
-            if (preferred) {
-                if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
-                    mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
-                }
-            } else {
-                mService.setPriority(device, BluetoothProfile.PRIORITY_OFF);
-            }
-        }
-
-        @Override
-        public int convertState(int headsetState) {
-            switch (headsetState) {
-            case BluetoothProfile.STATE_CONNECTED:
-                return SettingsBtStatus.CONNECTION_STATUS_CONNECTED;
-            case BluetoothProfile.STATE_CONNECTING:
-                return SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
-            case BluetoothProfile.STATE_DISCONNECTED:
-                return SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED;
-            default:
-                return SettingsBtStatus.CONNECTION_STATUS_UNKNOWN;
-            }
-        }
-
-        @Override
-        public int getDrawableResource() {
-            return R.drawable.ic_bt_headset_hfp;
-        }
-    }
-
-    /**
-     * OppProfileManager
-     */
-    private static class OppProfileManager extends LocalBluetoothProfileManager {
-
-        public OppProfileManager(LocalBluetoothManager localManager) {
-            super(localManager);
-        }
-
-        @Override
-        public List<BluetoothDevice> getConnectedDevices() {
-            return null;
-        }
-
-        @Override
-        public boolean connect(BluetoothDevice device) {
-            return false;
-        }
-
-        @Override
-        public boolean disconnect(BluetoothDevice device) {
-            return false;
-        }
-
-        @Override
-        public int getConnectionStatus(BluetoothDevice device) {
-            return -1;
-        }
-
-        @Override
-        public int getSummary(BluetoothDevice device) {
-            int connectionStatus = getConnectionStatus(device);
-
-            if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus)) {
-                return R.string.bluetooth_opp_profile_summary_connected;
-            } else {
-                return R.string.bluetooth_opp_profile_summary_not_connected;
-            }
-        }
-
-        @Override
-        public boolean isPreferred(BluetoothDevice device) {
-            return false;
-        }
-
-        @Override
-        public int getPreferred(BluetoothDevice device) {
-            return -1;
-        }
-
-        @Override
-        public void setPreferred(BluetoothDevice device, boolean preferred) {
-        }
-
-        @Override
-        public boolean isProfileReady() {
-            return true;
-        }
-
-        @Override
-        public int convertState(int oppState) {
-            switch (oppState) {
-            case 0:
-                return SettingsBtStatus.CONNECTION_STATUS_CONNECTED;
-            case 1:
-                return SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
-            case 2:
-                return SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED;
-            default:
-                return SettingsBtStatus.CONNECTION_STATUS_UNKNOWN;
-            }
-        }
-
-        @Override
-        public int getDrawableResource() {
-            return 0;   // no icon for OPP
-        }
-    }
-
-    private static class HidProfileManager extends LocalBluetoothProfileManager
-            implements BluetoothProfile.ServiceListener {
-        private BluetoothInputDevice mService;
-
-        public HidProfileManager(LocalBluetoothManager localManager) {
-            super(localManager);
-            BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-            adapter.getProfileProxy(localManager.getContext(), this, BluetoothProfile.INPUT_DEVICE);
-        }
-
-        public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            mService = (BluetoothInputDevice) proxy;
-        }
-
-        public void onServiceDisconnected(int profile) {
-            mService = null;
-        }
-
-        @Override
-        public boolean connect(BluetoothDevice device) {
-            return mService.connect(device);
-        }
-
-        @Override
-        public int convertState(int hidState) {
-            switch (hidState) {
-            case BluetoothProfile.STATE_CONNECTED:
-                return SettingsBtStatus.CONNECTION_STATUS_CONNECTED;
-            case BluetoothProfile.STATE_CONNECTING:
-                return SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
-            case BluetoothProfile.STATE_DISCONNECTED:
-                return SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED;
-            case BluetoothProfile.STATE_DISCONNECTING:
-                return SettingsBtStatus.CONNECTION_STATUS_DISCONNECTING;
-            default:
-                return SettingsBtStatus.CONNECTION_STATUS_UNKNOWN;
-            }
-        }
-
-        @Override
-        public boolean disconnect(BluetoothDevice device) {
-            return mService.disconnect(device);
-        }
-
-        @Override
-        public List<BluetoothDevice> getConnectedDevices() {
-            return mService.getConnectedDevices();
-        }
-
-        @Override
-        public int getConnectionStatus(BluetoothDevice device) {
-            return convertState(mService.getConnectionState(device));
-        }
-
-        @Override
-        public int getPreferred(BluetoothDevice device) {
-            return mService.getPriority(device);
-        }
-
-        @Override
-        public int getSummary(BluetoothDevice device) {
-            final int connectionStatus = getConnectionStatus(device);
-
-            if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus)) {
-                return R.string.bluetooth_hid_profile_summary_connected;
-            } else {
-                return SettingsBtStatus.getConnectionStatusSummary(connectionStatus);
-            }
-        }
-
-        @Override
-        public boolean isPreferred(BluetoothDevice device) {
-            return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
-        }
-
-        @Override
-        public boolean isProfileReady() {
-            return true;
-        }
-
-        @Override
-        public void setPreferred(BluetoothDevice device, boolean preferred) {
-            if (preferred) {
-                if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
-                    mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
-                }
-            } else {
-                mService.setPriority(device, BluetoothProfile.PRIORITY_OFF);
-            }
-        }
-
-        @Override
-        public int getDrawableResource() {
-            return R.drawable.ic_bt_keyboard_hid;
-        }
-    }
-
-    private static class PanProfileManager extends LocalBluetoothProfileManager
-            implements BluetoothProfile.ServiceListener {
-        private BluetoothPan mService;
-
-        public PanProfileManager(LocalBluetoothManager localManager) {
-            super(localManager);
-            BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-            adapter.getProfileProxy(localManager.getContext(), this, BluetoothProfile.PAN);
-        }
-
-        public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            mService = (BluetoothPan) proxy;
-        }
-
-        public void onServiceDisconnected(int profile) {
-            mService = null;
-        }
-
-        @Override
-        public boolean connect(BluetoothDevice device) {
-            List<BluetoothDevice> sinks = getConnectedDevices();
-            if (sinks != null) {
-                for (BluetoothDevice sink : sinks) {
-                    mService.disconnect(sink);
-                }
-            }
-            return mService.connect(device);
-        }
-
-        @Override
-        public int convertState(int panState) {
-            switch (panState) {
-            case BluetoothPan.STATE_CONNECTED:
-                return SettingsBtStatus.CONNECTION_STATUS_CONNECTED;
-            case BluetoothPan.STATE_CONNECTING:
-                return SettingsBtStatus.CONNECTION_STATUS_CONNECTING;
-            case BluetoothPan.STATE_DISCONNECTED:
-                return SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED;
-            case BluetoothPan.STATE_DISCONNECTING:
-                return SettingsBtStatus.CONNECTION_STATUS_DISCONNECTING;
-            default:
-                return SettingsBtStatus.CONNECTION_STATUS_UNKNOWN;
-            }
-        }
-
-        @Override
-        public boolean disconnect(BluetoothDevice device) {
-            return mService.disconnect(device);
-        }
-
-        @Override
-        public int getSummary(BluetoothDevice device) {
-            final int connectionStatus = getConnectionStatus(device);
-
-            if (SettingsBtStatus.isConnectionStatusConnected(connectionStatus)) {
-                return R.string.bluetooth_pan_profile_summary_connected;
-            } else {
-                return SettingsBtStatus.getConnectionStatusSummary(connectionStatus);
-            }
-        }
-
-        @Override
-        public boolean isProfileReady() {
-            return true;
-        }
-
-        @Override
-        public List<BluetoothDevice> getConnectedDevices() {
-            return mService.getConnectedDevices();
-        }
-
-        @Override
-        public int getConnectionStatus(BluetoothDevice device) {
-            return convertState(mService.getConnectionState(device));
-        }
-
-        @Override
-        public int getPreferred(BluetoothDevice device) {
-            return -1;
-        }
-
-        @Override
-        public boolean isPreferred(BluetoothDevice device) {
-            return true;
-        }
-
-        @Override
-        public void setPreferred(BluetoothDevice device, boolean preferred) {
-            // ignore: isPreferred is always true for PAN
-            return;
-        }
-
-        @Override
-        public int getDrawableResource() {
-            return R.drawable.ic_bt_network_pan;
+        if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.NAP) &&
+            mPanProfile != null) {
+            profiles.add(mPanProfile);
         }
     }
 }
diff --git a/src/com/android/settings/bluetooth/OppProfile.java b/src/com/android/settings/bluetooth/OppProfile.java
new file mode 100644
index 0000000..7cbae37
--- /dev/null
+++ b/src/com/android/settings/bluetooth/OppProfile.java
@@ -0,0 +1,92 @@
+/*
+ * 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.bluetooth.BluetoothClass;
+import android.bluetooth.BluetoothDevice;
+
+import com.android.settings.R;
+
+/**
+ * OppProfile handles Bluetooth OPP.
+ */
+final class OppProfile implements LocalBluetoothProfile {
+
+    static final String NAME = "OPP";
+
+    // Order of this profile in device profiles list
+    private static final int ORDINAL = 2;
+
+    public boolean isConnectable() {
+        return false;
+    }
+
+    public boolean isAutoConnectable() {
+        return false;
+    }
+
+    public boolean connect(BluetoothDevice device) {
+        return false;
+    }
+
+    public boolean disconnect(BluetoothDevice device) {
+        return false;
+    }
+
+    public int getConnectionStatus(BluetoothDevice device) {
+        return -1;  // FIXME: change to DISCONNECTED?
+    }
+
+    public boolean isPreferred(BluetoothDevice device) {
+        return false;
+    }
+
+    public int getPreferred(BluetoothDevice device) {
+        return -1;  // FIXME: is this correct?
+    }
+
+    public void setPreferred(BluetoothDevice device, boolean preferred) {
+    }
+
+    public boolean isProfileReady() {
+        return true;
+    }
+
+    public String toString() {
+        return NAME;
+    }
+
+    public int getOrdinal() {
+        return ORDINAL;
+    }
+
+    public int getNameResource() {
+        return R.string.bluetooth_profile_opp;
+    }
+
+    public int getDisconnectResource() {
+        return 0; // user must use notification to disconnect OPP transfer.
+    }
+
+    public int getSummaryResourceForDevice(BluetoothDevice device) {
+        return 0;   // OPP profile not displayed in UI
+    }
+
+    public int getDrawableResource(BluetoothClass btClass) {
+        return 0;   // no icon for OPP
+    }
+}
diff --git a/src/com/android/settings/bluetooth/PanProfile.java b/src/com/android/settings/bluetooth/PanProfile.java
new file mode 100644
index 0000000..3f456e4
--- /dev/null
+++ b/src/com/android/settings/bluetooth/PanProfile.java
@@ -0,0 +1,135 @@
+/*
+ * 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.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothClass;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothPan;
+import android.bluetooth.BluetoothProfile;
+import android.content.Context;
+
+import com.android.settings.R;
+
+import java.util.List;
+
+/**
+ * PanProfile handles Bluetooth PAN profile.
+ */
+final class PanProfile implements LocalBluetoothProfile {
+    private BluetoothPan mService;
+
+    static final String NAME = "PAN";
+
+    // Order of this profile in device profiles list
+    private static final int ORDINAL = 4;
+
+    // These callbacks run on the main thread.
+    private final class PanServiceListener
+            implements BluetoothProfile.ServiceListener {
+
+        public void onServiceConnected(int profile, BluetoothProfile proxy) {
+            mService = (BluetoothPan) proxy;
+        }
+
+        public void onServiceDisconnected(int profile) {
+            mService = null;
+        }
+    }
+
+    PanProfile(Context context) {
+        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+        adapter.getProfileProxy(context, new PanServiceListener(),
+                BluetoothProfile.PAN);
+    }
+
+    public boolean isConnectable() {
+        return true;
+    }
+
+    public boolean isAutoConnectable() {
+        return false;
+    }
+
+    public boolean connect(BluetoothDevice device) {
+        List<BluetoothDevice> sinks = mService.getConnectedDevices();
+        if (sinks != null) {
+            for (BluetoothDevice sink : sinks) {
+                mService.disconnect(sink);
+            }
+        }
+        return mService.connect(device);
+    }
+
+    public boolean disconnect(BluetoothDevice device) {
+        return mService.disconnect(device);
+    }
+
+    public int getConnectionStatus(BluetoothDevice device) {
+        return mService.getConnectionState(device);
+    }
+
+    public boolean isPreferred(BluetoothDevice device) {
+        return true;
+    }
+
+    public int getPreferred(BluetoothDevice device) {
+        return -1;
+    }
+
+    public void setPreferred(BluetoothDevice device, boolean preferred) {
+        // ignore: isPreferred is always true for PAN
+    }
+
+    public boolean isProfileReady() {
+        return true;
+    }
+
+    public String toString() {
+        return NAME;
+    }
+
+    public int getOrdinal() {
+        return ORDINAL;
+    }
+
+    public int getNameResource() {
+        return R.string.bluetooth_profile_pan;
+    }
+
+    public int getDisconnectResource() {
+        return R.string.bluetooth_disconnect_pan_profile;
+    }
+
+    public int getSummaryResourceForDevice(BluetoothDevice device) {
+        int state = mService.getConnectionState(device);
+        switch (state) {
+            case BluetoothProfile.STATE_DISCONNECTED:
+                return R.string.bluetooth_pan_profile_summary_use_for;
+
+            case BluetoothProfile.STATE_CONNECTED:
+                return R.string.bluetooth_pan_profile_summary_connected;
+
+            default:
+                return Utils.getConnectionStateSummary(state);
+        }
+    }
+
+    public int getDrawableResource(BluetoothClass btClass) {
+        return R.drawable.ic_bt_network_pan;
+    }
+}
diff --git a/src/com/android/settings/bluetooth/RequestPermissionActivity.java b/src/com/android/settings/bluetooth/RequestPermissionActivity.java
index 93d05bc..07a7316 100644
--- a/src/com/android/settings/bluetooth/RequestPermissionActivity.java
+++ b/src/com/android/settings/bluetooth/RequestPermissionActivity.java
@@ -27,7 +27,6 @@
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.SharedPreferences;
 import android.os.Bundle;
 import android.util.Log;
 
@@ -51,7 +50,7 @@
 
     private static final int REQUEST_CODE_START_BT = 1;
 
-    private LocalBluetoothManager mLocalManager;
+    private LocalBluetoothAdapter mLocalAdapter;
 
     private int mTimeout = BluetoothDiscoverableEnabler.DEFAULT_DISCOVERABLE_TIMEOUT;
 
@@ -66,18 +65,19 @@
 
     // True if requesting BT to be turned on
     // False if requesting BT to be turned on + discoverable mode
-    private boolean mEnableOnly = false;
+    private boolean mEnableOnly;
 
-    private boolean mUserConfirmed = false;
+    private boolean mUserConfirmed;
 
-    private AlertDialog mDialog = null;
+    private AlertDialog mDialog;
 
     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
 
         @Override
         public void onReceive(Context context, Intent intent) {
-            if (intent == null)
+            if (intent == null) {
                 return;
+            }
             if (mNeededToEnableBluetooth
                     && BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent.getAction())) {
                 int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothDevice.ERROR);
@@ -94,12 +94,13 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
+        // Note: initializes mLocalAdapter and returns true on error
         if (parseIntent()) {
             finish();
             return;
         }
 
-        int btState = mLocalManager.getBluetoothState();
+        int btState = mLocalAdapter.getState();
 
         switch (btState) {
             case BluetoothAdapter.STATE_OFF:
@@ -120,28 +121,29 @@
                  */
                 registerReceiver(mReceiver,
                         new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
-                Intent i = new Intent();
-                i.setClass(this, RequestPermissionHelperActivity.class);
+                Intent intent = new Intent();
+                intent.setClass(this, RequestPermissionHelperActivity.class);
                 if (mEnableOnly) {
-                    i.setAction(RequestPermissionHelperActivity.ACTION_INTERNAL_REQUEST_BT_ON);
+                    intent.setAction(RequestPermissionHelperActivity.ACTION_INTERNAL_REQUEST_BT_ON);
                 } else {
-                    i.setAction(RequestPermissionHelperActivity.
+                    intent.setAction(RequestPermissionHelperActivity.
                             ACTION_INTERNAL_REQUEST_BT_ON_AND_DISCOVERABLE);
-                    i.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, mTimeout);
+                    intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, mTimeout);
                 }
-                startActivityForResult(i, REQUEST_CODE_START_BT);
+                startActivityForResult(intent, REQUEST_CODE_START_BT);
                 mNeededToEnableBluetooth = true;
                 break;
             case BluetoothAdapter.STATE_ON:
                 if (mEnableOnly) {
                     // Nothing to do. Already enabled.
                     proceedAndFinish();
-                    return;
                 } else {
                     // Ask the user about enabling discovery mode
                     createDialog();
-                    break;
                 }
+                break;
+            default:
+                Log.e(TAG, "Unknown adapter state: " + btState);
         }
     }
 
@@ -176,8 +178,8 @@
     @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
         if (requestCode != REQUEST_CODE_START_BT) {
-            Log.e(TAG, "Unexpected onActivityResult " + requestCode + " " + resultCode);
-            setResult(Activity.RESULT_CANCELED);
+            Log.e(TAG, "Unexpected onActivityResult " + requestCode + ' ' + resultCode);
+            setResult(RESULT_CANCELED);
             finish();
             return;
         }
@@ -191,7 +193,7 @@
         // BT and discoverable mode.
         mUserConfirmed = true;
 
-        if (mLocalManager.getBluetoothState() == BluetoothAdapter.STATE_ON) {
+        if (mLocalAdapter.getBluetoothState() == BluetoothAdapter.STATE_ON) {
             proceedAndFinish();
         } else {
             // If BT is not up yet, show "Turning on Bluetooth..."
@@ -206,7 +208,7 @@
                 break;
 
             case DialogInterface.BUTTON_NEGATIVE:
-                setResult(Activity.RESULT_CANCELED);
+                setResult(RESULT_CANCELED);
                 finish();
                 break;
         }
@@ -217,18 +219,19 @@
 
         if (mEnableOnly) {
             // BT enabled. Done
-            returnCode = Activity.RESULT_OK;
-        } else if (mLocalManager.getBluetoothAdapter().setScanMode(
+            returnCode = RESULT_OK;
+        } else if (mLocalAdapter.setScanMode(
                 BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, mTimeout)) {
             // If already in discoverable mode, this will extend the timeout.
-            persistDiscoverableEndTimestamp(System.currentTimeMillis() + mTimeout * 1000);
+            LocalBluetoothPreferences.persistDiscoverableEndTimestamp(
+                    this, System.currentTimeMillis() + (long) mTimeout * 1000);
             returnCode = mTimeout;
             // Activity.RESULT_FIRST_USER should be 1
-            if (returnCode < Activity.RESULT_FIRST_USER) {
-                returnCode = Activity.RESULT_FIRST_USER;
+            if (returnCode < RESULT_FIRST_USER) {
+                returnCode = RESULT_FIRST_USER;
             }
         } else {
-            returnCode = Activity.RESULT_CANCELED;
+            returnCode = RESULT_CANCELED;
         }
 
         if (mDialog != null) {
@@ -239,6 +242,10 @@
         finish();
     }
 
+    /**
+     * Parse the received Intent and initialize mLocalBluetoothAdapter.
+     * @return true if an error occurred; false otherwise
+     */
     private boolean parseIntent() {
         Intent intent = getIntent();
         if (intent != null && intent.getAction().equals(BluetoothAdapter.ACTION_REQUEST_ENABLE)) {
@@ -257,16 +264,17 @@
             Log.e(TAG, "Error: this activity may be started only with intent "
                     + BluetoothAdapter.ACTION_REQUEST_ENABLE + " or "
                     + BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
-            setResult(Activity.RESULT_CANCELED);
+            setResult(RESULT_CANCELED);
             return true;
         }
 
-        mLocalManager = LocalBluetoothManager.getInstance(this);
-        if (mLocalManager == null) {
-            Log.e(TAG, "Error: there's a problem starting bluetooth");
-            setResult(Activity.RESULT_CANCELED);
+        LocalBluetoothManager manager = LocalBluetoothManager.getInstance(this);
+        if (manager == null) {
+            Log.e(TAG, "Error: there's a problem starting Bluetooth");
+            setResult(RESULT_CANCELED);
             return true;
         }
+        mLocalAdapter = manager.getBluetoothAdapter();
 
         return false;
     }
@@ -274,20 +282,14 @@
     @Override
     protected void onDestroy() {
         super.onDestroy();
-        if (mNeededToEnableBluetooth) unregisterReceiver(mReceiver);
-    }
-
-    private void persistDiscoverableEndTimestamp(long endTimestamp) {
-        SharedPreferences.Editor editor = mLocalManager.getSharedPreferences().edit();
-        editor.putLong(
-                BluetoothDiscoverableEnabler.SHARED_PREFERENCES_KEY_DISCOVERABLE_END_TIMESTAMP,
-                endTimestamp);
-        editor.apply();
+        if (mNeededToEnableBluetooth) {
+            unregisterReceiver(mReceiver);
+        }
     }
 
     @Override
     public void onBackPressed() {
-        setResult(Activity.RESULT_CANCELED);
+        setResult(RESULT_CANCELED);
         super.onBackPressed();
     }
 }
diff --git a/src/com/android/settings/bluetooth/RequestPermissionHelperActivity.java b/src/com/android/settings/bluetooth/RequestPermissionHelperActivity.java
index 2657d91..9b5946b 100644
--- a/src/com/android/settings/bluetooth/RequestPermissionHelperActivity.java
+++ b/src/com/android/settings/bluetooth/RequestPermissionHelperActivity.java
@@ -43,7 +43,7 @@
     public static final String ACTION_INTERNAL_REQUEST_BT_ON_AND_DISCOVERABLE =
         "com.android.settings.bluetooth.ACTION_INTERNAL_REQUEST_BT_ON_AND_DISCOVERABLE";
 
-    private LocalBluetoothManager mLocalManager;
+    private LocalBluetoothAdapter mLocalAdapter;
 
     private int mTimeout;
 
@@ -55,6 +55,7 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
+        // Note: initializes mLocalAdapter and returns true on error
         if (parseIntent()) {
             finish();
             return;
@@ -92,32 +93,33 @@
 
     public void onClick(DialogInterface dialog, int which) {
         int returnCode;
+        // FIXME: fix this ugly switch logic!
         switch (which) {
-            case DialogInterface.BUTTON_POSITIVE:
+            case BUTTON_POSITIVE:
                 int btState = 0;
 
                 try {
                     // TODO There's a better way.
                     int retryCount = 30;
                     do {
-                        btState = mLocalManager.getBluetoothState();
+                        btState = mLocalAdapter.getBluetoothState();
                         Thread.sleep(100);
                     } while (btState == BluetoothAdapter.STATE_TURNING_OFF && --retryCount > 0);
-                } catch (InterruptedException e) {
+                } catch (InterruptedException ignored) {
                     // don't care
                 }
 
                 if (btState == BluetoothAdapter.STATE_TURNING_ON
                         || btState == BluetoothAdapter.STATE_ON
-                        || mLocalManager.getBluetoothAdapter().enable()) {
+                        || mLocalAdapter.enable()) {
                     returnCode = RequestPermissionActivity.RESULT_BT_STARTING_OR_STARTED;
                 } else {
-                    returnCode = Activity.RESULT_CANCELED;
+                    returnCode = RESULT_CANCELED;
                 }
                 break;
 
-            case DialogInterface.BUTTON_NEGATIVE:
-                returnCode = Activity.RESULT_CANCELED;
+            case BUTTON_NEGATIVE:
+                returnCode = RESULT_CANCELED;
                 break;
             default:
                 return;
@@ -125,6 +127,10 @@
         setResult(returnCode);
     }
 
+    /**
+     * Parse the received Intent and initialize mLocalBluetoothAdapter.
+     * @return true if an error occurred; false otherwise
+     */
     private boolean parseIntent() {
         Intent intent = getIntent();
         if (intent != null && intent.getAction().equals(ACTION_INTERNAL_REQUEST_BT_ON)) {
@@ -136,23 +142,24 @@
             mTimeout = intent.getIntExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,
                     BluetoothDiscoverableEnabler.DEFAULT_DISCOVERABLE_TIMEOUT);
         } else {
-            setResult(Activity.RESULT_CANCELED);
+            setResult(RESULT_CANCELED);
             return true;
         }
 
-        mLocalManager = LocalBluetoothManager.getInstance(this);
-        if (mLocalManager == null) {
-            Log.e(TAG, "Error: there's a problem starting bluetooth");
-            setResult(Activity.RESULT_CANCELED);
+        LocalBluetoothManager manager = LocalBluetoothManager.getInstance(this);
+        if (manager == null) {
+            Log.e(TAG, "Error: there's a problem starting Bluetooth");
+            setResult(RESULT_CANCELED);
             return true;
         }
+        mLocalAdapter = manager.getBluetoothAdapter();
 
         return false;
     }
 
     @Override
     public void onBackPressed() {
-        setResult(Activity.RESULT_CANCELED);
+        setResult(RESULT_CANCELED);
         super.onBackPressed();
     }
 }
diff --git a/src/com/android/settings/bluetooth/SettingsBtStatus.java b/src/com/android/settings/bluetooth/SettingsBtStatus.java
deleted file mode 100644
index 2407b53..0000000
--- a/src/com/android/settings/bluetooth/SettingsBtStatus.java
+++ /dev/null
@@ -1,81 +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 com.android.settings.R;
-
-/**
- * SettingsBtStatus is a helper class that contains constants for various status
- * codes.
- */
-class SettingsBtStatus {
-    private static final String TAG = "SettingsBtStatus";
-
-    // Connection status
-
-    public static final int CONNECTION_STATUS_UNKNOWN = 0;
-    public static final int CONNECTION_STATUS_ACTIVE = 1;
-    /** Use {@link #isConnectionStatusConnected} to check for the connected state */
-    public static final int CONNECTION_STATUS_CONNECTED = 2;
-    public static final int CONNECTION_STATUS_CONNECTING = 3;
-    public static final int CONNECTION_STATUS_DISCONNECTED = 4;
-    public static final int CONNECTION_STATUS_DISCONNECTING = 5;
-
-    public static final int getConnectionStatusSummary(int connectionStatus) {
-        switch (connectionStatus) {
-        case CONNECTION_STATUS_ACTIVE:
-            return R.string.bluetooth_connected;
-        case CONNECTION_STATUS_CONNECTED:
-            return R.string.bluetooth_connected;
-        case CONNECTION_STATUS_CONNECTING:
-            return R.string.bluetooth_connecting;
-        case CONNECTION_STATUS_DISCONNECTED:
-            return R.string.bluetooth_disconnected;
-        case CONNECTION_STATUS_DISCONNECTING:
-            return R.string.bluetooth_disconnecting;
-        case CONNECTION_STATUS_UNKNOWN:
-            return R.string.bluetooth_unknown;
-        default:
-            return 0;
-        }
-    }
-
-    public static final boolean isConnectionStatusConnected(int connectionStatus) {
-        return connectionStatus == CONNECTION_STATUS_ACTIVE
-                || connectionStatus == CONNECTION_STATUS_CONNECTED;
-    }
-
-    public static final boolean isConnectionStatusBusy(int connectionStatus) {
-        return connectionStatus == CONNECTION_STATUS_CONNECTING
-                || connectionStatus == CONNECTION_STATUS_DISCONNECTING;
-    }
-
-    public static final int getPairingStatusSummary(int bondState) {
-        switch (bondState) {
-        case BluetoothDevice.BOND_BONDED:
-            return R.string.bluetooth_paired;
-        case BluetoothDevice.BOND_BONDING:
-            return R.string.bluetooth_pairing;
-        case BluetoothDevice.BOND_NONE:
-            return R.string.bluetooth_not_connected;
-        default:
-            return 0;
-        }
-    }
-}
diff --git a/src/com/android/settings/bluetooth/Utf8ByteLengthFilter.java b/src/com/android/settings/bluetooth/Utf8ByteLengthFilter.java
new file mode 100644
index 0000000..bae6e56
--- /dev/null
+++ b/src/com/android/settings/bluetooth/Utf8ByteLengthFilter.java
@@ -0,0 +1,84 @@
+/*
+ * 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.text.InputFilter;
+import android.text.Spanned;
+
+/**
+ * This filter will constrain edits so that the text length is not
+ * greater than the specified number of bytes using UTF-8 encoding.
+ * <p>The JNI method used by {@link android.server.BluetoothService}
+ * to convert UTF-16 to UTF-8 doesn't support surrogate pairs,
+ * therefore code points outside of the basic multilingual plane
+ * (0000-FFFF) will be encoded as a pair of 3-byte UTF-8 characters,
+ * rather than a single 4-byte UTF-8 encoding. Dalvik implements this
+ * conversion in {@code convertUtf16ToUtf8()} in
+ * {@code dalvik/vm/UtfString.c}.
+ * <p>This JNI method is unlikely to change in the future due to
+ * backwards compatibility requirements. It's also unclear whether
+ * the installed base of Bluetooth devices would correctly handle the
+ * encoding of surrogate pairs in UTF-8 as 4 bytes rather than 6.
+ * However, this filter will still work in scenarios where surrogate
+ * pairs are encoded as 4 bytes, with the caveat that the maximum
+ * length will be constrained more conservatively than necessary.
+ */
+class Utf8ByteLengthFilter implements InputFilter {
+    private final int mMaxBytes;
+
+    Utf8ByteLengthFilter(int maxBytes) {
+        mMaxBytes = maxBytes;
+    }
+
+    public CharSequence filter(CharSequence source, int start, int end,
+                               Spanned dest, int dstart, int dend) {
+        int srcByteCount = 0;
+        // count UTF-8 bytes in source substring
+        for (int i = start; i < end; i++) {
+            char c = source.charAt(i);
+            srcByteCount += (c < (char) 0x0080) ? 1 : (c < (char) 0x0800 ? 2 : 3);
+        }
+        int destLen = dest.length();
+        int destByteCount = 0;
+        // count UTF-8 bytes in destination excluding replaced section
+        for (int i = 0; i < destLen; i++) {
+            if (i < dstart || i >= dend) {
+                char c = dest.charAt(i);
+                destByteCount += (c < (char) 0x0080) ? 1 : (c < (char) 0x0800 ? 2 : 3);
+            }
+        }
+        int keepBytes = mMaxBytes - destByteCount;
+        if (keepBytes <= 0) {
+            return "";
+        } else if (keepBytes >= srcByteCount) {
+            return null; // use original dest string
+        } else {
+            // find end position of largest sequence that fits in keepBytes
+            for (int i = start; i < end; i++) {
+                char c = source.charAt(i);
+                keepBytes -= (c < (char) 0x0080) ? 1 : (c < (char) 0x0800 ? 2 : 3);
+                if (keepBytes < 0) {
+                    return source.subSequence(start, i);
+                }
+            }
+            // If the entire substring fits, we should have returned null
+            // above, so this line should not be reached. If for some
+            // reason it is, return null to use the original dest string.
+            return null;
+        }
+    }
+}
diff --git a/src/com/android/settings/bluetooth/Utils.java b/src/com/android/settings/bluetooth/Utils.java
new file mode 100644
index 0000000..7d38e17
--- /dev/null
+++ b/src/com/android/settings/bluetooth/Utils.java
@@ -0,0 +1,99 @@
+/*
+ * 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.bluetooth.BluetoothClass;
+import android.bluetooth.BluetoothProfile;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.widget.Toast;
+
+import com.android.settings.R;
+
+/**
+ * Utils is a helper class that contains constants for various
+ * Android resource IDs, debug logging flags, and static methods
+ * for creating dialogs.
+ */
+final class Utils {
+    static final boolean V = false; // verbose logging
+    static final boolean D = true;  // regular logging
+
+    private Utils() {
+    }
+
+    public static int getConnectionStateSummary(int connectionState) {
+        switch (connectionState) {
+        case BluetoothProfile.STATE_CONNECTED:
+            return R.string.bluetooth_connected;
+        case BluetoothProfile.STATE_CONNECTING:
+            return R.string.bluetooth_connecting;
+        case BluetoothProfile.STATE_DISCONNECTED:
+            return R.string.bluetooth_disconnected;
+        case BluetoothProfile.STATE_DISCONNECTING:
+            return R.string.bluetooth_disconnecting;
+        default:
+            return 0;
+        }
+    }
+
+    // Create (or recycle existing) and show disconnect dialog.
+    static AlertDialog showDisconnectDialog(Context context,
+            AlertDialog dialog,
+            DialogInterface.OnClickListener disconnectListener,
+            CharSequence title, CharSequence message) {
+        if (dialog == null) {
+            dialog = new AlertDialog.Builder(context)
+                    .setPositiveButton(android.R.string.ok, disconnectListener)
+                    .setNegativeButton(android.R.string.cancel, null)
+                    .create();
+        } else {
+            if (dialog.isShowing()) {
+                dialog.dismiss();
+            }
+            // use disconnectListener for the correct profile(s)
+            CharSequence okText = context.getText(android.R.string.ok);
+            dialog.setButton(DialogInterface.BUTTON_POSITIVE,
+                    okText, disconnectListener);
+        }
+        dialog.setTitle(title);
+        dialog.setMessage(message);
+        dialog.show();
+        return dialog;
+    }
+
+    // TODO: wire this up to show connection errors...
+    static void showConnectingError(Context context, String name) {
+        // if (!mIsConnectingErrorPossible) {
+        //     return;
+        // }
+        // mIsConnectingErrorPossible = false;
+
+        showError(context, name, R.string.bluetooth_connecting_error_message);
+    }
+
+    static void showError(Context context, String name, int messageResId) {
+        String message = context.getString(messageResId, name);
+        new AlertDialog.Builder(context)
+                .setIcon(android.R.drawable.ic_dialog_alert)
+                .setTitle(R.string.bluetooth_error_title)
+                .setMessage(message)
+                .setPositiveButton(android.R.string.ok, null)
+                .show();
+    }
+}
diff --git a/src/com/android/settings/widget/SettingsAppWidgetProvider.java b/src/com/android/settings/widget/SettingsAppWidgetProvider.java
index 8f17e05..ba2b615 100644
--- a/src/com/android/settings/widget/SettingsAppWidgetProvider.java
+++ b/src/com/android/settings/widget/SettingsAppWidgetProvider.java
@@ -38,6 +38,7 @@
 import android.util.Log;
 import android.widget.RemoteViews;
 import com.android.settings.R;
+import com.android.settings.bluetooth.LocalBluetoothAdapter;
 import com.android.settings.bluetooth.LocalBluetoothManager;
 
 /**
@@ -50,7 +51,7 @@
             new ComponentName("com.android.settings",
                     "com.android.settings.widget.SettingsAppWidgetProvider");
 
-    private static LocalBluetoothManager sLocalBluetoothManager = null;
+    private static LocalBluetoothAdapter sLocalBluetoothAdapter = null;
 
     private static final int BUTTON_WIFI = 0;
     private static final int BUTTON_BRIGHTNESS = 1;
@@ -411,18 +412,19 @@
 
         @Override
         public int getActualState(Context context) {
-            if (sLocalBluetoothManager == null) {
-                sLocalBluetoothManager = LocalBluetoothManager.getInstance(context);
-                if (sLocalBluetoothManager == null) {
+            if (sLocalBluetoothAdapter == null) {
+                LocalBluetoothManager manager = LocalBluetoothManager.getInstance(context);
+                if (manager == null) {
                     return STATE_UNKNOWN;  // On emulator?
                 }
+                sLocalBluetoothAdapter = manager.getBluetoothAdapter();
             }
-            return bluetoothStateToFiveState(sLocalBluetoothManager.getBluetoothState());
+            return bluetoothStateToFiveState(sLocalBluetoothAdapter.getBluetoothState());
         }
 
         @Override
         protected void requestStateChange(Context context, final boolean desiredState) {
-            if (sLocalBluetoothManager == null) {
+            if (sLocalBluetoothAdapter == null) {
                 Log.d(TAG, "No LocalBluetoothManager");
                 return;
             }
@@ -433,7 +435,7 @@
             new AsyncTask<Void, Void, Void>() {
                 @Override
                 protected Void doInBackground(Void... args) {
-                    sLocalBluetoothManager.setBluetoothEnabled(desiredState);
+                    sLocalBluetoothAdapter.setBluetoothEnabled(desiredState);
                     return null;
                 }
             }.execute();
@@ -584,7 +586,7 @@
     public void onUpdate(Context context, AppWidgetManager appWidgetManager,
             int[] appWidgetIds) {
         // Update each requested appWidgetId
-        RemoteViews view = buildUpdate(context, -1);
+        RemoteViews view = buildUpdate(context);
 
         for (int i = 0; i < appWidgetIds.length; i++) {
             appWidgetManager.updateAppWidget(appWidgetIds[i], view);
@@ -613,22 +615,22 @@
     /**
      * Load image for given widget and build {@link RemoteViews} for it.
      */
-    static RemoteViews buildUpdate(Context context, int appWidgetId) {
+    static RemoteViews buildUpdate(Context context) {
         RemoteViews views = new RemoteViews(context.getPackageName(),
                 R.layout.widget);
-        views.setOnClickPendingIntent(R.id.btn_wifi, getLaunchPendingIntent(context, appWidgetId,
+        views.setOnClickPendingIntent(R.id.btn_wifi, getLaunchPendingIntent(context,
                 BUTTON_WIFI));
         views.setOnClickPendingIntent(R.id.btn_brightness,
                 getLaunchPendingIntent(context,
-                        appWidgetId, BUTTON_BRIGHTNESS));
+                        BUTTON_BRIGHTNESS));
         views.setOnClickPendingIntent(R.id.btn_sync,
                 getLaunchPendingIntent(context,
-                        appWidgetId, BUTTON_SYNC));
+                        BUTTON_SYNC));
         views.setOnClickPendingIntent(R.id.btn_gps,
-                getLaunchPendingIntent(context, appWidgetId, BUTTON_GPS));
+                getLaunchPendingIntent(context, BUTTON_GPS));
         views.setOnClickPendingIntent(R.id.btn_bluetooth,
                 getLaunchPendingIntent(context,
-                        appWidgetId, BUTTON_BLUETOOTH));
+                        BUTTON_BLUETOOTH));
 
         updateButtons(views, context);
         return views;
@@ -640,7 +642,7 @@
      * @param context
      */
     public static void updateWidget(Context context) {
-        RemoteViews views = buildUpdate(context, -1);
+        RemoteViews views = buildUpdate(context);
         // Update specific list of appWidgetIds if given, otherwise default to all
         final AppWidgetManager gm = AppWidgetManager.getInstance(context);
         gm.updateAppWidget(THIS_APPWIDGET, views);
@@ -680,10 +682,9 @@
      * Creates PendingIntent to notify the widget of a button click.
      *
      * @param context
-     * @param appWidgetId
      * @return
      */
-    private static PendingIntent getLaunchPendingIntent(Context context, int appWidgetId,
+    private static PendingIntent getLaunchPendingIntent(Context context,
             int buttonId) {
         Intent launchIntent = new Intent();
         launchIntent.setClass(context, SettingsAppWidgetProvider.class);
