diff --git a/src/com/android/settings/SoundAndDisplaySettings.java b/src/com/android/settings/SoundAndDisplaySettings.java
index edcd4da..e01f7c3 100644
--- a/src/com/android/settings/SoundAndDisplaySettings.java
+++ b/src/com/android/settings/SoundAndDisplaySettings.java
@@ -18,7 +18,7 @@
 
 import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
 
-import com.android.settings.bluetooth.DockSettingsActivity;
+import com.android.settings.bluetooth.DockEventReceiver;
 
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
@@ -49,7 +49,7 @@
     /** If there is no setting in the provider, use this. */
     private static final int FALLBACK_SCREEN_TIMEOUT_VALUE = 30000;
     private static final int FALLBACK_EMERGENCY_TONE_VALUE = 0;
-    
+
     private static final String KEY_SILENT = "silent";
     private static final String KEY_VIBRATE = "vibrate";
     private static final String KEY_SCREEN_TIMEOUT = "screen_timeout";
@@ -89,9 +89,9 @@
     private CheckBoxPreference mAccelerometer;
     private CheckBoxPreference mNotificationPulse;
     private float[] mAnimationScales;
-    
+
     private AudioManager mAudioManager;
-    
+
     private IWindowManager mWindowManager;
 
     private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@@ -114,12 +114,12 @@
         super.onCreate(savedInstanceState);
         ContentResolver resolver = getContentResolver();
         int activePhoneType = TelephonyManager.getDefault().getPhoneType();
-        
+
         mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
         mWindowManager = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
 
         mMountService = IMountService.Stub.asInterface(ServiceManager.getService("mount"));
-        
+
         addPreferencesFromResource(R.xml.sound_and_display_settings);
 
         if (TelephonyManager.PHONE_TYPE_CDMA != activePhoneType) {
@@ -147,7 +147,7 @@
         mAnimations.setOnPreferenceChangeListener(this);
         mAccelerometer = (CheckBoxPreference) findPreference(KEY_ACCELEROMETER);
         mAccelerometer.setPersistent(false);
-        
+
         ListPreference screenTimeoutPreference =
             (ListPreference) findPreference(KEY_SCREEN_TIMEOUT);
         screenTimeoutPreference.setValue(String.valueOf(Settings.System.getInt(
@@ -184,9 +184,9 @@
     @Override
     protected void onResume() {
         super.onResume();
-        
+
         updateState(true);
-        
+
         IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION);
         if (mHasDockSettings) {
             if (mDockSettings != null) {
@@ -236,7 +236,7 @@
         final int ringerMode = mAudioManager.getRingerMode();
         final boolean silentOrVibrateMode =
                 ringerMode != AudioManager.RINGER_MODE_NORMAL;
-        
+
         if (silentOrVibrateMode != mSilent.isChecked() || force) {
             mSilent.setChecked(silentOrVibrateMode);
         }
@@ -245,25 +245,25 @@
             mPlayMediaNotificationSounds.setChecked(mMountService.getPlayNotificationSounds());
         } catch (RemoteException e) {
         }
-       
+
         boolean vibrateSetting;
         if (silentOrVibrateMode) {
             vibrateSetting = ringerMode == AudioManager.RINGER_MODE_VIBRATE;
         } else {
             vibrateSetting = mAudioManager.getVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER)
-                    == AudioManager.VIBRATE_SETTING_ON;            
+                    == AudioManager.VIBRATE_SETTING_ON;
         }
         if (vibrateSetting != mVibrate.isChecked() || force) {
             mVibrate.setChecked(vibrateSetting);
         }
-        
+
         int silentModeStreams = Settings.System.getInt(getContentResolver(),
                 Settings.System.MODE_RINGER_STREAMS_AFFECTED, 0);
-        boolean isAlarmInclSilentMode = (silentModeStreams & (1 << AudioManager.STREAM_ALARM)) != 0; 
+        boolean isAlarmInclSilentMode = (silentModeStreams & (1 << AudioManager.STREAM_ALARM)) != 0;
         mSilent.setSummary(isAlarmInclSilentMode ?
                 R.string.silent_mode_incl_alarm_summary :
                 R.string.silent_mode_summary);
-        
+
         int animations = 0;
         try {
             mAnimationScales = mWindowManager.getAnimationScales();
@@ -290,7 +290,7 @@
         mAnimations.setValueIndex(idx);
         updateAnimationsSummary(mAnimations.getValue());
         mAccelerometer.setChecked(Settings.System.getInt(
-                getContentResolver(), 
+                getContentResolver(),
                 Settings.System.ACCELEROMETER_ROTATION, 0) != 0);
     }
 
@@ -306,7 +306,7 @@
             }
         }
     }
-    
+
     private void setRingerMode(boolean silent, boolean vibrate) {
         if (silent) {
             mAudioManager.setRingerMode(vibrate ? AudioManager.RINGER_MODE_VIBRATE :
@@ -332,7 +332,7 @@
         } else if (preference == mDtmfTone) {
             Settings.System.putInt(getContentResolver(), Settings.System.DTMF_TONE_WHEN_DIALING,
                     mDtmfTone.isChecked() ? 1 : 0);
-            
+
         } else if (preference == mSoundEffects) {
             if (mSoundEffects.isChecked()) {
                 mAudioManager.loadSoundEffects();
@@ -345,7 +345,7 @@
         } else if (preference == mHapticFeedback) {
             Settings.System.putInt(getContentResolver(), Settings.System.HAPTIC_FEEDBACK_ENABLED,
                     mHapticFeedback.isChecked() ? 1 : 0);
-            
+
         } else if (preference == mAccelerometer) {
             Settings.System.putInt(getContentResolver(),
                     Settings.System.ACCELEROMETER_ROTATION,
@@ -356,8 +356,9 @@
                     Settings.System.NOTIFICATION_LIGHT_PULSE, value ? 1 : 0);
         } else if (preference == mDockSettings) {
             Intent i = new Intent(mDockIntent);
-            i.setClass(this, DockSettingsActivity.class);
-            startActivity(i);
+            i.setAction(DockEventReceiver.ACTION_DOCK_SHOW_UI);
+            i.setClass(this, DockEventReceiver.class);
+            sendBroadcast(i);
         }
 
         return true;
@@ -382,12 +383,12 @@
             } catch (NumberFormatException e) {
                 Log.e(TAG, "could not persist animation setting", e);
             }
-            
+
         }
         if (KEY_SCREEN_TIMEOUT.equals(key)) {
             int value = Integer.parseInt((String) objValue);
             try {
-                Settings.System.putInt(getContentResolver(), 
+                Settings.System.putInt(getContentResolver(),
                         SCREEN_OFF_TIMEOUT, value);
             } catch (NumberFormatException e) {
                 Log.e(TAG, "could not persist screen timeout setting", e);
diff --git a/src/com/android/settings/bluetooth/CachedBluetoothDevice.java b/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
index f749cf7..c3b97f6 100644
--- a/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
+++ b/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
@@ -227,44 +227,46 @@
     }
 
     public void onProfileStateChanged(Profile profile, int newProfileState) {
-        if (D) {
-            Log.d(TAG, "onProfileStateChanged:" + workQueue.toString());
-        }
-
-        int newState = LocalBluetoothProfileManager.getProfileManager(mLocalManager,
-                profile).convertState(newProfileState);
-
-        if (newState == SettingsBtStatus.CONNECTION_STATUS_CONNECTED) {
-            if (!mProfiles.contains(profile)) {
-                mProfiles.add(profile);
+        synchronized (workQueue) {
+            if (D) {
+                Log.d(TAG, "onProfileStateChanged:" + workQueue.toString());
             }
-        }
 
-        /* Ignore the transient states e.g. connecting, disconnecting */
-        if (newState == SettingsBtStatus.CONNECTION_STATUS_CONNECTED ||
-                newState == SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED) {
-            BluetoothJob job = workQueue.peek();
-            if (job == null) {
-                return;
-            } else if (!job.cachedDevice.mDevice.equals(mDevice)) {
-                // This can happen in 2 cases: 1) BT device initiated pairing and
-                // 2) disconnects of one headset that's triggered by connects of
-                // another.
-                if (D) {
-                    Log.d(TAG, "mDevice:" + mDevice + " != head:" + job.toString());
+            int newState = LocalBluetoothProfileManager.getProfileManager(mLocalManager,
+                    profile).convertState(newProfileState);
+
+            if (newState == SettingsBtStatus.CONNECTION_STATUS_CONNECTED) {
+                if (!mProfiles.contains(profile)) {
+                    mProfiles.add(profile);
                 }
+            }
 
-                // Check to see if we need to remove the stale items from the queue
-                if (!pruneQueue(null)) {
-                    // nothing in the queue was modify. Just ignore the notification and return.
+            /* Ignore the transient states e.g. connecting, disconnecting */
+            if (newState == SettingsBtStatus.CONNECTION_STATUS_CONNECTED ||
+                    newState == SettingsBtStatus.CONNECTION_STATUS_DISCONNECTED) {
+                BluetoothJob job = workQueue.peek();
+                if (job == null) {
                     return;
-                }
-            } else {
-                // Remove the first item and process the next one
-                workQueue.poll();
-            }
+                } else if (!job.cachedDevice.mDevice.equals(mDevice)) {
+                    // This can happen in 2 cases: 1) BT device initiated pairing and
+                    // 2) disconnects of one headset that's triggered by connects of
+                    // another.
+                    if (D) {
+                        Log.d(TAG, "mDevice:" + mDevice + " != head:" + job.toString());
+                    }
 
-            processCommands();
+                    // Check to see if we need to remove the stale items from the queue
+                    if (!pruneQueue(null)) {
+                        // nothing in the queue was modify. Just ignore the notification and return.
+                        return;
+                    }
+                } else {
+                    // Remove the first item and process the next one
+                    workQueue.poll();
+                }
+
+                processCommands();
+            }
         }
     }
 
diff --git a/src/com/android/settings/bluetooth/DockAudioStateChangeReceiver.java b/src/com/android/settings/bluetooth/DockAudioStateChangeReceiver.java
deleted file mode 100644
index d320742..0000000
--- a/src/com/android/settings/bluetooth/DockAudioStateChangeReceiver.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.bluetooth;
-
-import android.bluetooth.BluetoothDevice;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.util.Log;
-
-public class DockAudioStateChangeReceiver extends BroadcastReceiver {
-
-    private static final boolean DBG = true;
-    private static final String TAG = "DockAudioStateChangeReceiver";
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        if (intent == null)
-            return;
-
-        if (DBG) {
-            Log.e(TAG, "Action:" + intent.getAction()
-                    + " State:" + intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
-                            Intent.EXTRA_DOCK_STATE_UNDOCKED));
-        }
-
-        if (Intent.ACTION_DOCK_EVENT.equals(intent.getAction())) {
-            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
-            if (device == null) {
-                if (DBG) Log.e(TAG, "Device is missing");
-                return;
-            }
-
-            LocalBluetoothManager localManager = LocalBluetoothManager.getInstance(context);
-
-            int state = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
-                    Intent.EXTRA_DOCK_STATE_UNDOCKED);
-
-            switch (state) {
-                case Intent.EXTRA_DOCK_STATE_UNDOCKED:
-                    DockSettingsActivity.handleUndocked(context, localManager, device);
-                    break;
-                case Intent.EXTRA_DOCK_STATE_CAR:
-                case Intent.EXTRA_DOCK_STATE_DESK:
-                    if (DockSettingsActivity.getAutoConnectSetting(localManager)) {
-                        // Auto connect
-                        DockSettingsActivity.handleDocked(context, localManager, device, state);
-                    } else {
-                        // Don't auto connect. Show dialog.
-                        Intent i = new Intent(intent);
-                        i.setClass(context, DockSettingsActivity.class);
-                        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                        context.startActivity(i);
-                    }
-                    break;
-                default:
-                    Log.e(TAG, "Unknown state");
-                    break;
-            }
-        }
-    }
-}
diff --git a/src/com/android/settings/bluetooth/DockEventReceiver.java b/src/com/android/settings/bluetooth/DockEventReceiver.java
new file mode 100644
index 0000000..a2678b9
--- /dev/null
+++ b/src/com/android/settings/bluetooth/DockEventReceiver.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2009 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.Service;
+import android.bluetooth.BluetoothDevice;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.PowerManager;
+import android.util.Log;
+
+public class DockEventReceiver extends BroadcastReceiver {
+
+    private static final boolean DEBUG = true;
+
+    private static final String TAG = "DockEventReceiver";
+
+    public static final String ACTION_DOCK_SHOW_UI =
+        "com.android.settings.bluetooth.action.DOCK_SHOW_UI";
+
+    private static final int EXTRA_INVALID = -1234;
+
+    static final Object mStartingServiceSync = new Object();
+
+    static PowerManager.WakeLock mStartingService;
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        if (intent == null)
+            return;
+
+        int state = intent.getIntExtra(Intent.EXTRA_DOCK_STATE, EXTRA_INVALID);
+        BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+
+        if (DEBUG) {
+            Log.d(TAG, "Action: " + intent.getAction() + " State:" + state + " Device: "
+                    + (device == null ? "null" : device.getName()));
+        }
+
+        if (Intent.ACTION_DOCK_EVENT.equals(intent.getAction())
+                || ACTION_DOCK_SHOW_UI.endsWith(intent.getAction())) {
+            if (device == null) {
+                if (DEBUG) Log.e(TAG, "Device is missing");
+                return;
+            }
+
+            switch (state) {
+                case Intent.EXTRA_DOCK_STATE_UNDOCKED:
+                case Intent.EXTRA_DOCK_STATE_CAR:
+                case Intent.EXTRA_DOCK_STATE_DESK:
+                    Intent i = new Intent(intent);
+                    i.setClass(context, DockService.class);
+                    beginStartingService(context, i);
+                    break;
+                default:
+                    if (DEBUG) Log.e(TAG, "Unknown state");
+                    break;
+            }
+        }
+    }
+
+    /**
+     * 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) {
+                PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+                mStartingService = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
+                        "StartingDockService");
+                mStartingService.setReferenceCounted(false);
+            }
+
+            mStartingService.acquire();
+
+            if (context.startService(intent) == null) {
+                Log.e(TAG, "Can't start DockService");
+                mStartingService.release();
+            }
+        }
+    }
+
+    /**
+     * Called back by the service when it has finished processing notifications,
+     * releasing the wake lock if the service is now stopping.
+     */
+    public static void finishStartingService(Service service, int startId) {
+        synchronized (mStartingServiceSync) {
+            if (mStartingService != null) {
+                if (service.stopSelfResult(startId)) {
+                    mStartingService.release();
+                }
+            }
+        }
+    }
+}
diff --git a/src/com/android/settings/bluetooth/DockService.java b/src/com/android/settings/bluetooth/DockService.java
new file mode 100644
index 0000000..245b10d
--- /dev/null
+++ b/src/com/android/settings/bluetooth/DockService.java
@@ -0,0 +1,495 @@
+/*
+ * Copyright (C) 2009 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.app.AlertDialog;
+import android.app.Notification;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+
+public class DockService extends Service implements AlertDialog.OnMultiChoiceClickListener,
+        DialogInterface.OnClickListener, DialogInterface.OnDismissListener,
+        CompoundButton.OnCheckedChangeListener {
+
+    // TODO check for waitlock leak
+    // TODO check for service shutting down properly
+    // TODO sticky vs non-sticky
+    // TODO clean up static functions
+    // TODO test after wiping data
+
+    private static final String TAG = "DockService";
+
+    // TODO clean up logs. Disable DEBUG flag for this file and receiver's too
+    private static final boolean DEBUG = true;
+
+    private static final String SHARED_PREFERENCE_KEY_AUTO_CONNECT_TO_DOCK = "auto_connect_to_dock";
+
+    // Time allowed for the device to be undocked and redocked without severing
+    // the bluetooth connection
+    private static final long UNDOCKED_GRACE_PERIOD = 1000;
+
+    // Msg for user wanting the UI to setup the dock
+    private static final int MSG_TYPE_SHOW_UI = 111;
+    // Msg for device docked event
+    private static final int MSG_TYPE_DOCKED = 222;
+    // Msg for device undocked event
+    private static final int MSG_TYPE_UNDOCKED_TEMPORARY = 333;
+    // Msg for undocked command to be process after UNDOCKED_GRACE_PERIOD millis
+    // since MSG_TYPE_UNDOCKED_TEMPORARY
+    private static final int MSG_TYPE_UNDOCKED_PERMANENT = 444;
+
+    // Created in OnCreate()
+    private volatile Looper mServiceLooper;
+    private volatile ServiceHandler mServiceHandler;
+    private DockService mContext;
+    private LocalBluetoothManager mBtManager;
+
+    // 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
+    // was started after the docked event.
+    private BluetoothDevice mDevice;
+
+    // Created and used for the duration of the dialog
+    private AlertDialog mDialog;
+    private Profile[] mProfiles;
+    private boolean[] mCheckedItems;
+    private int mStartIdAssociatedWithDialog;
+
+    @Override
+    public void onCreate() {
+        if (DEBUG) Log.d(TAG, "onCreate");
+
+        mBtManager = LocalBluetoothManager.getInstance(this);
+        mContext = this;
+
+        HandlerThread thread = new HandlerThread("DockService");
+        thread.start();
+
+        mServiceLooper = thread.getLooper();
+        mServiceHandler = new ServiceHandler(mServiceLooper);
+    }
+
+    @Override
+    public void onDestroy() {
+        if (DEBUG) Log.d(TAG, "onDestroy");
+        if (mDialog != null) {
+            mDialog.dismiss();
+            mDialog = null;
+        }
+        mServiceLooper.quit();
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        // not supported
+        return null;
+    }
+
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+        if (DEBUG) Log.d(TAG, "onStartCommand startId:" + startId + " flags: " + flags);
+
+        if (intent == null) {
+            // Nothing to process, stop.
+            if (DEBUG) Log.d(TAG, "START_NOT_STICKY - intent is null.");
+
+            // NOTE: We MUST not call stopSelf() directly, since we need to
+            // make sure the wake lock acquired by the Receiver is released.
+            DockEventReceiver.finishStartingService(this, startId);
+            return START_NOT_STICKY;
+        }
+
+        Message msg = parseIntent(intent);
+        if (msg == null) {
+            // Bad intent
+            if (DEBUG) Log.d(TAG, "START_NOT_STICKY - Bad intent.");
+            DockEventReceiver.finishStartingService(this, startId);
+            return START_NOT_STICKY;
+        }
+
+        msg.arg2 = startId;
+        processMessage(msg);
+
+        return START_STICKY;
+    }
+
+    private final class ServiceHandler extends Handler {
+        public ServiceHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            processMessage(msg);
+        }
+    }
+
+    // This method gets messages from both onStartCommand and mServiceHandler/mServiceLooper
+    void processMessage(Message msg) {
+        int msgType = msg.what;
+        int state = msg.arg1;
+        int startId = msg.arg2;
+        BluetoothDevice device = (BluetoothDevice) msg.obj;
+
+        if(DEBUG) Log.d(TAG, "processMessage: " + msgType + " state: " + state + " device = "
+                + (msg.obj == null ? "null" : device.toString()));
+
+        switch (msgType) {
+            case MSG_TYPE_SHOW_UI:
+                //TODO dismiss mDialog if exist? Shouldn't normally happen
+                mDevice = device;
+                createDialog(mContext, mDevice, 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);
+
+                if (!device.equals(mDevice)) {
+                    if (mDevice != null) {
+                        // Not expected. Cleanup/undock existing
+                        handleUndocked(mContext, mBtManager, mDevice);
+                    }
+
+                    mDevice = device;
+                    if (getAutoConnectSetting(mBtManager, device.getAddress())) {
+                        // Setting == auto connect
+                        initBtSettings(mContext, device, state, false);
+                        applyBtSettings();
+                    } else {
+                        createDialog(mContext, mDevice, state, startId);
+                    }
+                }
+                break;
+
+            case MSG_TYPE_UNDOCKED_PERMANENT:
+                // Grace period passed. Disconnect.
+                handleUndocked(mContext, mBtManager, device);
+                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,
+                        0, device);
+                mServiceHandler.sendMessageDelayed(newMsg, UNDOCKED_GRACE_PERIOD);
+                break;
+        }
+
+        if (mDialog == null) {
+            // 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, msg.arg1);
+        }
+    }
+
+    private Message parseIntent(Intent intent) {
+        BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+        int state = intent.getIntExtra(Intent.EXTRA_DOCK_STATE, -1234);
+
+        if (DEBUG) {
+            Log.d(TAG, "Action: " + intent.getAction() + " State:" + state
+                    + " Device: " + (device == null ? "null" : device.getName()));
+        }
+
+        if (device == null) {
+            Log.e(TAG, "device is null");
+            return null;
+        }
+
+        int msgType;
+        switch (state) {
+            case Intent.EXTRA_DOCK_STATE_UNDOCKED:
+                msgType = MSG_TYPE_UNDOCKED_TEMPORARY;
+                break;
+            case Intent.EXTRA_DOCK_STATE_DESK:
+            case Intent.EXTRA_DOCK_STATE_CAR:
+                if (DockEventReceiver.ACTION_DOCK_SHOW_UI.equals(intent.getAction())) {
+                    msgType = MSG_TYPE_SHOW_UI;
+                } else {
+                    msgType = MSG_TYPE_DOCKED;
+                }
+                break;
+            default:
+                return null;
+        }
+
+        return mServiceHandler.obtainMessage(msgType, state, 0, device);
+    }
+
+    private boolean createDialog(DockService service, BluetoothDevice device, int state,
+            int startId) {
+        switch (state) {
+            case Intent.EXTRA_DOCK_STATE_CAR:
+            case Intent.EXTRA_DOCK_STATE_DESK:
+                break;
+            default:
+                return false;
+        }
+
+        startForeground(0, new Notification());
+
+        // Device in a new dock.
+        boolean firstTime = !hasAutoConnectSetting(mBtManager, device.getAddress());
+
+        CharSequence[] items = initBtSettings(service, device, state, firstTime);
+
+        final AlertDialog.Builder ab = new AlertDialog.Builder(service);
+        ab.setTitle(service.getString(R.string.bluetooth_dock_settings_title));
+
+        // Profiles
+        ab.setMultiChoiceItems(items, mCheckedItems, service);
+
+        // Remember this settings
+        LayoutInflater inflater = (LayoutInflater) service
+                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        float pixelScaleFactor = service.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 || getAutoConnectSetting(mBtManager, device.getAddress());
+        rememberCheckbox.setChecked(checked);
+        rememberCheckbox.setOnCheckedChangeListener(this);
+        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 = " + getAutoConnectSetting(mBtManager, device.getAddress()));
+        }
+
+        // Ok Button
+        ab.setPositiveButton(service.getString(android.R.string.ok), service);
+
+        mStartIdAssociatedWithDialog = startId;
+        mDialog = ab.create();
+        mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
+        mDialog.setOnDismissListener(service);
+        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;
+    }
+
+    // Called when the "Remember" Checkbox is clicked
+    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+        if (DEBUG) Log.d(TAG, "onCheckedChanged: Remember Settings = " + isChecked);
+        saveAutoConnectSetting(mBtManager, 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.
+        DockEventReceiver.finishStartingService(mContext, mStartIdAssociatedWithDialog);
+        mContext.stopForeground(true);
+    }
+
+    // Called when clicked on the OK button
+    public void onClick(DialogInterface dialog, int which) {
+        if (which == DialogInterface.BUTTON_POSITIVE) {
+            if (!hasAutoConnectSetting(mBtManager, mDevice.getAddress())) {
+                saveAutoConnectSetting(mBtManager, mDevice.getAddress(), true);
+            }
+
+            // TODO move this to a background thread
+            switch (mBtManager.getBluetoothState()) {
+                case BluetoothAdapter.STATE_OFF:
+                case BluetoothAdapter.STATE_TURNING_OFF:
+                    mBtManager.getBluetoothAdapter().enable();
+                    // TODO can I call connect right away? probably not.
+                    break;
+                case BluetoothAdapter.STATE_TURNING_ON:
+                    // TODO wait? probably
+                    break;
+                case BluetoothAdapter.STATE_ON:
+                    break;
+            }
+
+            applyBtSettings();
+        }
+    }
+
+    private CharSequence[] initBtSettings(DockService service, BluetoothDevice device, int state,
+            boolean firstTime) {
+        // TODO Avoid hardcoding dock and profiles. Read from system properties
+        int numOfProfiles = 0;
+        switch (state) {
+            case Intent.EXTRA_DOCK_STATE_DESK:
+                numOfProfiles = 1;
+                break;
+            case Intent.EXTRA_DOCK_STATE_CAR:
+                numOfProfiles = 2;
+                break;
+            default:
+                return null;
+        }
+
+        mProfiles = new Profile[numOfProfiles];
+        mCheckedItems = new boolean[numOfProfiles];
+        CharSequence[] items = new CharSequence[numOfProfiles];
+
+        int i = 0;
+        switch (state) {
+            case Intent.EXTRA_DOCK_STATE_CAR:
+                items[i] = service.getString(R.string.bluetooth_dock_settings_headset);
+                mProfiles[i] = Profile.HEADSET;
+                if (firstTime) {
+                    mCheckedItems[i] = true;
+                } else {
+                    mCheckedItems[i] = LocalBluetoothProfileManager.getProfileManager(mBtManager,
+                            Profile.HEADSET).isPreferred(device);
+                }
+                ++i;
+                // fall through
+            case Intent.EXTRA_DOCK_STATE_DESK:
+                items[i] = service.getString(R.string.bluetooth_dock_settings_a2dp);
+                mProfiles[i] = Profile.A2DP;
+                if (firstTime) {
+                    mCheckedItems[i] = true;
+                } else {
+                    mCheckedItems[i] = LocalBluetoothProfileManager.getProfileManager(mBtManager,
+                            Profile.A2DP).isPreferred(device);
+                }
+                break;
+        }
+        return items;
+    }
+
+    private void applyBtSettings() {
+        if (mProfiles == null) return;
+        for (int i = 0; i < mProfiles.length; i++) {
+            LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
+                    .getProfileManager(mBtManager, mProfiles[i]);
+            boolean isConnected = profileManager.isConnected(mDevice);
+            CachedBluetoothDevice cachedDevice = getCachedBluetoothDevice(mContext, mBtManager,
+                    mDevice);
+
+            if (DEBUG) Log.d(TAG, mProfiles[i].toString() + " = " + mCheckedItems[i]);
+
+            if (mCheckedItems[i] && !isConnected) {
+                // Checked but not connected
+                if (DEBUG) Log.d(TAG, "Connecting ");
+                cachedDevice.connect(mProfiles[i]);
+            } else if (!mCheckedItems[i] && isConnected) {
+                // Unchecked but connected
+                if (DEBUG) Log.d(TAG, "Disconnecting");
+                cachedDevice.disconnect(mProfiles[i]);
+            }
+            profileManager.setPreferred(mDevice, mCheckedItems[i]);
+            if (DEBUG) {
+                if (mCheckedItems[i] != LocalBluetoothProfileManager.getProfileManager(
+                        mBtManager, Profile.HEADSET).isPreferred(mDevice)) {
+                    Log.e(TAG, "Can't save prefered value");
+                }
+            }
+        }
+    }
+
+    void handleUndocked(Context context, LocalBluetoothManager localManager,
+            BluetoothDevice device) {
+        if (mDialog != null) {
+            mDialog.dismiss();
+            mDialog = null;
+        }
+        mDevice = null;
+        CachedBluetoothDevice cachedBluetoothDevice = getCachedBluetoothDevice(context,
+                localManager, device);
+        cachedBluetoothDevice.disconnect();
+    }
+
+    void handleDocked(Context context, LocalBluetoothManager localManager,
+            BluetoothDevice device, int state) {
+        CachedBluetoothDevice cachedBluetoothDevice = getCachedBluetoothDevice(context,
+                localManager, device);
+        cachedBluetoothDevice.connect();
+    }
+
+    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);
+        }
+        return cachedBluetoothDevice;
+    }
+
+    public static boolean hasAutoConnectSetting(LocalBluetoothManager localManager, String addr) {
+        return localManager.getSharedPreferences().contains(
+                SHARED_PREFERENCE_KEY_AUTO_CONNECT_TO_DOCK + addr);
+    }
+
+    public static boolean getAutoConnectSetting(LocalBluetoothManager localManager, String addr) {
+        return localManager.getSharedPreferences().getBoolean(
+                SHARED_PREFERENCE_KEY_AUTO_CONNECT_TO_DOCK + addr, false);
+    }
+
+    public static void saveAutoConnectSetting(LocalBluetoothManager localManager, String addr,
+            boolean autoConnect) {
+        SharedPreferences.Editor editor = localManager.getSharedPreferences().edit();
+        editor.putBoolean(SHARED_PREFERENCE_KEY_AUTO_CONNECT_TO_DOCK + addr, autoConnect);
+        editor.commit();
+    }
+
+    // TODO Delete this method if not needed.
+    private Notification getNotification(Service service) {
+        CharSequence title = service.getString(R.string.dock_settings_title);
+
+        Notification n = new Notification(R.drawable.ic_bt_headphones_a2dp, title, System
+                .currentTimeMillis());
+
+        CharSequence contentText = service.getString(R.string.dock_settings_summary);
+        Intent notificationIntent = new Intent(service, DockEventReceiver.class);
+        notificationIntent.setAction(DockEventReceiver.ACTION_DOCK_SHOW_UI);
+        PendingIntent pendingIntent = PendingIntent.getActivity(service, 0, notificationIntent, 0);
+
+        n.setLatestEventInfo(service, title, contentText, pendingIntent);
+        return n;
+    }
+}
diff --git a/src/com/android/settings/bluetooth/DockSettingsActivity.java b/src/com/android/settings/bluetooth/DockSettingsActivity.java
deleted file mode 100644
index f5e0055..0000000
--- a/src/com/android/settings/bluetooth/DockSettingsActivity.java
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * Copyright (C) 2009 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.internal.app.AlertActivity;
-import com.android.internal.app.AlertController;
-import com.android.settings.R;
-import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
-
-import android.app.AlertDialog;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.WindowManager;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.CompoundButton.OnCheckedChangeListener;
-
-/**
- * RequestPermissionActivity asks the user whether to enable discovery. This is
- * usually started by an application wanted to start bluetooth and or discovery
- */
-public class DockSettingsActivity extends AlertActivity implements DialogInterface.OnClickListener,
-        AlertDialog.OnMultiChoiceClickListener, OnCheckedChangeListener {
-
-    private static final String TAG = "DockSettingsActivity";
-
-    private static final boolean DEBUG = true;
-
-    private static final String SHARED_PREFERENCES_KEY_AUTO_CONNECT_TO_DOCK = "auto_connect_to_dock";
-
-    private BluetoothDevice mDevice;
-
-    private int mState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
-
-    private CachedBluetoothDevice mCachedDevice;
-
-    private LocalBluetoothManager mLocalManager;
-
-    private LocalBluetoothProfileManager mA2dpMgr;
-
-    private LocalBluetoothProfileManager mHeadsetMgr;
-
-    private LocalBluetoothProfileManager[] mProfileManagers;
-
-    private boolean[] mCheckedItems;
-
-    private CheckBox mRememberCheck;
-
-    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (!parseIntent(intent)) {
-                finish();
-                return;
-            }
-
-            if (DEBUG) Log.d(TAG, "Action: " + intent.getAction() + " State: " + mState);
-        }
-    };
-
-    private Profile[] mProfiles;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        if (!parseIntent(getIntent())) {
-            finish();
-            return;
-        }
-
-        if (mState == Intent.EXTRA_DOCK_STATE_UNDOCKED) {
-            handleUndocked(this, mLocalManager, mDevice);
-            dismiss();
-            return;
-        }
-        getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
-        createDialog();
-        getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
-    }
-
-    @Override
-    protected void onNewIntent(Intent intent) {
-        if (!parseIntent(getIntent())) {
-            finish();
-            return;
-        }
-    }
-
-    @Override
-    protected void onResume() {
-        super.onResume();
-
-        IntentFilter filter = new IntentFilter(Intent.ACTION_DOCK_EVENT);
-        registerReceiver(mReceiver, filter);
-    }
-
-    @Override
-    protected void onPause() {
-        super.onPause();
-
-        unregisterReceiver(mReceiver);
-    }
-
-    private void createDialog() {
-        // TODO Avoid hardcoding dock and profiles. Read from system properties
-        int numOfProfiles;
-        switch (mState) {
-            case Intent.EXTRA_DOCK_STATE_CAR:
-                numOfProfiles = 2;
-                break;
-            case Intent.EXTRA_DOCK_STATE_DESK:
-                numOfProfiles = 1;
-                break;
-            default:
-                return;
-        }
-
-        CharSequence[] items = new CharSequence[numOfProfiles];
-        mCheckedItems = new boolean[numOfProfiles];
-        mProfileManagers = new LocalBluetoothProfileManager[numOfProfiles];
-        mProfiles = new Profile[numOfProfiles];
-
-        int i = 0;
-        switch (mState) {
-            case Intent.EXTRA_DOCK_STATE_CAR:
-                mProfileManagers[i] = mHeadsetMgr;
-                mProfiles[i] = Profile.HEADSET;
-                mCheckedItems[i] = mHeadsetMgr.isPreferred(mDevice);
-                items[i] = getString(R.string.bluetooth_dock_settings_headset);
-                ++i;
-                // fall through
-            case Intent.EXTRA_DOCK_STATE_DESK:
-                mProfileManagers[i] = mA2dpMgr;
-                mProfiles[i] = Profile.A2DP;
-                mCheckedItems[i] = mA2dpMgr.isPreferred(mDevice);
-                items[i] = getString(R.string.bluetooth_dock_settings_a2dp);
-                break;
-        }
-
-        final AlertController.AlertParams p = mAlertParams;
-        p.mTitle = getString(R.string.bluetooth_dock_settings_title);
-
-        // Profiles
-        p.mIsMultiChoice = true;
-        p.mItems = items;
-        p.mCheckedItems = mCheckedItems;
-        p.mOnCheckboxClickListener = this;
-
-        // Remember this settings
-        LayoutInflater inflater = (LayoutInflater) getSystemService(
-                Context.LAYOUT_INFLATER_SERVICE);
-        p.mView = inflater.inflate(R.layout.remember_dock_setting, null);
-        p.mViewSpacingSpecified = true;
-        float pixelScaleFactor = getResources().getDisplayMetrics().density;
-        p.mViewSpacingLeft = (int) (14 * pixelScaleFactor);
-        p.mViewSpacingRight = (int) (14 * pixelScaleFactor);
-        mRememberCheck = (CheckBox)p.mView.findViewById(R.id.remember);
-        if (DEBUG) Log.d(TAG, "Auto Check? = " + getAutoConnectSetting(mLocalManager));
-        mRememberCheck.setChecked(getAutoConnectSetting(mLocalManager));
-        mRememberCheck.setOnCheckedChangeListener(this);
-
-        // Ok Button
-        p.mPositiveButtonText = getString(android.R.string.ok);
-        p.mPositiveButtonListener = this;
-
-        setupAlert();
-    }
-
-    // Called when the individual items are clicked.
-    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);
-        saveAutoConnectSetting(mLocalManager, isChecked);
-    }
-
-    // Called when clicked on the OK button
-    public void onClick(DialogInterface dialog, int which) {
-        if (which == DialogInterface.BUTTON_POSITIVE) {
-            switch (mLocalManager.getBluetoothState()) {
-                case BluetoothAdapter.STATE_OFF:
-                case BluetoothAdapter.STATE_TURNING_OFF:
-                    mLocalManager.getBluetoothAdapter().enable();
-                    // TODO can I call connect right away? probably not.
-                    break;
-                case BluetoothAdapter.STATE_TURNING_ON:
-                    // TODO wait? probably
-                    break;
-                case BluetoothAdapter.STATE_ON:
-                    break;
-            }
-
-            for(int i = 0; i < mProfileManagers.length; i++) {
-                mProfileManagers[i].setPreferred(mDevice, mCheckedItems[i]);
-
-                if (DEBUG) Log.d(TAG, mProfileManagers[i].toString() + " = " + mCheckedItems[i]);
-                boolean isConnected = mProfileManagers[i].isConnected(mDevice);
-                if (mCheckedItems[i] && !isConnected) {
-                    if (DEBUG) Log.d(TAG, "Connecting ");
-                    mCachedDevice.connect(mProfiles[i]);
-                } else if (isConnected){
-                    if (DEBUG) Log.d(TAG, "Disconnecting");
-                    mProfileManagers[i].disconnect(mDevice);
-                }
-            }
-        }
-    }
-
-    private boolean parseIntent(Intent intent) {
-        if (intent == null) {
-            return false;
-        }
-
-        mLocalManager = LocalBluetoothManager.getInstance(this);
-        if (mLocalManager == null) {
-            if (DEBUG) Log.d(TAG, "Error: there's a problem starting bluetooth");
-            return false;
-        }
-
-        mDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
-        if (mDevice == null) {
-            if (DEBUG) Log.d(TAG, "device == null");
-            return false;
-        }
-
-        mState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
-                Intent.EXTRA_DOCK_STATE_UNDOCKED);
-        if (mState == Intent.EXTRA_DOCK_STATE_UNDOCKED) {
-            handleUndocked(this, mLocalManager, mDevice);
-            return false;
-        }
-
-        mCachedDevice = getCachedBluetoothDevice(this, mLocalManager, mDevice);
-        mA2dpMgr = LocalBluetoothProfileManager.getProfileManager(mLocalManager, Profile.A2DP);
-        mHeadsetMgr = LocalBluetoothProfileManager.getProfileManager(mLocalManager,
-                Profile.HEADSET);
-
-        return true;
-    }
-
-    public static void handleUndocked(Context context, LocalBluetoothManager localManager,
-            BluetoothDevice device) {
-        CachedBluetoothDevice cachedBluetoothDevice = getCachedBluetoothDevice(context,
-                localManager, device);
-        cachedBluetoothDevice.disconnect();
-    }
-
-    public static void handleDocked(Context context, LocalBluetoothManager localManager,
-            BluetoothDevice device, int state) {
-        CachedBluetoothDevice cachedBluetoothDevice = getCachedBluetoothDevice(context,
-                localManager, device);
-        cachedBluetoothDevice.connect();
-    }
-
-    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);
-        }
-        return cachedBluetoothDevice;
-    }
-
-    public static boolean hasAutoConnectSetting(LocalBluetoothManager localManager) {
-        return localManager.getSharedPreferences().contains(
-                SHARED_PREFERENCES_KEY_AUTO_CONNECT_TO_DOCK);
-    }
-
-    public static boolean getAutoConnectSetting(LocalBluetoothManager localManager) {
-        return localManager.getSharedPreferences().getBoolean(
-                SHARED_PREFERENCES_KEY_AUTO_CONNECT_TO_DOCK, false);
-    }
-
-    public static void saveAutoConnectSetting(LocalBluetoothManager localManager,
-            boolean autoConnect) {
-        SharedPreferences.Editor editor = localManager.getSharedPreferences().edit();
-        editor.putBoolean(SHARED_PREFERENCES_KEY_AUTO_CONNECT_TO_DOCK, autoConnect);
-        editor.commit();
-    }
-}
