diff --git a/src/com/android/server/telecom/BluetoothHeadsetProxy.java b/src/com/android/server/telecom/BluetoothHeadsetProxy.java
index e4eed87..a43b3cd 100644
--- a/src/com/android/server/telecom/BluetoothHeadsetProxy.java
+++ b/src/com/android/server/telecom/BluetoothHeadsetProxy.java
@@ -36,6 +36,19 @@
         mBluetoothHeadset = headset;
     }
 
+    public void clccResponse(int index, int direction, int status, int mode, boolean mpty,
+            String number, int type) {
+
+        mBluetoothHeadset.clccResponse(index, direction, status, mode, mpty, number, type);
+    }
+
+    public void phoneStateChanged(int numActive, int numHeld, int callState, String number,
+            int type, String name) {
+
+        mBluetoothHeadset.phoneStateChanged(numActive, numHeld, callState, number, type,
+            name);
+    }
+
     public List<BluetoothDevice> getConnectedDevices() {
         return mBluetoothHeadset.getConnectedDevices();
     }
diff --git a/src/com/android/server/telecom/BluetoothPhoneServiceImpl.java b/src/com/android/server/telecom/BluetoothPhoneServiceImpl.java
new file mode 100644
index 0000000..f2ea950
--- /dev/null
+++ b/src/com/android/server/telecom/BluetoothPhoneServiceImpl.java
@@ -0,0 +1,932 @@
+/*
+ * Copyright (C) 2014 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.server.telecom;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothHeadset;
+import android.bluetooth.BluetoothProfile;
+import android.bluetooth.IBluetoothHeadsetPhone;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.telecom.Connection;
+import android.telecom.Log;
+import android.telecom.PhoneAccount;
+import android.telecom.VideoProfile;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.telecom.CallsManager.CallsManagerListener;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Bluetooth headset manager for Telecom. This class shares the call state with the bluetooth device
+ * and accepts call-related commands to perform on behalf of the BT device.
+ */
+public class BluetoothPhoneServiceImpl {
+
+    public interface BluetoothPhoneServiceImplFactory {
+        BluetoothPhoneServiceImpl makeBluetoothPhoneServiceImpl(Context context,
+                TelecomSystem.SyncRoot lock, CallsManager callsManager,
+                PhoneAccountRegistrar phoneAccountRegistrar);
+    }
+
+    private static final String TAG = "BluetoothPhoneService";
+
+    // match up with bthf_call_state_t of bt_hf.h
+    private static final int CALL_STATE_ACTIVE = 0;
+    private static final int CALL_STATE_HELD = 1;
+    private static final int CALL_STATE_DIALING = 2;
+    private static final int CALL_STATE_ALERTING = 3;
+    private static final int CALL_STATE_INCOMING = 4;
+    private static final int CALL_STATE_WAITING = 5;
+    private static final int CALL_STATE_IDLE = 6;
+    private static final int CALL_STATE_DISCONNECTED = 7;
+
+    // match up with bthf_call_state_t of bt_hf.h
+    // Terminate all held or set UDUB("busy") to a waiting call
+    private static final int CHLD_TYPE_RELEASEHELD = 0;
+    // Terminate all active calls and accepts a waiting/held call
+    private static final int CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD = 1;
+    // Hold all active calls and accepts a waiting/held call
+    private static final int CHLD_TYPE_HOLDACTIVE_ACCEPTHELD = 2;
+    // Add all held calls to a conference
+    private static final int CHLD_TYPE_ADDHELDTOCONF = 3;
+
+    // Indicates that no call is ringing
+    private static final int DEFAULT_RINGING_ADDRESS_TYPE = 128;
+
+    private int mNumActiveCalls = 0;
+    private int mNumHeldCalls = 0;
+    private int mNumChildrenOfActiveCall = 0;
+    private int mBluetoothCallState = CALL_STATE_IDLE;
+    private String mRingingAddress = "";
+    private int mRingingAddressType = DEFAULT_RINGING_ADDRESS_TYPE;
+    private Call mOldHeldCall = null;
+    private boolean mIsDisconnectedTonePlaying = false;
+
+    /**
+     * Binder implementation of IBluetoothHeadsetPhone. Implements the command interface that the
+     * bluetooth headset code uses to control call.
+     */
+    @VisibleForTesting
+    public final IBluetoothHeadsetPhone.Stub mBinder = new IBluetoothHeadsetPhone.Stub() {
+        @Override
+        public boolean answerCall() throws RemoteException {
+            synchronized (mLock) {
+                enforceModifyPermission();
+                Log.startSession("BPSI.aC");
+                long token = Binder.clearCallingIdentity();
+                try {
+                    Log.i(TAG, "BT - answering call");
+                    Call call = mCallsManager.getRingingOrSimulatedRingingCall();
+                    if (call != null) {
+                        mCallsManager.answerCall(call, VideoProfile.STATE_AUDIO_ONLY);
+                        return true;
+                    }
+                    return false;
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                    Log.endSession();
+                }
+
+            }
+        }
+
+        @Override
+        public boolean hangupCall() throws RemoteException {
+            synchronized (mLock) {
+                enforceModifyPermission();
+                Log.startSession("BPSI.hC");
+                long token = Binder.clearCallingIdentity();
+                try {
+                    Log.i(TAG, "BT - hanging up call");
+                    Call call = mCallsManager.getForegroundCall();
+                    if (call != null) {
+                        mCallsManager.disconnectCall(call);
+                        return true;
+                    }
+                    return false;
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                    Log.endSession();
+                }
+            }
+        }
+
+        @Override
+        public boolean sendDtmf(int dtmf) throws RemoteException {
+            synchronized (mLock) {
+                enforceModifyPermission();
+                Log.startSession("BPSI.sD");
+                long token = Binder.clearCallingIdentity();
+                try {
+                    Log.i(TAG, "BT - sendDtmf %c", Log.DEBUG ? dtmf : '.');
+                    Call call = mCallsManager.getForegroundCall();
+                    if (call != null) {
+                        // TODO: Consider making this a queue instead of starting/stopping
+                        // in quick succession.
+                        mCallsManager.playDtmfTone(call, (char) dtmf);
+                        mCallsManager.stopDtmfTone(call);
+                        return true;
+                    }
+                    return false;
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                    Log.endSession();
+                }
+            }
+        }
+
+        @Override
+        public String getNetworkOperator() throws RemoteException {
+            synchronized (mLock) {
+                enforceModifyPermission();
+                Log.startSession("BPSI.gNO");
+                long token = Binder.clearCallingIdentity();
+                try {
+                    Log.i(TAG, "getNetworkOperator");
+                    PhoneAccount account = getBestPhoneAccount();
+                    if (account != null && account.getLabel() != null) {
+                        return account.getLabel().toString();
+                    } else {
+                        // Finally, just get the network name from telephony.
+                        return mContext.getSystemService(TelephonyManager.class)
+                                .getNetworkOperatorName();
+                    }
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                    Log.endSession();
+                }
+            }
+        }
+
+        @Override
+        public String getSubscriberNumber() throws RemoteException {
+            synchronized (mLock) {
+                enforceModifyPermission();
+                Log.startSession("BPSI.gSN");
+                long token = Binder.clearCallingIdentity();
+                try {
+                    Log.i(TAG, "getSubscriberNumber");
+                    String address = null;
+                    PhoneAccount account = getBestPhoneAccount();
+                    if (account != null) {
+                        Uri addressUri = account.getAddress();
+                        if (addressUri != null) {
+                            address = addressUri.getSchemeSpecificPart();
+                        }
+                    }
+                    if (TextUtils.isEmpty(address)) {
+                        address = mContext.getSystemService(TelephonyManager.class)
+                                .getLine1Number();
+                        if (address == null) address = "";
+                    }
+                    return address;
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                    Log.endSession();
+                }
+            }
+        }
+
+        @Override
+        public boolean listCurrentCalls() throws RemoteException {
+            synchronized (mLock) {
+                enforceModifyPermission();
+                Log.startSession("BPSI.lCC");
+                long token = Binder.clearCallingIdentity();
+                try {
+                    // only log if it is after we recently updated the headset state or else it can
+                    // clog the android log since this can be queried every second.
+                    boolean logQuery = mHeadsetUpdatedRecently;
+                    mHeadsetUpdatedRecently = false;
+
+                    if (logQuery) {
+                        Log.i(TAG, "listcurrentCalls");
+                    }
+
+                    sendListOfCalls(logQuery);
+                    return true;
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                    Log.endSession();
+                }
+            }
+        }
+
+        @Override
+        public boolean queryPhoneState() throws RemoteException {
+            synchronized (mLock) {
+                enforceModifyPermission();
+                Log.startSession("BPSI.qPS");
+                long token = Binder.clearCallingIdentity();
+                try {
+                    Log.i(TAG, "queryPhoneState");
+                    updateHeadsetWithCallState(true /* force */);
+                    return true;
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                    Log.endSession();
+                }
+            }
+        }
+
+        @Override
+        public boolean processChld(int chld) throws RemoteException {
+            synchronized (mLock) {
+                enforceModifyPermission();
+                Log.startSession("BPSI.pC");
+                long token = Binder.clearCallingIdentity();
+                try {
+                    Log.i(TAG, "processChld %d", chld);
+                    return BluetoothPhoneServiceImpl.this.processChld(chld);
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                    Log.endSession();
+                }
+            }
+        }
+
+        @Override
+        public void updateBtHandsfreeAfterRadioTechnologyChange() throws RemoteException {
+            Log.d(TAG, "RAT change - deprecated");
+            // deprecated
+        }
+
+        @Override
+        public void cdmaSetSecondCallState(boolean state) throws RemoteException {
+            Log.d(TAG, "cdma 1 - deprecated");
+            // deprecated
+        }
+
+        @Override
+        public void cdmaSwapSecondCallState() throws RemoteException {
+            Log.d(TAG, "cdma 2 - deprecated");
+            // deprecated
+        }
+    };
+
+    /**
+     * Listens to call changes from the CallsManager and calls into methods to update the bluetooth
+     * headset with the new states.
+     */
+    @VisibleForTesting
+    public CallsManagerListener mCallsManagerListener = new CallsManagerListenerBase() {
+        @Override
+        public void onCallAdded(Call call) {
+            if (call.isExternalCall()) {
+                return;
+            }
+            updateHeadsetWithCallState(false /* force */);
+        }
+
+        @Override
+        public void onCallRemoved(Call call) {
+            if (call.isExternalCall()) {
+                return;
+            }
+            mClccIndexMap.remove(call);
+            updateHeadsetWithCallState(false /* force */);
+        }
+
+        /**
+         * Where a call which was external becomes a regular call, or a regular call becomes
+         * external, treat as an add or remove, respectively.
+         *
+         * @param call The call.
+         * @param isExternalCall {@code True} if the call became external, {@code false} otherwise.
+         */
+        @Override
+        public void onExternalCallChanged(Call call, boolean isExternalCall) {
+            if (isExternalCall) {
+                onCallRemoved(call);
+            } else {
+                onCallAdded(call);
+            }
+        }
+
+        @Override
+        public void onCallStateChanged(Call call, int oldState, int newState) {
+            if (call.isExternalCall()) {
+                return;
+            }
+            // If a call is being put on hold because of a new connecting call, ignore the
+            // CONNECTING since the BT state update needs to send out the numHeld = 1 + dialing
+            // state atomically.
+            // When the call later transitions to DIALING/DISCONNECTED we will then send out the
+            // aggregated update.
+            if (oldState == CallState.ACTIVE && newState == CallState.ON_HOLD) {
+                for (Call otherCall : mCallsManager.getCalls()) {
+                    if (otherCall.getState() == CallState.CONNECTING) {
+                        return;
+                    }
+                }
+            }
+
+            // To have an active call and another dialing at the same time is an invalid BT
+            // state. We can assume that the active call will be automatically held which will
+            // send another update at which point we will be in the right state.
+            if (mCallsManager.getActiveCall() != null
+                    && oldState == CallState.CONNECTING &&
+                    (newState == CallState.DIALING || newState == CallState.PULLING)) {
+                return;
+            }
+            updateHeadsetWithCallState(false /* force */);
+        }
+
+        @Override
+        public void onIsConferencedChanged(Call call) {
+            if (call.isExternalCall()) {
+                return;
+            }
+            /*
+             * Filter certain onIsConferencedChanged callbacks. Unfortunately this needs to be done
+             * because conference change events are not atomic and multiple callbacks get fired
+             * when two calls are conferenced together. This confuses updateHeadsetWithCallState
+             * if it runs in the middle of two calls being conferenced and can cause spurious and
+             * incorrect headset state updates. One of the scenarios is described below for CDMA
+             * conference calls.
+             *
+             * 1) Call 1 and Call 2 are being merged into conference Call 3.
+             * 2) Call 1 has its parent set to Call 3, but Call 2 does not have a parent yet.
+             * 3) updateHeadsetWithCallState now thinks that there are two active calls (Call 2 and
+             * Call 3) when there is actually only one active call (Call 3).
+             */
+            if (call.getParentCall() != null) {
+                // If this call is newly conferenced, ignore the callback. We only care about the
+                // one sent for the parent conference call.
+                Log.d(this, "Ignoring onIsConferenceChanged from child call with new parent");
+                return;
+            }
+            if (call.getChildCalls().size() == 1) {
+                // If this is a parent call with only one child, ignore the callback as well since
+                // the minimum number of child calls to start a conference call is 2. We expect
+                // this to be called again when the parent call has another child call added.
+                Log.d(this, "Ignoring onIsConferenceChanged from parent with only one child call");
+                return;
+            }
+            updateHeadsetWithCallState(false /* force */);
+        }
+
+        @Override
+        public void onDisconnectedTonePlaying(boolean isTonePlaying) {
+            mIsDisconnectedTonePlaying = isTonePlaying;
+            updateHeadsetWithCallState(false /* force */);
+        }
+    };
+
+    /**
+     * Listens to connections and disconnections of bluetooth headsets.  We need to save the current
+     * bluetooth headset so that we know where to send call updates.
+     */
+    @VisibleForTesting
+    public BluetoothProfile.ServiceListener mProfileListener =
+            new BluetoothProfile.ServiceListener() {
+                @Override
+                public void onServiceConnected(int profile, BluetoothProfile proxy) {
+                    synchronized (mLock) {
+                        setBluetoothHeadset(new BluetoothHeadsetProxy((BluetoothHeadset) proxy));
+                        updateHeadsetWithCallState(true /* force */);
+                    }
+                }
+
+                @Override
+                public void onServiceDisconnected(int profile) {
+                    synchronized (mLock) {
+                        mBluetoothHeadset = null;
+                    }
+                }
+            };
+
+    /**
+     * Receives events for global state changes of the bluetooth adapter.
+     */
+    @VisibleForTesting
+    public final BroadcastReceiver mBluetoothAdapterReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            synchronized (mLock) {
+                int state = intent
+                        .getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
+                Log.d(TAG, "Bluetooth Adapter state: %d", state);
+                if (state == BluetoothAdapter.STATE_ON) {
+                    try {
+                        mBinder.queryPhoneState();
+                    } catch (RemoteException e) {
+                        // Remote exception not expected
+                    }
+                }
+            }
+        }
+    };
+
+    private BluetoothAdapterProxy mBluetoothAdapter;
+    private BluetoothHeadsetProxy mBluetoothHeadset;
+
+    // A map from Calls to indexes used to identify calls for CLCC (C* List Current Calls).
+    private Map<Call, Integer> mClccIndexMap = new HashMap<>();
+
+    private boolean mHeadsetUpdatedRecently = false;
+
+    private final Context mContext;
+    private final TelecomSystem.SyncRoot mLock;
+    private final CallsManager mCallsManager;
+    private final PhoneAccountRegistrar mPhoneAccountRegistrar;
+
+    public IBinder getBinder() {
+        return mBinder;
+    }
+
+    public BluetoothPhoneServiceImpl(
+            Context context,
+            TelecomSystem.SyncRoot lock,
+            CallsManager callsManager,
+            BluetoothAdapterProxy bluetoothAdapter,
+            PhoneAccountRegistrar phoneAccountRegistrar) {
+        Log.d(this, "onCreate");
+
+        mContext = context;
+        mLock = lock;
+        mCallsManager = callsManager;
+        mPhoneAccountRegistrar = phoneAccountRegistrar;
+
+        mBluetoothAdapter = bluetoothAdapter;
+        if (mBluetoothAdapter == null) {
+            Log.d(this, "BluetoothPhoneService shutting down, no BT Adapter found.");
+            return;
+        }
+        mBluetoothAdapter.getProfileProxy(context, mProfileListener, BluetoothProfile.HEADSET);
+
+        IntentFilter intentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
+        context.registerReceiver(mBluetoothAdapterReceiver, intentFilter);
+
+        mCallsManager.addListener(mCallsManagerListener);
+        updateHeadsetWithCallState(false /* force */);
+    }
+
+    @VisibleForTesting
+    public void setBluetoothHeadset(BluetoothHeadsetProxy bluetoothHeadset) {
+        mBluetoothHeadset = bluetoothHeadset;
+    }
+
+    private boolean processChld(int chld) {
+        Call activeCall = mCallsManager.getActiveCall();
+        Call ringingCall = mCallsManager.getRingingOrSimulatedRingingCall();
+        Call heldCall = mCallsManager.getHeldCall();
+
+        // TODO: Keeping as Log.i for now.  Move to Log.d after L release if BT proves stable.
+        Log.i(TAG, "Active: %s\nRinging: %s\nHeld: %s", activeCall, ringingCall, heldCall);
+
+        if (chld == CHLD_TYPE_RELEASEHELD) {
+            if (ringingCall != null) {
+                mCallsManager.rejectCall(ringingCall, false, null);
+                return true;
+            } else if (heldCall != null) {
+                mCallsManager.disconnectCall(heldCall);
+                return true;
+            }
+        } else if (chld == CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD) {
+            if (activeCall == null && ringingCall == null && heldCall == null)
+                return false;
+            if (activeCall != null) {
+                mCallsManager.disconnectCall(activeCall);
+                if (ringingCall != null) {
+                    mCallsManager.answerCall(ringingCall, VideoProfile.STATE_AUDIO_ONLY);
+                }
+                return true;
+            }
+            if (ringingCall != null) {
+                mCallsManager.answerCall(ringingCall, ringingCall.getVideoState());
+            } else if (heldCall != null) {
+                mCallsManager.unholdCall(heldCall);
+            }
+            return true;
+        } else if (chld == CHLD_TYPE_HOLDACTIVE_ACCEPTHELD) {
+            if (activeCall != null && activeCall.can(Connection.CAPABILITY_SWAP_CONFERENCE)) {
+                activeCall.swapConference();
+                Log.i(TAG, "CDMA calls in conference swapped, updating headset");
+                updateHeadsetWithCallState(true /* force */);
+                return true;
+            } else if (ringingCall != null) {
+                mCallsManager.answerCall(ringingCall, VideoProfile.STATE_AUDIO_ONLY);
+                return true;
+            } else if (heldCall != null) {
+                // CallsManager will hold any active calls when unhold() is called on a
+                // currently-held call.
+                mCallsManager.unholdCall(heldCall);
+                return true;
+            } else if (activeCall != null && activeCall.can(Connection.CAPABILITY_HOLD)) {
+                mCallsManager.holdCall(activeCall);
+                return true;
+            }
+        } else if (chld == CHLD_TYPE_ADDHELDTOCONF) {
+            if (activeCall != null) {
+                if (activeCall.can(Connection.CAPABILITY_MERGE_CONFERENCE)) {
+                    activeCall.mergeConference();
+                    return true;
+                } else {
+                    List<Call> conferenceable = activeCall.getConferenceableCalls();
+                    if (!conferenceable.isEmpty()) {
+                        mCallsManager.conference(activeCall, conferenceable.get(0));
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    private void enforceModifyPermission() {
+        mContext.enforceCallingOrSelfPermission(
+                android.Manifest.permission.MODIFY_PHONE_STATE, null);
+    }
+
+    private void sendListOfCalls(boolean shouldLog) {
+        Collection<Call> mCalls = mCallsManager.getCalls();
+        for (Call call : mCalls) {
+            // We don't send the parent conference call to the bluetooth device.
+            // We do, however want to send conferences that have no children to the bluetooth
+            // device (e.g. IMS Conference).
+            if (!call.isConference() ||
+                    (call.isConference() && call
+                            .can(Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN))) {
+                sendClccForCall(call, shouldLog);
+            }
+        }
+        sendClccEndMarker();
+    }
+
+    /**
+     * Sends a single clcc (C* List Current Calls) event for the specified call.
+     */
+    private void sendClccForCall(Call call, boolean shouldLog) {
+        boolean isForeground = mCallsManager.getForegroundCall() == call;
+        int state = getBtCallState(call, isForeground);
+        boolean isPartOfConference = false;
+        boolean isConferenceWithNoChildren = call.isConference() && call
+                .can(Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
+
+        if (state == CALL_STATE_IDLE) {
+            return;
+        }
+
+        Call conferenceCall = call.getParentCall();
+        if (conferenceCall != null) {
+            isPartOfConference = true;
+
+            // Run some alternative states for Conference-level merge/swap support.
+            // Basically, if call supports swapping or merging at the conference-level, then we need
+            // to expose the calls as having distinct states (ACTIVE vs CAPABILITY_HOLD) or the
+            // functionality won't show up on the bluetooth device.
+
+            // Before doing any special logic, ensure that we are dealing with an ACTIVE call and
+            // that the conference itself has a notion of the current "active" child call.
+            Call activeChild = conferenceCall.getConferenceLevelActiveCall();
+            if (state == CALL_STATE_ACTIVE && activeChild != null) {
+                // Reevaluate state if we can MERGE or if we can SWAP without previously having
+                // MERGED.
+                boolean shouldReevaluateState =
+                        conferenceCall.can(Connection.CAPABILITY_MERGE_CONFERENCE) ||
+                        (conferenceCall.can(Connection.CAPABILITY_SWAP_CONFERENCE) &&
+                        !conferenceCall.wasConferencePreviouslyMerged());
+
+                if (shouldReevaluateState) {
+                    isPartOfConference = false;
+                    if (call == activeChild) {
+                        state = CALL_STATE_ACTIVE;
+                    } else {
+                        // At this point we know there is an "active" child and we know that it is
+                        // not this call, so set it to HELD instead.
+                        state = CALL_STATE_HELD;
+                    }
+                }
+            }
+            if (conferenceCall.getState() == CallState.ON_HOLD &&
+                    conferenceCall.can(Connection.CAPABILITY_MANAGE_CONFERENCE)) {
+                // If the parent IMS CEP conference call is on hold, we should mark this call as
+                // being on hold regardless of what the other children are doing.
+                state = CALL_STATE_HELD;
+            }
+        } else if (isConferenceWithNoChildren) {
+            // Handle the special case of an IMS conference call without conference event package
+            // support.  The call will be marked as a conference, but the conference will not have
+            // child calls where conference event packages are not used by the carrier.
+            isPartOfConference = true;
+        }
+
+        int index = getIndexForCall(call);
+        int direction = call.isIncoming() ? 1 : 0;
+        final Uri addressUri;
+        if (call.getGatewayInfo() != null) {
+            addressUri = call.getGatewayInfo().getOriginalAddress();
+        } else {
+            addressUri = call.getHandle();
+        }
+
+        String address = addressUri == null ? null : addressUri.getSchemeSpecificPart();
+        if (address != null) {
+            address = PhoneNumberUtils.stripSeparators(address);
+        }
+
+        int addressType = address == null ? -1 : PhoneNumberUtils.toaFromString(address);
+
+        if (shouldLog) {
+            Log.i(this, "sending clcc for call %d, %d, %d, %b, %s, %d",
+                    index, direction, state, isPartOfConference, Log.piiHandle(address),
+                    addressType);
+        }
+
+        if (mBluetoothHeadset != null) {
+            mBluetoothHeadset.clccResponse(
+                    index, direction, state, 0, isPartOfConference, address, addressType);
+        }
+    }
+
+    private void sendClccEndMarker() {
+        // End marker is recognized with an index value of 0. All other parameters are ignored.
+        if (mBluetoothHeadset != null) {
+            mBluetoothHeadset.clccResponse(0 /* index */, 0, 0, 0, false, null, 0);
+        }
+    }
+
+    /**
+     * Returns the caches index for the specified call.  If no such index exists, then an index is
+     * given (smallest number starting from 1 that isn't already taken).
+     */
+    private int getIndexForCall(Call call) {
+        if (mClccIndexMap.containsKey(call)) {
+            return mClccIndexMap.get(call);
+        }
+
+        int i = 1;  // Indexes for bluetooth clcc are 1-based.
+        while (mClccIndexMap.containsValue(i)) {
+            i++;
+        }
+
+        // NOTE: Indexes are removed in {@link #onCallRemoved}.
+        mClccIndexMap.put(call, i);
+        return i;
+    }
+
+    /**
+     * Sends an update of the current call state to the current Headset.
+     *
+     * @param force {@code true} if the headset state should be sent regardless if no changes to the
+     *      state have occurred, {@code false} if the state should only be sent if the state has
+     *      changed.
+     */
+    private void updateHeadsetWithCallState(boolean force) {
+        Call activeCall = mCallsManager.getActiveCall();
+        Call ringingCall = mCallsManager.getRingingOrSimulatedRingingCall();
+        Call heldCall = mCallsManager.getHeldCall();
+
+        int bluetoothCallState = getBluetoothCallStateForUpdate();
+
+        String ringingAddress = null;
+        int ringingAddressType = DEFAULT_RINGING_ADDRESS_TYPE;
+        String ringingName = null;
+        if (ringingCall != null && ringingCall.getHandle() != null
+            && !ringingCall.isSilentRingingRequested()) {
+            ringingAddress = ringingCall.getHandle().getSchemeSpecificPart();
+            if (ringingAddress != null) {
+                ringingAddressType = PhoneNumberUtils.toaFromString(ringingAddress);
+            }
+            ringingName = ringingCall.getCallerDisplayName();
+            if (TextUtils.isEmpty(ringingName)) {
+                ringingName = ringingCall.getName();
+            }
+        }
+        if (ringingAddress == null) {
+            ringingAddress = "";
+        }
+
+        int numActiveCalls = activeCall == null ? 0 : 1;
+        int numHeldCalls = mCallsManager.getNumHeldCalls();
+        int numChildrenOfActiveCall = activeCall == null ? 0 : activeCall.getChildCalls().size();
+
+        // Intermediate state for GSM calls which are in the process of being swapped.
+        // TODO: Should we be hardcoding this value to 2 or should we check if all top level calls
+        //       are held?
+        boolean callsPendingSwitch = (numHeldCalls == 2);
+
+        // For conference calls which support swapping the active call within the conference
+        // (namely CDMA calls) we need to expose that as a held call in order for the BT device
+        // to show "swap" and "merge" functionality.
+        boolean ignoreHeldCallChange = false;
+        if (activeCall != null && activeCall.isConference() &&
+                !activeCall.can(Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN)) {
+            if (activeCall.can(Connection.CAPABILITY_SWAP_CONFERENCE)) {
+                // Indicate that BT device should show SWAP command by indicating that there is a
+                // call on hold, but only if the conference wasn't previously merged.
+                numHeldCalls = activeCall.wasConferencePreviouslyMerged() ? 0 : 1;
+            } else if (activeCall.can(Connection.CAPABILITY_MERGE_CONFERENCE)) {
+                numHeldCalls = 1;  // Merge is available, so expose via numHeldCalls.
+            }
+
+            for (Call childCall : activeCall.getChildCalls()) {
+                // Held call has changed due to it being combined into a CDMA conference. Keep
+                // track of this and ignore any future update since it doesn't really count as
+                // a call change.
+                if (mOldHeldCall == childCall) {
+                    ignoreHeldCallChange = true;
+                    break;
+                }
+            }
+        }
+
+        if (mBluetoothHeadset != null &&
+                (force ||
+                        (!callsPendingSwitch &&
+                                (numActiveCalls != mNumActiveCalls ||
+                                        numChildrenOfActiveCall != mNumChildrenOfActiveCall ||
+                                        numHeldCalls != mNumHeldCalls ||
+                                        bluetoothCallState != mBluetoothCallState ||
+                                        !TextUtils.equals(ringingAddress, mRingingAddress) ||
+                                        ringingAddressType != mRingingAddressType ||
+                                (heldCall != mOldHeldCall && !ignoreHeldCallChange))))) {
+
+            // If the call is transitioning into the alerting state, send DIALING first.
+            // Some devices expect to see a DIALING state prior to seeing an ALERTING state
+            // so we need to send it first.
+            boolean sendDialingFirst = mBluetoothCallState != bluetoothCallState &&
+                    bluetoothCallState == CALL_STATE_ALERTING;
+
+            mOldHeldCall = heldCall;
+            mNumActiveCalls = numActiveCalls;
+            mNumChildrenOfActiveCall = numChildrenOfActiveCall;
+            mNumHeldCalls = numHeldCalls;
+            mBluetoothCallState = bluetoothCallState;
+            mRingingAddress = ringingAddress;
+            mRingingAddressType = ringingAddressType;
+
+            if (sendDialingFirst) {
+                // Log in full to make logs easier to debug.
+                Log.i(TAG, "updateHeadsetWithCallState " +
+                        "numActive %s, " +
+                        "numHeld %s, " +
+                        "callState %s, " +
+                        "ringing number %s, " +
+                        "ringing type %s, " +
+                        "ringing name %s",
+                        mNumActiveCalls,
+                        mNumHeldCalls,
+                        CALL_STATE_DIALING,
+                        Log.pii(mRingingAddress),
+                        mRingingAddressType,
+                        Log.pii(ringingName));
+                mBluetoothHeadset.phoneStateChanged(
+                        mNumActiveCalls,
+                        mNumHeldCalls,
+                        CALL_STATE_DIALING,
+                        mRingingAddress,
+                        mRingingAddressType,
+                        ringingName);
+            }
+
+            Log.i(TAG, "updateHeadsetWithCallState " +
+                    "numActive %s, " +
+                    "numHeld %s, " +
+                    "callState %s, " +
+                    "ringing number %s, " +
+                    "ringing type %s, " +
+                    "ringing name %s",
+                    mNumActiveCalls,
+                    mNumHeldCalls,
+                    mBluetoothCallState,
+                    Log.pii(mRingingAddress),
+                    mRingingAddressType,
+                    Log.pii(ringingName));
+
+            mBluetoothHeadset.phoneStateChanged(
+                    mNumActiveCalls,
+                    mNumHeldCalls,
+                    mBluetoothCallState,
+                    mRingingAddress,
+                    mRingingAddressType,
+                    ringingName);
+
+            mHeadsetUpdatedRecently = true;
+        }
+    }
+
+    private int getBluetoothCallStateForUpdate() {
+        Call ringingCall = mCallsManager.getRingingOrSimulatedRingingCall();
+        Call dialingCall = mCallsManager.getOutgoingCall();
+        boolean hasOnlyDisconnectedCalls = mCallsManager.hasOnlyDisconnectedCalls();
+
+        //
+        // !! WARNING !!
+        // You will note that CALL_STATE_WAITING, CALL_STATE_HELD, and CALL_STATE_ACTIVE are not
+        // used in this version of the call state mappings.  This is on purpose.
+        // phone_state_change() in btif_hf.c is not written to handle these states. Only with the
+        // listCalls*() method are WAITING and ACTIVE used.
+        // Using the unsupported states here caused problems with inconsistent state in some
+        // bluetooth devices (like not getting out of ringing state after answering a call).
+        //
+        int bluetoothCallState = CALL_STATE_IDLE;
+        if (ringingCall != null && !ringingCall.isSilentRingingRequested()) {
+            bluetoothCallState = CALL_STATE_INCOMING;
+        } else if (dialingCall != null) {
+            bluetoothCallState = CALL_STATE_ALERTING;
+        } else if (hasOnlyDisconnectedCalls || mIsDisconnectedTonePlaying) {
+            // Keep the DISCONNECTED state until the disconnect tone's playback is done
+            bluetoothCallState = CALL_STATE_DISCONNECTED;
+        }
+        return bluetoothCallState;
+    }
+
+    private int getBtCallState(Call call, boolean isForeground) {
+        switch (call.getState()) {
+            case CallState.NEW:
+            case CallState.ABORTED:
+            case CallState.DISCONNECTED:
+            case CallState.AUDIO_PROCESSING:
+                return CALL_STATE_IDLE;
+
+            case CallState.ACTIVE:
+                return CALL_STATE_ACTIVE;
+
+            case CallState.CONNECTING:
+            case CallState.SELECT_PHONE_ACCOUNT:
+            case CallState.DIALING:
+            case CallState.PULLING:
+                // Yes, this is correctly returning ALERTING.
+                // "Dialing" for BT means that we have sent information to the service provider
+                // to place the call but there is no confirmation that the call is going through.
+                // When there finally is confirmation, the ringback is played which is referred to
+                // as an "alert" tone, thus, ALERTING.
+                // TODO: We should consider using the ALERTING terms in Telecom because that
+                // seems to be more industry-standard.
+                return CALL_STATE_ALERTING;
+
+            case CallState.ON_HOLD:
+                return CALL_STATE_HELD;
+
+            case CallState.RINGING:
+            case CallState.ANSWERED:
+            case CallState.SIMULATED_RINGING:
+                if (call.isSilentRingingRequested()) {
+                    return CALL_STATE_IDLE;
+                } else if (isForeground) {
+                    return CALL_STATE_INCOMING;
+                } else {
+                    return CALL_STATE_WAITING;
+                }
+        }
+        return CALL_STATE_IDLE;
+    }
+
+    /**
+     * Returns the best phone account to use for the given state of all calls.
+     * First, tries to return the phone account for the foreground call, second the default
+     * phone account for PhoneAccount.SCHEME_TEL.
+     */
+    private PhoneAccount getBestPhoneAccount() {
+        if (mPhoneAccountRegistrar == null) {
+            return null;
+        }
+
+        Call call = mCallsManager.getForegroundCall();
+
+        PhoneAccount account = null;
+        if (call != null) {
+            // First try to get the network name of the foreground call.
+            account = mPhoneAccountRegistrar.getPhoneAccountOfCurrentUser(
+                    call.getTargetPhoneAccount());
+        }
+
+        if (account == null) {
+            // Second, Try to get the label for the default Phone Account.
+            account = mPhoneAccountRegistrar.getPhoneAccountUnchecked(
+                    mPhoneAccountRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(
+                            PhoneAccount.SCHEME_TEL));
+        }
+        return account;
+    }
+}
diff --git a/src/com/android/server/telecom/TelecomSystem.java b/src/com/android/server/telecom/TelecomSystem.java
index 8928e76..4842796 100644
--- a/src/com/android/server/telecom/TelecomSystem.java
+++ b/src/com/android/server/telecom/TelecomSystem.java
@@ -26,6 +26,7 @@
 import com.android.server.telecom.ui.DisconnectedCallNotifier;
 import com.android.server.telecom.ui.IncomingCallNotifier;
 import com.android.server.telecom.ui.MissedCallNotifierImpl.MissedCallNotifierImplFactory;
+import com.android.server.telecom.BluetoothPhoneServiceImpl.BluetoothPhoneServiceImplFactory;
 import com.android.server.telecom.CallAudioManager.AudioServiceFactory;
 import com.android.server.telecom.DefaultDialerCache.DefaultDialerManagerAdapter;
 import com.android.server.telecom.ui.ToastFactory;
@@ -114,6 +115,7 @@
     private final CallsManager mCallsManager;
     private final RespondViaSmsManager mRespondViaSmsManager;
     private final Context mContext;
+    private final BluetoothPhoneServiceImpl mBluetoothPhoneServiceImpl;
     private final CallIntentProcessor mCallIntentProcessor;
     private final TelecomBroadcastIntentProcessor mTelecomBroadcastIntentProcessor;
     private final TelecomServiceImpl mTelecomServiceImpl;
@@ -190,6 +192,8 @@
             ProximitySensorManagerFactory proximitySensorManagerFactory,
             InCallWakeLockControllerFactory inCallWakeLockControllerFactory,
             AudioServiceFactory audioServiceFactory,
+            BluetoothPhoneServiceImplFactory
+                    bluetoothPhoneServiceImplFactory,
             ConnectionServiceFocusManager.ConnectionServiceFocusManagerFactory
                     connectionServiceFocusManagerFactory,
             Timeouts.Adapter timeoutsAdapter,
@@ -346,6 +350,8 @@
             mCallsManager.onUserSwitch(currentUserHandle);
         }
 
+        mBluetoothPhoneServiceImpl = bluetoothPhoneServiceImplFactory.makeBluetoothPhoneServiceImpl(
+                mContext, mLock, mCallsManager, mPhoneAccountRegistrar);
         mCallIntentProcessor = new CallIntentProcessor(mContext, mCallsManager, defaultDialerCache);
         mTelecomBroadcastIntentProcessor = new TelecomBroadcastIntentProcessor(
                 mContext, mCallsManager);
@@ -383,6 +389,10 @@
         return mCallsManager;
     }
 
+    public BluetoothPhoneServiceImpl getBluetoothPhoneServiceImpl() {
+        return mBluetoothPhoneServiceImpl;
+    }
+
     public CallIntentProcessor getCallIntentProcessor() {
         return mCallIntentProcessor;
     }
diff --git a/src/com/android/server/telecom/components/BluetoothPhoneService.java b/src/com/android/server/telecom/components/BluetoothPhoneService.java
new file mode 100644
index 0000000..c5e195c
--- /dev/null
+++ b/src/com/android/server/telecom/components/BluetoothPhoneService.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 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.server.telecom.components;
+
+import com.android.server.telecom.TelecomSystem;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+/**
+ * Bluetooth headset manager for Telecom. This class shares the call state with the bluetooth device
+ * and accepts call-related commands to perform on behalf of the BT device.
+ */
+public final class BluetoothPhoneService extends Service implements TelecomSystem.Component {
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        synchronized (getTelecomSystem().getLock()) {
+            return getTelecomSystem().getBluetoothPhoneServiceImpl().getBinder();
+        }
+    }
+
+    @Override
+    public TelecomSystem getTelecomSystem() {
+        return TelecomSystem.getInstance();
+    }
+}
diff --git a/src/com/android/server/telecom/components/TelecomService.java b/src/com/android/server/telecom/components/TelecomService.java
index 9ad0da4..271264d 100644
--- a/src/com/android/server/telecom/components/TelecomService.java
+++ b/src/com/android/server/telecom/components/TelecomService.java
@@ -18,6 +18,7 @@
 
 import android.app.Service;
 import android.app.role.RoleManager;
+import android.bluetooth.BluetoothAdapter;
 import android.content.Context;
 import android.content.Intent;
 import android.media.IAudioService;
@@ -34,6 +35,8 @@
 import com.android.internal.telecom.ITelecomLoader;
 import com.android.internal.telecom.ITelecomService;
 import com.android.server.telecom.AsyncRingtonePlayer;
+import com.android.server.telecom.BluetoothAdapterProxy;
+import com.android.server.telecom.BluetoothPhoneServiceImpl;
 import com.android.server.telecom.CallAudioModeStateMachine;
 import com.android.server.telecom.CallAudioRouteStateMachine;
 import com.android.server.telecom.CallerInfoAsyncQueryFactory;
@@ -169,6 +172,17 @@
                                             ServiceManager.getService(Context.AUDIO_SERVICE));
                                 }
                             },
+                            new BluetoothPhoneServiceImpl.BluetoothPhoneServiceImplFactory() {
+                                @Override
+                                public BluetoothPhoneServiceImpl makeBluetoothPhoneServiceImpl(
+                                        Context context, TelecomSystem.SyncRoot lock,
+                                        CallsManager callsManager,
+                                        PhoneAccountRegistrar phoneAccountRegistrar) {
+                                    return new BluetoothPhoneServiceImpl(context, lock,
+                                            callsManager, new BluetoothAdapterProxy(),
+                                            phoneAccountRegistrar);
+                                }
+                            },
                             ConnectionServiceFocusManager::new,
                             new Timeouts.Adapter(),
                             new AsyncRingtonePlayer(),
@@ -193,6 +207,9 @@
                             new ContactsAsyncHelper.Factory(),
                             internalServiceRetriever.getDeviceIdleController()));
         }
+        if (BluetoothAdapter.getDefaultAdapter() != null) {
+            context.startService(new Intent(context, BluetoothPhoneService.class));
+        }
     }
 
     @Override
diff --git a/tests/src/com/android/server/telecom/tests/BluetoothPhoneServiceTest.java b/tests/src/com/android/server/telecom/tests/BluetoothPhoneServiceTest.java
new file mode 100644
index 0000000..532cc7e
--- /dev/null
+++ b/tests/src/com/android/server/telecom/tests/BluetoothPhoneServiceTest.java
@@ -0,0 +1,1136 @@
+/*
+ * Copyright (C) 2015 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.server.telecom.tests;
+
+import android.bluetooth.BluetoothAdapter;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.graphics.drawable.Icon;
+import android.net.Uri;
+import android.os.Binder;
+import android.telecom.Connection;
+import android.telecom.GatewayInfo;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.TelephonyManager;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.server.telecom.BluetoothAdapterProxy;
+import com.android.server.telecom.BluetoothHeadsetProxy;
+import com.android.server.telecom.BluetoothPhoneServiceImpl;
+import com.android.server.telecom.Call;
+import com.android.server.telecom.CallState;
+import com.android.server.telecom.CallsManager;
+import com.android.server.telecom.PhoneAccountRegistrar;
+import com.android.server.telecom.TelecomSystem;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyChar;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.isNull;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
+
+@RunWith(JUnit4.class)
+public class BluetoothPhoneServiceTest extends TelecomTestCase {
+
+    private static final int TEST_DTMF_TONE = 0;
+    private static final String TEST_ACCOUNT_ADDRESS = "//foo.com/";
+    private static final int TEST_ACCOUNT_INDEX = 0;
+
+    // match up with BluetoothPhoneServiceImpl
+    private static final int CALL_STATE_ACTIVE = 0;
+    private static final int CALL_STATE_HELD = 1;
+    private static final int CALL_STATE_DIALING = 2;
+    private static final int CALL_STATE_ALERTING = 3;
+    private static final int CALL_STATE_INCOMING = 4;
+    private static final int CALL_STATE_WAITING = 5;
+    private static final int CALL_STATE_IDLE = 6;
+    private static final int CALL_STATE_DISCONNECTED = 7;
+    // Terminate all held or set UDUB("busy") to a waiting call
+    private static final int CHLD_TYPE_RELEASEHELD = 0;
+    // Terminate all active calls and accepts a waiting/held call
+    private static final int CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD = 1;
+    // Hold all active calls and accepts a waiting/held call
+    private static final int CHLD_TYPE_HOLDACTIVE_ACCEPTHELD = 2;
+    // Add all held calls to a conference
+    private static final int CHLD_TYPE_ADDHELDTOCONF = 3;
+
+    private BluetoothPhoneServiceImpl mBluetoothPhoneService;
+    private final TelecomSystem.SyncRoot mLock = new TelecomSystem.SyncRoot() {
+    };
+
+    @Mock CallsManager mMockCallsManager;
+    @Mock PhoneAccountRegistrar mMockPhoneAccountRegistrar;
+    @Mock BluetoothHeadsetProxy mMockBluetoothHeadset;
+
+    @Override
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        MockitoAnnotations.initMocks(this);
+        mContext = mComponentContextFixture.getTestDouble().getApplicationContext();
+
+        // Ensure initialization does not actually try to access any of the CallsManager fields.
+        // This also works to return null if it is not overwritten later in the test.
+        doNothing().when(mMockCallsManager).addListener(any(
+                CallsManager.CallsManagerListener.class));
+        doReturn(null).when(mMockCallsManager).getActiveCall();
+        doReturn(null).when(mMockCallsManager).getRingingOrSimulatedRingingCall();
+        doReturn(null).when(mMockCallsManager).getHeldCall();
+        doReturn(null).when(mMockCallsManager).getOutgoingCall();
+        doReturn(0).when(mMockCallsManager).getNumHeldCalls();
+        doReturn(false).when(mMockCallsManager).hasOnlyDisconnectedCalls();
+        mBluetoothPhoneService = new BluetoothPhoneServiceImpl(mContext, mLock, mMockCallsManager,
+                mock(BluetoothAdapterProxy.class), mMockPhoneAccountRegistrar);
+
+        // Bring in test Bluetooth Headset
+        mBluetoothPhoneService.setBluetoothHeadset(mMockBluetoothHeadset);
+    }
+
+    @Override
+    @After
+    public void tearDown() throws Exception {
+
+        mBluetoothPhoneService = null;
+        super.tearDown();
+    }
+
+    @SmallTest
+    @Test
+    public void testHeadsetAnswerCall() throws Exception {
+        Call mockCall = createRingingCall();
+
+        boolean callAnswered = mBluetoothPhoneService.mBinder.answerCall();
+
+        verify(mMockCallsManager).answerCall(eq(mockCall), any(int.class));
+        assertEquals(callAnswered, true);
+    }
+
+    @SmallTest
+    @Test
+    public void testHeadsetAnswerCallNull() throws Exception {
+        when(mMockCallsManager.getRingingOrSimulatedRingingCall()).thenReturn(null);
+
+        boolean callAnswered = mBluetoothPhoneService.mBinder.answerCall();
+
+        verify(mMockCallsManager,never()).answerCall(any(Call.class), any(int.class));
+        assertEquals(callAnswered, false);
+    }
+
+    @SmallTest
+    @Test
+    public void testHeadsetHangupCall() throws Exception {
+        Call mockCall = createForegroundCall();
+
+        boolean callHungup = mBluetoothPhoneService.mBinder.hangupCall();
+
+        verify(mMockCallsManager).disconnectCall(eq(mockCall));
+        assertEquals(callHungup, true);
+    }
+
+    @SmallTest
+    @Test
+    public void testHeadsetHangupCallNull() throws Exception {
+        when(mMockCallsManager.getForegroundCall()).thenReturn(null);
+
+        boolean callHungup = mBluetoothPhoneService.mBinder.hangupCall();
+
+        verify(mMockCallsManager,never()).disconnectCall(any(Call.class));
+        assertEquals(callHungup, false);
+    }
+
+    @SmallTest
+    @Test
+    public void testHeadsetSendDTMF() throws Exception {
+        Call mockCall = createForegroundCall();
+
+        boolean sentDtmf = mBluetoothPhoneService.mBinder.sendDtmf(TEST_DTMF_TONE);
+
+        verify(mMockCallsManager).playDtmfTone(eq(mockCall), eq((char) TEST_DTMF_TONE));
+        verify(mMockCallsManager).stopDtmfTone(eq(mockCall));
+        assertEquals(sentDtmf, true);
+    }
+
+    @SmallTest
+    @Test
+    public void testHeadsetSendDTMFNull() throws Exception {
+        when(mMockCallsManager.getForegroundCall()).thenReturn(null);
+
+        boolean sentDtmf = mBluetoothPhoneService.mBinder.sendDtmf(TEST_DTMF_TONE);
+
+        verify(mMockCallsManager,never()).playDtmfTone(any(Call.class), anyChar());
+        verify(mMockCallsManager,never()).stopDtmfTone(any(Call.class));
+        assertEquals(sentDtmf, false);
+    }
+
+    @SmallTest
+    @Test
+    public void testGetNetworkOperator() throws Exception {
+        Call mockCall = createForegroundCall();
+        PhoneAccount fakePhoneAccount = makeQuickAccount("id0", TEST_ACCOUNT_INDEX);
+        when(mMockPhoneAccountRegistrar.getPhoneAccountOfCurrentUser(
+                nullable(PhoneAccountHandle.class))).thenReturn(fakePhoneAccount);
+
+        String networkOperator = mBluetoothPhoneService.mBinder.getNetworkOperator();
+
+        assertEquals(networkOperator, "label0");
+    }
+
+    @SmallTest
+    @Test
+    public void testGetNetworkOperatorNoPhoneAccount() throws Exception {
+        when(mMockCallsManager.getForegroundCall()).thenReturn(null);
+
+        String networkOperator = mBluetoothPhoneService.mBinder.getNetworkOperator();
+
+        assertEquals(networkOperator, "label1");
+    }
+
+    @SmallTest
+    @Test
+    public void testGetSubscriberNumber() throws Exception {
+        Call mockCall = createForegroundCall();
+        PhoneAccount fakePhoneAccount = makeQuickAccount("id0", TEST_ACCOUNT_INDEX);
+        when(mMockPhoneAccountRegistrar.getPhoneAccountOfCurrentUser(
+                nullable(PhoneAccountHandle.class))).thenReturn(fakePhoneAccount);
+
+        String subscriberNumber = mBluetoothPhoneService.mBinder.getSubscriberNumber();
+
+        assertEquals(subscriberNumber, TEST_ACCOUNT_ADDRESS + TEST_ACCOUNT_INDEX);
+    }
+
+    @SmallTest
+    @Test
+    public void testGetSubscriberNumberFallbackToTelephony() throws Exception {
+        Call mockCall = createForegroundCall();
+        String fakeNumber = "8675309";
+        when(mMockPhoneAccountRegistrar.getPhoneAccountOfCurrentUser(
+                nullable(PhoneAccountHandle.class))).thenReturn(null);
+        when(mMockPhoneAccountRegistrar.getPhoneAccountUnchecked(
+                nullable(PhoneAccountHandle.class))).thenReturn(null);
+        when(mComponentContextFixture.getTelephonyManager().getLine1Number())
+                .thenReturn(fakeNumber);
+
+        String subscriberNumber = mBluetoothPhoneService.mBinder.getSubscriberNumber();
+
+        assertEquals(subscriberNumber, fakeNumber);
+    }
+
+    @MediumTest
+    @Test
+    public void testListCurrentCallsOneCall() throws Exception {
+        ArrayList<Call> calls = new ArrayList<>();
+        Call activeCall = createActiveCall();
+        when(activeCall.getState()).thenReturn(CallState.ACTIVE);
+        calls.add(activeCall);
+        when(activeCall.isConference()).thenReturn(false);
+        when(activeCall.getHandle()).thenReturn(Uri.parse("tel:555-000"));
+        when(mMockCallsManager.getCalls()).thenReturn(calls);
+
+        mBluetoothPhoneService.mBinder.listCurrentCalls();
+
+        verify(mMockBluetoothHeadset).clccResponse(eq(1), eq(0), eq(0), eq(0), eq(false),
+                eq("555000"), eq(PhoneNumberUtils.TOA_Unknown));
+        verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
+    }
+
+    @MediumTest
+    @Test
+    public void testListCurrentCallsSilentRinging() throws Exception {
+        ArrayList<Call> calls = new ArrayList<>();
+        Call silentRingingCall = createActiveCall();
+        when(silentRingingCall.getState()).thenReturn(CallState.RINGING);
+        when(silentRingingCall.isSilentRingingRequested()).thenReturn(true);
+        calls.add(silentRingingCall);
+        when(silentRingingCall.isConference()).thenReturn(false);
+        when(silentRingingCall.getHandle()).thenReturn(Uri.parse("tel:555-000"));
+        when(mMockCallsManager.getCalls()).thenReturn(calls);
+        when(mMockCallsManager.getRingingOrSimulatedRingingCall()).thenReturn(silentRingingCall);
+
+        mBluetoothPhoneService.mBinder.listCurrentCalls();
+
+        verify(mMockBluetoothHeadset, never()).clccResponse(eq(1), eq(0), eq(0), eq(0), eq(false),
+            eq("555000"), eq(PhoneNumberUtils.TOA_Unknown));
+        verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
+    }
+
+    @MediumTest
+    @Test
+    public void testConferenceInProgressCDMA() throws Exception {
+        // If two calls are being conferenced and updateHeadsetWithCallState runs while this is
+        // still occuring, it will look like there is an active and held call still while we are
+        // transitioning into a conference.
+        // Call has been put into a CDMA "conference" with one call on hold.
+        ArrayList<Call> calls = new ArrayList<>();
+        Call parentCall = createActiveCall();
+        final Call confCall1 = mock(Call.class);
+        final Call confCall2 = createHeldCall();
+        calls.add(parentCall);
+        calls.add(confCall1);
+        calls.add(confCall2);
+        when(mMockCallsManager.getCalls()).thenReturn(calls);
+        when(confCall1.getState()).thenReturn(CallState.ACTIVE);
+        when(confCall2.getState()).thenReturn(CallState.ACTIVE);
+        when(confCall1.isIncoming()).thenReturn(false);
+        when(confCall2.isIncoming()).thenReturn(true);
+        when(confCall1.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
+                Uri.parse("tel:555-0000")));
+        when(confCall2.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
+                Uri.parse("tel:555-0001")));
+        addCallCapability(parentCall, Connection.CAPABILITY_MERGE_CONFERENCE);
+        addCallCapability(parentCall, Connection.CAPABILITY_SWAP_CONFERENCE);
+        removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
+        when(parentCall.getConferenceLevelActiveCall()).thenReturn(confCall1);
+        when(parentCall.isConference()).thenReturn(true);
+        when(parentCall.getChildCalls()).thenReturn(new LinkedList<Call>() {{
+            add(confCall1);
+            add(confCall2);
+        }});
+        //Add links from child calls to parent
+        when(confCall1.getParentCall()).thenReturn(parentCall);
+        when(confCall2.getParentCall()).thenReturn(parentCall);
+
+        mBluetoothPhoneService.mBinder.queryPhoneState();
+        verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(1), eq(CALL_STATE_IDLE),
+                eq(""), eq(128), nullable(String.class));
+        when(parentCall.wasConferencePreviouslyMerged()).thenReturn(true);
+        mBluetoothPhoneService.mCallsManagerListener.onIsConferencedChanged(parentCall);
+        verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(0), eq(CALL_STATE_IDLE),
+                eq(""), eq(128), nullable(String.class));
+        when(mMockCallsManager.getHeldCall()).thenReturn(null);
+        // Spurious call to onIsConferencedChanged.
+        mBluetoothPhoneService.mCallsManagerListener.onIsConferencedChanged(parentCall);
+        // Make sure the call has only occurred collectively 2 times (not on the third)
+        verify(mMockBluetoothHeadset, times(2)).phoneStateChanged(any(int.class),
+                any(int.class), any(int.class), nullable(String.class), any(int.class),
+                nullable(String.class));
+    }
+
+    @MediumTest
+    @Test
+    public void testListCurrentCallsCdmaHold() throws Exception {
+        // Call has been put into a CDMA "conference" with one call on hold.
+        ArrayList<Call> calls = new ArrayList<>();
+        Call parentCall = createActiveCall();
+        final Call foregroundCall = mock(Call.class);
+        final Call heldCall = createHeldCall();
+        calls.add(parentCall);
+        calls.add(foregroundCall);
+        calls.add(heldCall);
+        when(mMockCallsManager.getCalls()).thenReturn(calls);
+        when(foregroundCall.getState()).thenReturn(CallState.ACTIVE);
+        when(heldCall.getState()).thenReturn(CallState.ACTIVE);
+        when(foregroundCall.isIncoming()).thenReturn(false);
+        when(heldCall.isIncoming()).thenReturn(true);
+        when(foregroundCall.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
+                Uri.parse("tel:555-0000")));
+        when(heldCall.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
+                Uri.parse("tel:555-0001")));
+        addCallCapability(parentCall, Connection.CAPABILITY_MERGE_CONFERENCE);
+        addCallCapability(parentCall, Connection.CAPABILITY_SWAP_CONFERENCE);
+        removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
+        when(parentCall.getConferenceLevelActiveCall()).thenReturn(foregroundCall);
+        when(parentCall.isConference()).thenReturn(true);
+        when(parentCall.getChildCalls()).thenReturn(new LinkedList<Call>() {{
+            add(foregroundCall);
+            add(heldCall);
+        }});
+        //Add links from child calls to parent
+        when(foregroundCall.getParentCall()).thenReturn(parentCall);
+        when(heldCall.getParentCall()).thenReturn(parentCall);
+
+        mBluetoothPhoneService.mBinder.listCurrentCalls();
+
+        verify(mMockBluetoothHeadset).clccResponse(eq(1), eq(0), eq(CALL_STATE_ACTIVE), eq(0),
+                eq(false), eq("5550000"), eq(PhoneNumberUtils.TOA_Unknown));
+        verify(mMockBluetoothHeadset).clccResponse(eq(2), eq(1), eq(CALL_STATE_HELD), eq(0),
+                eq(false), eq("5550001"), eq(PhoneNumberUtils.TOA_Unknown));
+        verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
+    }
+
+    @MediumTest
+    @Test
+    public void testListCurrentCallsCdmaConference() throws Exception {
+        // Call is in a true CDMA conference
+        ArrayList<Call> calls = new ArrayList<>();
+        Call parentCall = createActiveCall();
+        final Call confCall1 = mock(Call.class);
+        final Call confCall2 = createHeldCall();
+        calls.add(parentCall);
+        calls.add(confCall1);
+        calls.add(confCall2);
+        when(mMockCallsManager.getCalls()).thenReturn(calls);
+        when(confCall1.getState()).thenReturn(CallState.ACTIVE);
+        when(confCall2.getState()).thenReturn(CallState.ACTIVE);
+        when(confCall1.isIncoming()).thenReturn(false);
+        when(confCall2.isIncoming()).thenReturn(true);
+        when(confCall1.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
+                Uri.parse("tel:555-0000")));
+        when(confCall2.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
+                Uri.parse("tel:555-0001")));
+        removeCallCapability(parentCall, Connection.CAPABILITY_MERGE_CONFERENCE);
+        removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
+        when(parentCall.wasConferencePreviouslyMerged()).thenReturn(true);
+        when(parentCall.getConferenceLevelActiveCall()).thenReturn(confCall1);
+        when(parentCall.isConference()).thenReturn(true);
+        when(parentCall.getChildCalls()).thenReturn(new LinkedList<Call>() {{
+            add(confCall1);
+            add(confCall2);
+        }});
+        //Add links from child calls to parent
+        when(confCall1.getParentCall()).thenReturn(parentCall);
+        when(confCall2.getParentCall()).thenReturn(parentCall);
+
+        mBluetoothPhoneService.mBinder.listCurrentCalls();
+
+        verify(mMockBluetoothHeadset).clccResponse(eq(1), eq(0), eq(CALL_STATE_ACTIVE), eq(0),
+                eq(true), eq("5550000"), eq(PhoneNumberUtils.TOA_Unknown));
+        verify(mMockBluetoothHeadset).clccResponse(eq(2), eq(1), eq(CALL_STATE_ACTIVE), eq(0),
+                eq(true), eq("5550001"), eq(PhoneNumberUtils.TOA_Unknown));
+        verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
+    }
+
+    @MediumTest
+    @Test
+    public void testWaitingCallClccResponse() throws Exception {
+        ArrayList<Call> calls = new ArrayList<>();
+        when(mMockCallsManager.getCalls()).thenReturn(calls);
+        // This test does not define a value for getForegroundCall(), so this ringing call will
+        // be treated as if it is a waiting call when listCurrentCalls() is invoked.
+        Call waitingCall = createRingingCall();
+        calls.add(waitingCall);
+        when(waitingCall.isIncoming()).thenReturn(true);
+        when(waitingCall.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
+                Uri.parse("tel:555-0000")));
+        when(waitingCall.getState()).thenReturn(CallState.RINGING);
+        when(waitingCall.isConference()).thenReturn(false);
+
+        mBluetoothPhoneService.mBinder.listCurrentCalls();
+        verify(mMockBluetoothHeadset).clccResponse(1, 1, CALL_STATE_WAITING, 0, false,
+                "5550000", PhoneNumberUtils.TOA_Unknown);
+        verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
+        verify(mMockBluetoothHeadset, times(2)).clccResponse(anyInt(),
+                anyInt(), anyInt(), anyInt(), anyBoolean(), nullable(String.class), anyInt());
+    }
+
+    @MediumTest
+    @Test
+    public void testNewCallClccResponse() throws Exception {
+        ArrayList<Call> calls = new ArrayList<>();
+        when(mMockCallsManager.getCalls()).thenReturn(calls);
+        Call newCall = createForegroundCall();
+        calls.add(newCall);
+        when(newCall.getState()).thenReturn(CallState.NEW);
+        when(newCall.isConference()).thenReturn(false);
+
+        mBluetoothPhoneService.mBinder.listCurrentCalls();
+        verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
+        verify(mMockBluetoothHeadset, times(1)).clccResponse(anyInt(),
+                anyInt(), anyInt(), anyInt(), anyBoolean(), nullable(String.class), anyInt());
+    }
+
+    @MediumTest
+    @Test
+    public void testRingingCallClccResponse() throws Exception {
+        ArrayList<Call> calls = new ArrayList<>();
+        when(mMockCallsManager.getCalls()).thenReturn(calls);
+        Call ringingCall = createForegroundCall();
+        calls.add(ringingCall);
+        when(ringingCall.getState()).thenReturn(CallState.RINGING);
+        when(ringingCall.isIncoming()).thenReturn(true);
+        when(ringingCall.isConference()).thenReturn(false);
+        when(ringingCall.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
+                Uri.parse("tel:555-0000")));
+
+        mBluetoothPhoneService.mBinder.listCurrentCalls();
+        verify(mMockBluetoothHeadset).clccResponse(1, 1, CALL_STATE_INCOMING, 0, false,
+                "5550000", PhoneNumberUtils.TOA_Unknown);
+        verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
+        verify(mMockBluetoothHeadset, times(2)).clccResponse(anyInt(),
+                anyInt(), anyInt(), anyInt(), anyBoolean(), nullable(String.class), anyInt());
+    }
+
+    @MediumTest
+    @Test
+    public void testCallClccCache() throws Exception {
+        ArrayList<Call> calls = new ArrayList<>();
+        when(mMockCallsManager.getCalls()).thenReturn(calls);
+        Call ringingCall = createForegroundCall();
+        calls.add(ringingCall);
+        when(ringingCall.getState()).thenReturn(CallState.RINGING);
+        when(ringingCall.isIncoming()).thenReturn(true);
+        when(ringingCall.isConference()).thenReturn(false);
+        when(ringingCall.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
+                Uri.parse("tel:5550000")));
+
+        mBluetoothPhoneService.mBinder.listCurrentCalls();
+        verify(mMockBluetoothHeadset).clccResponse(1, 1, CALL_STATE_INCOMING, 0, false,
+                "5550000", PhoneNumberUtils.TOA_Unknown);
+
+        // Test Caching of old call indicies in clcc
+        when(ringingCall.getState()).thenReturn(CallState.ACTIVE);
+        Call newHoldingCall = createHeldCall();
+        calls.add(0, newHoldingCall);
+        when(newHoldingCall.getState()).thenReturn(CallState.ON_HOLD);
+        when(newHoldingCall.isIncoming()).thenReturn(true);
+        when(newHoldingCall.isConference()).thenReturn(false);
+        when(newHoldingCall.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
+                Uri.parse("tel:555-0001")));
+
+        mBluetoothPhoneService.mBinder.listCurrentCalls();
+        verify(mMockBluetoothHeadset).clccResponse(1, 1, CALL_STATE_ACTIVE, 0, false,
+                "5550000", PhoneNumberUtils.TOA_Unknown);
+        verify(mMockBluetoothHeadset).clccResponse(2, 1, CALL_STATE_HELD, 0, false,
+                "5550001", PhoneNumberUtils.TOA_Unknown);
+        verify(mMockBluetoothHeadset, times(2)).clccResponse(0, 0, 0, 0, false, null, 0);
+    }
+
+    @MediumTest
+    @Test
+    public void testAlertingCallClccResponse() throws Exception {
+        ArrayList<Call> calls = new ArrayList<>();
+        when(mMockCallsManager.getCalls()).thenReturn(calls);
+        Call dialingCall = createForegroundCall();
+        calls.add(dialingCall);
+        when(dialingCall.getState()).thenReturn(CallState.DIALING);
+        when(dialingCall.isIncoming()).thenReturn(false);
+        when(dialingCall.isConference()).thenReturn(false);
+        when(dialingCall.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
+                Uri.parse("tel:555-0000")));
+
+        mBluetoothPhoneService.mBinder.listCurrentCalls();
+        verify(mMockBluetoothHeadset).clccResponse(1, 0, CALL_STATE_ALERTING, 0, false,
+                "5550000", PhoneNumberUtils.TOA_Unknown);
+        verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
+        verify(mMockBluetoothHeadset, times(2)).clccResponse(anyInt(),
+                anyInt(), anyInt(), anyInt(), anyBoolean(), nullable(String.class), anyInt());
+    }
+
+    @MediumTest
+    @Test
+    public void testHoldingCallClccResponse() throws Exception {
+        ArrayList<Call> calls = new ArrayList<>();
+        when(mMockCallsManager.getCalls()).thenReturn(calls);
+        Call dialingCall = createForegroundCall();
+        calls.add(dialingCall);
+        when(dialingCall.getState()).thenReturn(CallState.DIALING);
+        when(dialingCall.isIncoming()).thenReturn(false);
+        when(dialingCall.isConference()).thenReturn(false);
+        when(dialingCall.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
+                Uri.parse("tel:555-0000")));
+        Call holdingCall = createHeldCall();
+        calls.add(holdingCall);
+        when(holdingCall.getState()).thenReturn(CallState.ON_HOLD);
+        when(holdingCall.isIncoming()).thenReturn(true);
+        when(holdingCall.isConference()).thenReturn(false);
+        when(holdingCall.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
+                Uri.parse("tel:555-0001")));
+
+        mBluetoothPhoneService.mBinder.listCurrentCalls();
+        verify(mMockBluetoothHeadset).clccResponse(1, 0, CALL_STATE_ALERTING, 0, false,
+                "5550000", PhoneNumberUtils.TOA_Unknown);
+        verify(mMockBluetoothHeadset).clccResponse(2, 1, CALL_STATE_HELD, 0, false,
+                "5550001", PhoneNumberUtils.TOA_Unknown);
+        verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
+        verify(mMockBluetoothHeadset, times(3)).clccResponse(anyInt(),
+                anyInt(), anyInt(), anyInt(), anyBoolean(), nullable(String.class), anyInt());
+    }
+
+    @MediumTest
+    @Test
+    public void testListCurrentCallsImsConference() throws Exception {
+        ArrayList<Call> calls = new ArrayList<>();
+        Call parentCall = createActiveCall();
+        calls.add(parentCall);
+        addCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
+        when(parentCall.isConference()).thenReturn(true);
+        when(parentCall.getState()).thenReturn(CallState.ACTIVE);
+        when(parentCall.isIncoming()).thenReturn(true);
+        when(mMockCallsManager.getCalls()).thenReturn(calls);
+
+        mBluetoothPhoneService.mBinder.listCurrentCalls();
+
+        verify(mMockBluetoothHeadset).clccResponse(eq(1), eq(1), eq(CALL_STATE_ACTIVE), eq(0),
+                eq(true), (String) isNull(), eq(-1));
+        verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
+    }
+
+    @MediumTest
+    @Test
+    public void testListCurrentCallsHeldImsCepConference() throws Exception {
+        ArrayList<Call> calls = new ArrayList<>();
+        Call parentCall = createHeldCall();
+        Call childCall1 = createActiveCall();
+        Call childCall2 = createActiveCall();
+        calls.add(parentCall);
+        calls.add(childCall1);
+        calls.add(childCall2);
+        addCallCapability(parentCall, Connection.CAPABILITY_MANAGE_CONFERENCE);
+        when(childCall1.getParentCall()).thenReturn(parentCall);
+        when(childCall2.getParentCall()).thenReturn(parentCall);
+
+        when(parentCall.isConference()).thenReturn(true);
+        when(parentCall.getState()).thenReturn(CallState.ON_HOLD);
+        when(childCall1.getState()).thenReturn(CallState.ACTIVE);
+        when(childCall2.getState()).thenReturn(CallState.ACTIVE);
+
+        when(parentCall.isIncoming()).thenReturn(true);
+        when(mMockCallsManager.getCalls()).thenReturn(calls);
+
+        mBluetoothPhoneService.mBinder.listCurrentCalls();
+
+        verify(mMockBluetoothHeadset).clccResponse(eq(1), eq(0), eq(CALL_STATE_HELD), eq(0),
+                eq(true), (String) isNull(), eq(-1));
+        verify(mMockBluetoothHeadset).clccResponse(eq(2), eq(0), eq(CALL_STATE_HELD), eq(0),
+                eq(true), (String) isNull(), eq(-1));
+        verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
+    }
+
+    @MediumTest
+    @Test
+    public void testQueryPhoneState() throws Exception {
+        Call ringingCall = createRingingCall();
+        when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:5550000"));
+
+        mBluetoothPhoneService.mBinder.queryPhoneState();
+
+        verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_INCOMING),
+                eq("5550000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
+    }
+
+    @MediumTest
+    @Test
+    public void testCDMAConferenceQueryState() throws Exception {
+        Call parentConfCall = createActiveCall();
+        final Call confCall1 = mock(Call.class);
+        final Call confCall2 = mock(Call.class);
+        when(parentConfCall.getHandle()).thenReturn(Uri.parse("tel:555-0000"));
+        addCallCapability(parentConfCall, Connection.CAPABILITY_SWAP_CONFERENCE);
+        removeCallCapability(parentConfCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
+        when(parentConfCall.wasConferencePreviouslyMerged()).thenReturn(true);
+        when(parentConfCall.isConference()).thenReturn(true);
+        when(parentConfCall.getChildCalls()).thenReturn(new LinkedList<Call>() {{
+            add(confCall1);
+            add(confCall2);
+        }});
+
+        mBluetoothPhoneService.mBinder.queryPhoneState();
+        verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(0), eq(CALL_STATE_IDLE),
+                eq(""), eq(128), nullable(String.class));
+    }
+
+    @MediumTest
+    @Test
+    public void testProcessChldTypeReleaseHeldRinging() throws Exception {
+        Call ringingCall = createRingingCall();
+
+        boolean didProcess = mBluetoothPhoneService.mBinder.processChld(CHLD_TYPE_RELEASEHELD);
+
+        verify(mMockCallsManager).rejectCall(eq(ringingCall), eq(false), nullable(String.class));
+        assertEquals(didProcess, true);
+    }
+
+    @MediumTest
+    @Test
+    public void testProcessChldTypeReleaseHeldHold() throws Exception {
+        Call onHoldCall = createHeldCall();
+
+        boolean didProcess = mBluetoothPhoneService.mBinder.processChld(CHLD_TYPE_RELEASEHELD);
+
+        verify(mMockCallsManager).disconnectCall(eq(onHoldCall));
+        assertEquals(didProcess, true);
+    }
+
+    @MediumTest
+    @Test
+    public void testProcessChldReleaseActiveRinging() throws Exception {
+        Call activeCall = createActiveCall();
+        Call ringingCall = createRingingCall();
+
+        boolean didProcess = mBluetoothPhoneService.mBinder.processChld(
+                CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD);
+
+        verify(mMockCallsManager).disconnectCall(eq(activeCall));
+        verify(mMockCallsManager).answerCall(eq(ringingCall), any(int.class));
+        assertEquals(didProcess, true);
+    }
+
+    @MediumTest
+    @Test
+    public void testProcessChldReleaseActiveHold() throws Exception {
+        Call activeCall = createActiveCall();
+        Call heldCall = createHeldCall();
+
+        boolean didProcess = mBluetoothPhoneService.mBinder.processChld(
+                CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD);
+
+        verify(mMockCallsManager).disconnectCall(eq(activeCall));
+        // Call unhold will occur as part of CallsManager auto-unholding the background call on its
+        // own.
+        assertEquals(didProcess, true);
+    }
+
+    @MediumTest
+    @Test
+    public void testProcessChldHoldActiveRinging() throws Exception {
+        Call ringingCall = createRingingCall();
+
+        boolean didProcess = mBluetoothPhoneService.mBinder.processChld(
+                CHLD_TYPE_HOLDACTIVE_ACCEPTHELD);
+
+        verify(mMockCallsManager).answerCall(eq(ringingCall), any(int.class));
+        assertEquals(didProcess, true);
+    }
+
+    @MediumTest
+    @Test
+    public void testProcessChldHoldActiveUnhold() throws Exception {
+        Call heldCall = createHeldCall();
+
+        boolean didProcess = mBluetoothPhoneService.mBinder.processChld(
+                CHLD_TYPE_HOLDACTIVE_ACCEPTHELD);
+
+        verify(mMockCallsManager).unholdCall(eq(heldCall));
+        assertEquals(didProcess, true);
+    }
+
+    @MediumTest
+    @Test
+    public void testProcessChldHoldActiveHold() throws Exception {
+        Call activeCall = createActiveCall();
+        addCallCapability(activeCall, Connection.CAPABILITY_HOLD);
+
+        boolean didProcess = mBluetoothPhoneService.mBinder.processChld(
+                CHLD_TYPE_HOLDACTIVE_ACCEPTHELD);
+
+        verify(mMockCallsManager).holdCall(eq(activeCall));
+        assertEquals(didProcess, true);
+    }
+
+    @MediumTest
+    @Test
+    public void testProcessChldAddHeldToConfHolding() throws Exception {
+        Call activeCall = createActiveCall();
+        addCallCapability(activeCall, Connection.CAPABILITY_MERGE_CONFERENCE);
+
+        boolean didProcess = mBluetoothPhoneService.mBinder.processChld(CHLD_TYPE_ADDHELDTOCONF);
+
+        verify(activeCall).mergeConference();
+        assertEquals(didProcess, true);
+    }
+
+    @MediumTest
+    @Test
+    public void testProcessChldAddHeldToConf() throws Exception {
+        Call activeCall = createActiveCall();
+        removeCallCapability(activeCall, Connection.CAPABILITY_MERGE_CONFERENCE);
+        Call conferenceableCall = mock(Call.class);
+        ArrayList<Call> conferenceableCalls = new ArrayList<>();
+        conferenceableCalls.add(conferenceableCall);
+        when(activeCall.getConferenceableCalls()).thenReturn(conferenceableCalls);
+
+        boolean didProcess = mBluetoothPhoneService.mBinder.processChld(CHLD_TYPE_ADDHELDTOCONF);
+
+        verify(mMockCallsManager).conference(activeCall, conferenceableCall);
+        assertEquals(didProcess, true);
+    }
+
+    @MediumTest
+    @Test
+    public void testProcessChldHoldActiveSwapConference() throws Exception {
+        // Create an active CDMA Call with a call on hold and simulate a swapConference().
+        Call parentCall = createActiveCall();
+        final Call foregroundCall = mock(Call.class);
+        final Call heldCall = createHeldCall();
+        addCallCapability(parentCall, Connection.CAPABILITY_SWAP_CONFERENCE);
+        removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
+        when(parentCall.isConference()).thenReturn(true);
+        when(parentCall.wasConferencePreviouslyMerged()).thenReturn(false);
+        when(parentCall.getChildCalls()).thenReturn(new LinkedList<Call>() {{
+            add(foregroundCall);
+            add(heldCall);
+        }});
+
+        boolean didProcess = mBluetoothPhoneService.mBinder.processChld(
+                CHLD_TYPE_HOLDACTIVE_ACCEPTHELD);
+
+        verify(parentCall).swapConference();
+        verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(1), eq(CALL_STATE_IDLE), eq(""),
+                eq(128), nullable(String.class));
+        assertEquals(didProcess, true);
+    }
+
+    // Testing the CallsManager Listener Functionality on Bluetooth
+    @MediumTest
+    @Test
+    public void testOnCallAddedRinging() throws Exception {
+        Call ringingCall = createRingingCall();
+        when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:555000"));
+
+        mBluetoothPhoneService.mCallsManagerListener.onCallAdded(ringingCall);
+
+        verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_INCOMING),
+                eq("555000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
+    }
+
+    @MediumTest
+    @Test
+    public void testSilentRingingCallState() throws Exception {
+        Call ringingCall = createRingingCall();
+        when(ringingCall.isSilentRingingRequested()).thenReturn(true);
+        when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:555000"));
+
+        mBluetoothPhoneService.mCallsManagerListener.onCallAdded(ringingCall);
+
+        verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
+                anyString(), anyInt(), nullable(String.class));
+    }
+
+    @MediumTest
+    @Test
+    public void testOnCallAddedCdmaActiveHold() throws Exception {
+        // Call has been put into a CDMA "conference" with one call on hold.
+        Call parentCall = createActiveCall();
+        final Call foregroundCall = mock(Call.class);
+        final Call heldCall = createHeldCall();
+        addCallCapability(parentCall, Connection.CAPABILITY_MERGE_CONFERENCE);
+        removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
+        when(parentCall.isConference()).thenReturn(true);
+        when(parentCall.getChildCalls()).thenReturn(new LinkedList<Call>() {{
+            add(foregroundCall);
+            add(heldCall);
+        }});
+
+        mBluetoothPhoneService.mCallsManagerListener.onCallAdded(parentCall);
+
+        verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(1), eq(CALL_STATE_IDLE),
+                eq(""), eq(128), nullable(String.class));
+    }
+
+    @MediumTest
+    @Test
+    public void testOnCallRemoved() throws Exception {
+        Call activeCall = createActiveCall();
+        mBluetoothPhoneService.mCallsManagerListener.onCallAdded(activeCall);
+        doReturn(null).when(mMockCallsManager).getActiveCall();
+        mBluetoothPhoneService.mCallsManagerListener.onCallRemoved(activeCall);
+
+        verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_IDLE),
+                eq(""), eq(128), nullable(String.class));
+    }
+
+    @MediumTest
+    @Test
+    public void testOnCallStateChangedConnectingCall() throws Exception {
+        Call activeCall = mock(Call.class);
+        Call connectingCall = mock(Call.class);
+        when(connectingCall.getState()).thenReturn(CallState.CONNECTING);
+        ArrayList<Call> calls = new ArrayList<>();
+        calls.add(connectingCall);
+        calls.add(activeCall);
+        when(mMockCallsManager.getCalls()).thenReturn(calls);
+
+        mBluetoothPhoneService.mCallsManagerListener.onCallStateChanged(activeCall,
+                CallState.ACTIVE, CallState.ON_HOLD);
+
+        verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
+                anyString(), anyInt(), nullable(String.class));
+    }
+
+    @MediumTest
+    @Test
+    public void testOnCallAddedAudioProcessing() throws Exception {
+        Call call = mock(Call.class);
+        when(call.getState()).thenReturn(CallState.AUDIO_PROCESSING);
+        mBluetoothPhoneService.mCallsManagerListener.onCallAdded(call);
+
+        verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
+                anyString(), anyInt(), nullable(String.class));
+    }
+
+    @MediumTest
+    @Test
+    public void testOnCallStateChangedRingingToAudioProcessing() throws Exception {
+        Call ringingCall = createRingingCall();
+        when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:555000"));
+
+        mBluetoothPhoneService.mCallsManagerListener.onCallAdded(ringingCall);
+
+        verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_INCOMING),
+                eq("555000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
+
+        when(ringingCall.getState()).thenReturn(CallState.AUDIO_PROCESSING);
+        when(mMockCallsManager.getRingingOrSimulatedRingingCall()).thenReturn(null);
+
+        mBluetoothPhoneService.mCallsManagerListener.onCallStateChanged(ringingCall,
+                CallState.RINGING, CallState.AUDIO_PROCESSING);
+
+        verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_IDLE),
+                eq(""), eq(128), nullable(String.class));
+    }
+
+    @MediumTest
+    @Test
+    public void testOnCallStateChangedAudioProcessingToSimulatedRinging() throws Exception {
+        Call ringingCall = createRingingCall();
+        when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:555-0000"));
+
+        mBluetoothPhoneService.mCallsManagerListener.onCallStateChanged(ringingCall,
+                CallState.AUDIO_PROCESSING, CallState.SIMULATED_RINGING);
+
+        verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_INCOMING),
+                eq("555-0000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
+    }
+
+    @MediumTest
+    @Test
+    public void testOnCallStateChangedAudioProcessingToActive() throws Exception {
+        Call activeCall = createActiveCall();
+        when(activeCall.getState()).thenReturn(CallState.ACTIVE);
+
+        mBluetoothPhoneService.mCallsManagerListener.onCallStateChanged(activeCall,
+                CallState.AUDIO_PROCESSING, CallState.ACTIVE);
+
+        verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(0), eq(CALL_STATE_IDLE),
+                eq(""), eq(128), nullable(String.class));
+    }
+
+    @MediumTest
+    @Test
+    public void testOnCallStateChangedDialing() throws Exception {
+        Call activeCall = createActiveCall();
+
+        mBluetoothPhoneService.mCallsManagerListener.onCallStateChanged(activeCall,
+                CallState.CONNECTING, CallState.DIALING);
+
+        verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
+                anyString(), anyInt(), nullable(String.class));
+    }
+
+    @MediumTest
+    @Test
+    public void testOnCallStateChangedAlerting() throws Exception {
+        Call outgoingCall = createOutgoingCall();
+
+        mBluetoothPhoneService.mCallsManagerListener.onCallStateChanged(outgoingCall,
+                CallState.NEW, CallState.DIALING);
+
+        verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_DIALING),
+                eq(""), eq(128), nullable(String.class));
+        verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_ALERTING),
+                eq(""), eq(128), nullable(String.class));
+    }
+
+    @MediumTest
+    @Test
+    public void testOnCallStateChangedDisconnected() throws Exception {
+        Call disconnectedCall = createDisconnectedCall();
+        doReturn(true).when(mMockCallsManager).hasOnlyDisconnectedCalls();
+        mBluetoothPhoneService.mCallsManagerListener.onCallStateChanged(disconnectedCall,
+                CallState.DISCONNECTING, CallState.DISCONNECTED);
+        verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_DISCONNECTED),
+                eq(""), eq(128), nullable(String.class));
+
+        doReturn(false).when(mMockCallsManager).hasOnlyDisconnectedCalls();
+        mBluetoothPhoneService.mCallsManagerListener.onDisconnectedTonePlaying(true);
+        verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_DISCONNECTED),
+                eq(""), eq(128), nullable(String.class));
+
+        mBluetoothPhoneService.mCallsManagerListener.onDisconnectedTonePlaying(false);
+        verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_IDLE),
+                eq(""), eq(128), nullable(String.class));
+    }
+
+    @MediumTest
+    @Test
+    public void testOnCallStateChanged() throws Exception {
+        Call ringingCall = createRingingCall();
+        when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:555-0000"));
+        mBluetoothPhoneService.mCallsManagerListener.onCallAdded(ringingCall);
+
+        verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_INCOMING),
+                eq("555-0000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
+
+        //Switch to active
+        doReturn(null).when(mMockCallsManager).getRingingOrSimulatedRingingCall();
+        when(mMockCallsManager.getActiveCall()).thenReturn(ringingCall);
+
+        mBluetoothPhoneService.mCallsManagerListener.onCallStateChanged(ringingCall,
+                CallState.RINGING, CallState.ACTIVE);
+
+        verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(0), eq(CALL_STATE_IDLE),
+                eq(""), eq(128), nullable(String.class));
+    }
+
+    @MediumTest
+    @Test
+    public void testOnCallStateChangedGSMSwap() throws Exception {
+        Call heldCall = createHeldCall();
+        when(heldCall.getHandle()).thenReturn(Uri.parse("tel:555-0000"));
+        doReturn(2).when(mMockCallsManager).getNumHeldCalls();
+        mBluetoothPhoneService.mCallsManagerListener.onCallStateChanged(heldCall,
+                CallState.ACTIVE, CallState.ON_HOLD);
+
+        verify(mMockBluetoothHeadset, never()).phoneStateChanged(eq(0), eq(2), eq(CALL_STATE_HELD),
+                eq("5550000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
+    }
+
+    @MediumTest
+    @Test
+    public void testOnIsConferencedChanged() throws Exception {
+        // Start with two calls that are being merged into a CDMA conference call. The
+        // onIsConferencedChanged method will be called multiple times during the call. Make sure
+        // that the bluetooth phone state is updated properly.
+        Call parentCall = createActiveCall();
+        Call activeCall = mock(Call.class);
+        Call heldCall = createHeldCall();
+        when(activeCall.getParentCall()).thenReturn(parentCall);
+        when(heldCall.getParentCall()).thenReturn(parentCall);
+        ArrayList<Call> calls = new ArrayList<>();
+        calls.add(activeCall);
+        when(parentCall.getChildCalls()).thenReturn(calls);
+        when(parentCall.isConference()).thenReturn(true);
+        removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
+        addCallCapability(parentCall, Connection.CAPABILITY_SWAP_CONFERENCE);
+        when(parentCall.wasConferencePreviouslyMerged()).thenReturn(false);
+
+        // Be sure that onIsConferencedChanged rejects spurious changes during set up of
+        // CDMA "conference"
+        mBluetoothPhoneService.mCallsManagerListener.onIsConferencedChanged(activeCall);
+        verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
+                anyString(), anyInt(), nullable(String.class));
+        mBluetoothPhoneService.mCallsManagerListener.onIsConferencedChanged(heldCall);
+        verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
+                anyString(), anyInt(), nullable(String.class));
+        mBluetoothPhoneService.mCallsManagerListener.onIsConferencedChanged(parentCall);
+        verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
+                anyString(), anyInt(), nullable(String.class));
+
+        calls.add(heldCall);
+        mBluetoothPhoneService.mCallsManagerListener.onIsConferencedChanged(parentCall);
+        verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(1), eq(CALL_STATE_IDLE),
+                eq(""), eq(128), nullable(String.class));
+    }
+
+    @MediumTest
+    @Test
+    public void testBluetoothAdapterReceiver() throws Exception {
+        Call ringingCall = createRingingCall();
+        when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:5550000"));
+
+        Intent intent = new Intent();
+        intent.putExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_ON);
+        mBluetoothPhoneService.mBluetoothAdapterReceiver.onReceive(mContext, intent);
+
+        verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_INCOMING),
+                eq("5550000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
+    }
+
+    private void addCallCapability(Call call, int capability) {
+        when(call.can(capability)).thenReturn(true);
+    }
+
+    private void removeCallCapability(Call call, int capability) {
+        when(call.can(capability)).thenReturn(false);
+    }
+
+    private Call createActiveCall() {
+        Call call = mock(Call.class);
+        when(mMockCallsManager.getActiveCall()).thenReturn(call);
+        return call;
+    }
+
+    private Call createRingingCall() {
+        Call call = mock(Call.class);
+        when(mMockCallsManager.getRingingOrSimulatedRingingCall()).thenReturn(call);
+        return call;
+    }
+
+    private Call createHeldCall() {
+        Call call = mock(Call.class);
+        when(mMockCallsManager.getHeldCall()).thenReturn(call);
+        return call;
+    }
+
+    private Call createOutgoingCall() {
+        Call call = mock(Call.class);
+        when(mMockCallsManager.getOutgoingCall()).thenReturn(call);
+        return call;
+    }
+
+    private Call createDisconnectedCall() {
+        Call call = mock(Call.class);
+        when(mMockCallsManager.getFirstCallWithState(CallState.DISCONNECTED)).thenReturn(call);
+        return call;
+    }
+
+    private Call createForegroundCall() {
+        Call call = mock(Call.class);
+        when(mMockCallsManager.getForegroundCall()).thenReturn(call);
+        return call;
+    }
+
+    private static ComponentName makeQuickConnectionServiceComponentName() {
+        return new ComponentName("com.android.server.telecom.tests",
+                "com.android.server.telecom.tests.MockConnectionService");
+    }
+
+    private static PhoneAccountHandle makeQuickAccountHandle(String id) {
+        return new PhoneAccountHandle(makeQuickConnectionServiceComponentName(), id,
+                Binder.getCallingUserHandle());
+    }
+
+    private PhoneAccount.Builder makeQuickAccountBuilder(String id, int idx) {
+        return new PhoneAccount.Builder(makeQuickAccountHandle(id), "label" + idx);
+    }
+
+    private PhoneAccount makeQuickAccount(String id, int idx) {
+        return makeQuickAccountBuilder(id, idx)
+                .setAddress(Uri.parse(TEST_ACCOUNT_ADDRESS + idx))
+                .setSubscriptionAddress(Uri.parse("tel:555-000" + idx))
+                .setCapabilities(idx)
+                .setIcon(Icon.createWithResource(
+                        "com.android.server.telecom.tests", R.drawable.stat_sys_phone_call))
+                .setShortDescription("desc" + idx)
+                .setIsEnabled(true)
+                .build();
+    }
+}
diff --git a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
index 5c1cdc4..e8234fc 100644
--- a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
+++ b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
@@ -69,6 +69,7 @@
 
 import com.android.internal.telecom.IInCallAdapter;
 import com.android.server.telecom.AsyncRingtonePlayer;
+import com.android.server.telecom.BluetoothPhoneServiceImpl;
 import com.android.server.telecom.CallAudioManager;
 import com.android.server.telecom.CallAudioModeStateMachine;
 import com.android.server.telecom.CallAudioRouteStateMachine;
@@ -200,6 +201,7 @@
     @Mock HeadsetMediaButton mHeadsetMediaButton;
     @Mock ProximitySensorManager mProximitySensorManager;
     @Mock InCallWakeLockController mInCallWakeLockController;
+    @Mock BluetoothPhoneServiceImpl mBluetoothPhoneServiceImpl;
     @Mock AsyncRingtonePlayer mAsyncRingtonePlayer;
     @Mock IncomingCallNotifier mIncomingCallNotifier;
     @Mock ClockProxy mClockProxy;
@@ -483,6 +485,7 @@
                 proximitySensorManagerFactory,
                 inCallWakeLockControllerFactory,
                 () -> mAudioService,
+                (context, lock, callsManager, phoneAccountRegistrar) -> mBluetoothPhoneServiceImpl,
                 mConnServFMFactory,
                 mTimeoutsAdapter,
                 mAsyncRingtonePlayer,
