diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 3a11921..7b95d50 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -436,13 +436,6 @@
             </intent-filter>
         </activity>
 
-        <!-- bluetooth phone service -->
-        <service android:name="BluetoothPhoneService">
-            <intent-filter>
-                <action android:name="android.bluetooth.IBluetoothHeadsetPhone" />
-            </intent-filter>
-        </service>
-
         <!-- Broadcast Receiver that will process BOOT Complete and launch OTA -->
         <receiver android:name="OtaStartupReceiver" android:exported="false"
                 androidprv:primaryUserOnly="true">
diff --git a/src/com/android/phone/BluetoothPhoneService.java b/src/com/android/phone/BluetoothPhoneService.java
deleted file mode 100644
index 653d671..0000000
--- a/src/com/android/phone/BluetoothPhoneService.java
+++ /dev/null
@@ -1,982 +0,0 @@
-/*
- * Copyright (C) 2012 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.phone;
-
-import android.app.Service;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-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.os.AsyncResult;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.PowerManager.WakeLock;
-import android.os.SystemProperties;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.ServiceState;
-import android.util.Log;
-
-import com.android.internal.telephony.Call;
-import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.TelephonyIntents;
-import com.android.internal.telephony.CallManager;
-
-import com.android.phone.CallGatewayManager.RawGatewayInfo;
-
-import java.io.IOException;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Bluetooth headset manager for the Phone app.
- * @hide
- */
-public class BluetoothPhoneService extends Service {
-    private static final String TAG = "BluetoothPhoneService";
-    private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 1)
-            && (SystemProperties.getInt("ro.debuggable", 0) == 1);
-    private static final boolean VDBG = (PhoneGlobals.DBG_LEVEL >= 2);  // even more logging
-
-    private static final String MODIFY_PHONE_STATE = android.Manifest.permission.MODIFY_PHONE_STATE;
-
-    private BluetoothAdapter mAdapter;
-    private CallManager mCM;
-    private CallGatewayManager mCallGatewayManager;
-
-    private BluetoothHeadset mBluetoothHeadset;
-
-    private PowerManager mPowerManager;
-
-    private WakeLock mStartCallWakeLock;  // held while waiting for the intent to start call
-
-    private PhoneConstants.State mPhoneState = PhoneConstants.State.IDLE;
-    CdmaPhoneCallState.PhoneCallState mCdmaThreeWayCallState =
-                                            CdmaPhoneCallState.PhoneCallState.IDLE;
-
-    private Call.State mForegroundCallState;
-    private Call.State mRingingCallState;
-    private CallNumber mRingNumber;
-    // number of active calls
-    int mNumActive;
-    // number of background (held) calls
-    int mNumHeld;
-
-    long mBgndEarliestConnectionTime = 0;
-
-    // CDMA specific flag used in context with BT devices having display capabilities
-    // to show which Caller is active. This state might not be always true as in CDMA
-    // networks if a caller drops off no update is provided to the Phone.
-    // This flag is just used as a toggle to provide a update to the BT device to specify
-    // which caller is active.
-    private boolean mCdmaIsSecondCallActive = false;
-    private boolean mCdmaCallsSwapped = false;
-
-    private long[] mClccTimestamps; // Timestamps associated with each clcc index
-    private boolean[] mClccUsed;     // Is this clcc index in use
-
-    private static final int GSM_MAX_CONNECTIONS = 6;  // Max connections allowed by GSM
-    private static final int CDMA_MAX_CONNECTIONS = 2;  // Max connections allowed by CDMA
-    private IntentFilter mIntentFilter;
-
-    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
-            if (VDBG) Log.d(TAG, "Received BLUETOOTH_STATE_CHANGED_ACTION state:" + state);
-            if(state == BluetoothAdapter.STATE_ON) {
-                if (DBG) Log.d(TAG, "Bluetooth Turned ON, query phone state");
-                Message msg = Message.obtain(mHandler, QUERY_PHONE_STATE);
-                mHandler.sendMessage(msg);
-            }
-        }
-    };
-
-    @Override
-    public void onCreate() {
-        super.onCreate();
-        mCM = CallManager.getInstance();
-        mAdapter = BluetoothAdapter.getDefaultAdapter();
-        if (mAdapter == null) {
-            if (VDBG) Log.d(TAG, "mAdapter null");
-            return;
-        }
-        mCallGatewayManager = CallGatewayManager.getInstance();
-
-        mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
-        mStartCallWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
-                                                       TAG + ":StartCall");
-        mStartCallWakeLock.setReferenceCounted(false);
-
-        mAdapter.getProfileProxy(this, mProfileListener, BluetoothProfile.HEADSET);
-
-        mForegroundCallState = Call.State.IDLE;
-        mRingingCallState = Call.State.IDLE;
-        mNumActive = 0;
-        mNumHeld = 0;
-        mRingNumber = new CallNumber("", 0);;
-
-        handlePreciseCallStateChange(null);
-
-        if(VDBG) Log.d(TAG, "onCreate register for updates");
-        // register for updates
-        mCM.registerForPreciseCallStateChanged(mHandler, PRECISE_CALL_STATE_CHANGED, null);
-        mCM.registerForCallWaiting(mHandler, PHONE_CDMA_CALL_WAITING, null);
-        mCM.registerForDisconnect(mHandler, PHONE_ON_DISCONNECT, null);
-
-        mIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
-        this.registerReceiver(mReceiver, mIntentFilter);
-        // TODO(BT) registerForIncomingRing?
-        mClccTimestamps = new long[GSM_MAX_CONNECTIONS];
-        mClccUsed = new boolean[GSM_MAX_CONNECTIONS];
-        for (int i = 0; i < GSM_MAX_CONNECTIONS; i++) {
-            mClccUsed[i] = false;
-        }
-    }
-
-    @Override
-    public void onStart(Intent intent, int startId) {
-        if (mAdapter == null) {
-            Log.w(TAG, "Stopping Bluetooth BluetoothPhoneService Service: device does not have BT");
-            stopSelf();
-        }
-        if (VDBG) Log.d(TAG, "BluetoothPhoneService started");
-    }
-
-    @Override
-    public void onDestroy() {
-        super.onDestroy();
-        if (DBG) log("Stopping Bluetooth BluetoothPhoneService Service");
-        this.unregisterReceiver(mReceiver);
-    }
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        return mBinder;
-    }
-
-    private static final int PRECISE_CALL_STATE_CHANGED = 1;
-    private static final int PHONE_CDMA_CALL_WAITING = 2;
-    private static final int LIST_CURRENT_CALLS = 3;
-    private static final int QUERY_PHONE_STATE = 4;
-    private static final int CDMA_SWAP_SECOND_CALL_STATE = 5;
-    private static final int CDMA_SET_SECOND_CALL_STATE = 6;
-    private static final int PHONE_ON_DISCONNECT = 7;
-
-    private Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            if (VDBG) Log.d(TAG, "handleMessage: " + msg.what);
-            switch(msg.what) {
-                case PRECISE_CALL_STATE_CHANGED:
-                case PHONE_CDMA_CALL_WAITING:
-                case PHONE_ON_DISCONNECT:
-                    Connection connection = null;
-                    if (((AsyncResult) msg.obj).result instanceof Connection) {
-                        connection = (Connection) ((AsyncResult) msg.obj).result;
-                    }
-                    handlePreciseCallStateChange(connection);
-                    break;
-                case LIST_CURRENT_CALLS:
-                    handleListCurrentCalls();
-                    break;
-                case QUERY_PHONE_STATE:
-                    handleQueryPhoneState();
-                    break;
-                case CDMA_SWAP_SECOND_CALL_STATE:
-                    handleCdmaSwapSecondCallState();
-                    break;
-                case CDMA_SET_SECOND_CALL_STATE:
-                    handleCdmaSetSecondCallState((Boolean) msg.obj);
-                    break;
-            }
-        }
-    };
-
-    private void updateBtPhoneStateAfterRadioTechnologyChange() {
-        if(VDBG) Log.d(TAG, "updateBtPhoneStateAfterRadioTechnologyChange...");
-
-        //Unregister all events from the old obsolete phone
-        mCM.unregisterForPreciseCallStateChanged(mHandler);
-        mCM.unregisterForCallWaiting(mHandler);
-
-        //Register all events new to the new active phone
-        mCM.registerForPreciseCallStateChanged(mHandler,
-                                               PRECISE_CALL_STATE_CHANGED, null);
-        mCM.registerForCallWaiting(mHandler,
-                                   PHONE_CDMA_CALL_WAITING, null);
-    }
-
-    private void handlePreciseCallStateChange(Connection connection) {
-        // get foreground call state
-        int oldNumActive = mNumActive;
-        int oldNumHeld = mNumHeld;
-        Call.State oldRingingCallState = mRingingCallState;
-        Call.State oldForegroundCallState = mForegroundCallState;
-        CallNumber oldRingNumber = mRingNumber;
-
-        Call foregroundCall = mCM.getActiveFgCall();
-
-        if (VDBG)
-            Log.d(TAG, " handlePreciseCallStateChange: foreground: " + foregroundCall +
-                " background: " + mCM.getFirstActiveBgCall() + " ringing: " +
-                mCM.getFirstActiveRingingCall());
-
-        mForegroundCallState = foregroundCall.getState();
-        /* if in transition, do not update */
-        if (mForegroundCallState == Call.State.DISCONNECTING)
-        {
-            Log.d(TAG, "handlePreciseCallStateChange. Call disconnecting, wait before update");
-            return;
-        }
-        else
-            mNumActive = (mForegroundCallState == Call.State.ACTIVE) ? 1 : 0;
-
-        Call ringingCall = mCM.getFirstActiveRingingCall();
-        mRingingCallState = ringingCall.getState();
-        mRingNumber = getCallNumber(connection, ringingCall);
-
-        if (mCM.getDefaultPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
-            mNumHeld = getNumHeldCdma();
-            PhoneGlobals app = PhoneGlobals.getInstance();
-            if (app.cdmaPhoneCallState != null) {
-                CdmaPhoneCallState.PhoneCallState currCdmaThreeWayCallState =
-                        app.cdmaPhoneCallState.getCurrentCallState();
-                CdmaPhoneCallState.PhoneCallState prevCdmaThreeWayCallState =
-                    app.cdmaPhoneCallState.getPreviousCallState();
-
-                log("CDMA call state: " + currCdmaThreeWayCallState + " prev state:" +
-                    prevCdmaThreeWayCallState);
-
-                if ((mBluetoothHeadset != null) &&
-                    (mCdmaThreeWayCallState != currCdmaThreeWayCallState)) {
-                    // In CDMA, the network does not provide any feedback
-                    // to the phone when the 2nd MO call goes through the
-                    // stages of DIALING > ALERTING -> ACTIVE we fake the
-                    // sequence
-                    log("CDMA 3way call state change. mNumActive: " + mNumActive +
-                        " mNumHeld: " + mNumHeld + " IsThreeWayCallOrigStateDialing: " +
-                        app.cdmaPhoneCallState.IsThreeWayCallOrigStateDialing());
-                    if ((currCdmaThreeWayCallState ==
-                            CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE)
-                                && app.cdmaPhoneCallState.IsThreeWayCallOrigStateDialing()) {
-                        // Mimic dialing, put the call on hold, alerting
-                        mBluetoothHeadset.phoneStateChanged(0, mNumHeld,
-                            convertCallState(Call.State.IDLE, Call.State.DIALING),
-                            mRingNumber.mNumber, mRingNumber.mType);
-
-                        mBluetoothHeadset.phoneStateChanged(0, mNumHeld,
-                            convertCallState(Call.State.IDLE, Call.State.ALERTING),
-                            mRingNumber.mNumber, mRingNumber.mType);
-
-                    }
-
-                    // In CDMA, the network does not provide any feedback to
-                    // the phone when a user merges a 3way call or swaps
-                    // between two calls we need to send a CIEV response
-                    // indicating that a call state got changed which should
-                    // trigger a CLCC update request from the BT client.
-                    if (currCdmaThreeWayCallState ==
-                            CdmaPhoneCallState.PhoneCallState.CONF_CALL &&
-                            prevCdmaThreeWayCallState ==
-                              CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
-                        log("CDMA 3way conf call. mNumActive: " + mNumActive +
-                            " mNumHeld: " + mNumHeld);
-                        mBluetoothHeadset.phoneStateChanged(mNumActive, mNumHeld,
-                            convertCallState(Call.State.IDLE, mForegroundCallState),
-                            mRingNumber.mNumber, mRingNumber.mType);
-                    }
-                }
-                mCdmaThreeWayCallState = currCdmaThreeWayCallState;
-            }
-        } else {
-            mNumHeld = getNumHeldUmts();
-        }
-
-        boolean callsSwitched = false;
-        if (mCM.getDefaultPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA &&
-            mCdmaThreeWayCallState == CdmaPhoneCallState.PhoneCallState.CONF_CALL) {
-            callsSwitched = mCdmaCallsSwapped;
-        } else {
-            Call backgroundCall = mCM.getFirstActiveBgCall();
-            callsSwitched =
-                (mNumHeld == 1 && ! (backgroundCall.getEarliestConnectTime() ==
-                    mBgndEarliestConnectionTime));
-            mBgndEarliestConnectionTime = backgroundCall.getEarliestConnectTime();
-        }
-
-        if (mNumActive != oldNumActive || mNumHeld != oldNumHeld ||
-            mRingingCallState != oldRingingCallState ||
-            mForegroundCallState != oldForegroundCallState ||
-            !mRingNumber.equalTo(oldRingNumber) ||
-            callsSwitched) {
-            if (mBluetoothHeadset != null) {
-                mBluetoothHeadset.phoneStateChanged(mNumActive, mNumHeld,
-                    convertCallState(mRingingCallState, mForegroundCallState),
-                    mRingNumber.mNumber, mRingNumber.mType);
-            }
-        }
-    }
-
-    private void handleListCurrentCalls() {
-        Phone phone = mCM.getDefaultPhone();
-        int phoneType = phone.getPhoneType();
-
-        // TODO(BT) handle virtual call
-
-        if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-            listCurrentCallsCdma();
-        } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
-            listCurrentCallsGsm();
-        } else {
-            Log.e(TAG, "Unexpected phone type: " + phoneType);
-        }
-        // end the result
-        // when index is 0, other parameter does not matter
-        if (mBluetoothHeadset != null) {
-            mBluetoothHeadset.clccResponse(0, 0, 0, 0, false, "", 0);
-        }
-    }
-
-    private void handleQueryPhoneState() {
-        if (mBluetoothHeadset != null) {
-            mBluetoothHeadset.phoneStateChanged(mNumActive, mNumHeld,
-                convertCallState(mRingingCallState, mForegroundCallState),
-                mRingNumber.mNumber, mRingNumber.mType);
-        }
-    }
-
-    private int getNumHeldUmts() {
-        int countHeld = 0;
-        List<Call> heldCalls = mCM.getBackgroundCalls();
-
-        for (Call call : heldCalls) {
-            if (call.getState() == Call.State.HOLDING) {
-                countHeld++;
-            }
-        }
-        return countHeld;
-    }
-
-    private int getNumHeldCdma() {
-        int numHeld = 0;
-        PhoneGlobals app = PhoneGlobals.getInstance();
-        if (app.cdmaPhoneCallState != null) {
-            CdmaPhoneCallState.PhoneCallState curr3WayCallState =
-                app.cdmaPhoneCallState.getCurrentCallState();
-            CdmaPhoneCallState.PhoneCallState prev3WayCallState =
-                app.cdmaPhoneCallState.getPreviousCallState();
-
-            log("CDMA call state: " + curr3WayCallState + " prev state:" +
-                prev3WayCallState);
-            if (curr3WayCallState == CdmaPhoneCallState.PhoneCallState.CONF_CALL) {
-                if (prev3WayCallState == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
-                    numHeld = 0; //0: no calls held, as now *both* the caller are active
-                } else {
-                    numHeld = 1; //1: held call and active call, as on answering a
-                    // Call Waiting, one of the caller *is* put on hold
-                }
-            } else if (curr3WayCallState == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
-                numHeld = 1; //1: held call and active call, as on make a 3 Way Call
-                // the first caller *is* put on hold
-            } else {
-                numHeld = 0; //0: no calls held as this is a SINGLE_ACTIVE call
-            }
-        }
-        return numHeld;
-    }
-
-    private CallNumber getCallNumber(Connection connection, Call call) {
-        String number = null;
-        int type = 128;
-        // find phone number and type
-        if (connection == null) {
-            connection = call.getEarliestConnection();
-            if (connection == null) {
-                Log.e(TAG, "Could not get a handle on Connection object for the call");
-            }
-        }
-        if (connection != null) {
-            number = connection.getAddress();
-            if (number != null) {
-                type = PhoneNumberUtils.toaFromString(number);
-            }
-        }
-        if (number == null) {
-            number = "";
-        }
-        return new CallNumber(number, type);
-    }
-
-    private class CallNumber
-    {
-        private String mNumber = null;
-        private int mType = 0;
-
-        private CallNumber(String number, int type) {
-            mNumber = number;
-            mType = type;
-        }
-
-        private boolean equalTo(CallNumber callNumber)
-        {
-            if (mType != callNumber.mType) return false;
-
-            if (mNumber != null && mNumber.compareTo(callNumber.mNumber) == 0) {
-                return true;
-            }
-            return false;
-        }
-    }
-
-    private BluetoothProfile.ServiceListener mProfileListener =
-            new BluetoothProfile.ServiceListener() {
-        public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            mBluetoothHeadset = (BluetoothHeadset) proxy;
-        }
-        public void onServiceDisconnected(int profile) {
-            mBluetoothHeadset = null;
-        }
-    };
-
-    private void listCurrentCallsGsm() {
-        // Collect all known connections
-        // clccConnections isindexed by CLCC index
-        Connection[] clccConnections = new Connection[GSM_MAX_CONNECTIONS];
-        LinkedList<Connection> newConnections = new LinkedList<Connection>();
-        LinkedList<Connection> connections = new LinkedList<Connection>();
-
-        Call foregroundCall = mCM.getActiveFgCall();
-        Call backgroundCall = mCM.getFirstActiveBgCall();
-        Call ringingCall = mCM.getFirstActiveRingingCall();
-
-        if (ringingCall.getState().isAlive()) {
-            connections.addAll(ringingCall.getConnections());
-        }
-        if (foregroundCall.getState().isAlive()) {
-            connections.addAll(foregroundCall.getConnections());
-        }
-        if (backgroundCall.getState().isAlive()) {
-            connections.addAll(backgroundCall.getConnections());
-        }
-
-        // Mark connections that we already known about
-        boolean clccUsed[] = new boolean[GSM_MAX_CONNECTIONS];
-        for (int i = 0; i < GSM_MAX_CONNECTIONS; i++) {
-            clccUsed[i] = mClccUsed[i];
-            mClccUsed[i] = false;
-        }
-        for (Connection c : connections) {
-            boolean found = false;
-            long timestamp = c.getCreateTime();
-            for (int i = 0; i < GSM_MAX_CONNECTIONS; i++) {
-                if (clccUsed[i] && timestamp == mClccTimestamps[i]) {
-                    mClccUsed[i] = true;
-                    found = true;
-                    clccConnections[i] = c;
-                    break;
-                }
-            }
-            if (!found) {
-                newConnections.add(c);
-            }
-        }
-
-        // Find a CLCC index for new connections
-        while (!newConnections.isEmpty()) {
-            // Find lowest empty index
-            int i = 0;
-            while (mClccUsed[i]) i++;
-            // Find earliest connection
-            long earliestTimestamp = newConnections.get(0).getCreateTime();
-            Connection earliestConnection = newConnections.get(0);
-            for (int j = 0; j < newConnections.size(); j++) {
-                long timestamp = newConnections.get(j).getCreateTime();
-                if (timestamp < earliestTimestamp) {
-                    earliestTimestamp = timestamp;
-                    earliestConnection = newConnections.get(j);
-                }
-            }
-
-            // update
-            mClccUsed[i] = true;
-            mClccTimestamps[i] = earliestTimestamp;
-            clccConnections[i] = earliestConnection;
-            newConnections.remove(earliestConnection);
-        }
-
-        // Send CLCC response to Bluetooth headset service
-        for (int i = 0; i < clccConnections.length; i++) {
-            if (mClccUsed[i]) {
-                sendClccResponseGsm(i, clccConnections[i]);
-            }
-        }
-    }
-
-    /** Convert a Connection object into a single +CLCC result */
-    private void sendClccResponseGsm(int index, Connection connection) {
-        int state = convertCallState(connection.getState());
-        boolean mpty = false;
-        Call call = connection.getCall();
-        if (call != null) {
-            mpty = call.isMultiparty();
-        }
-
-        boolean isIncoming = connection.isIncoming();
-
-        // For GV outgoing calls send the contact phone #, not the gateway #.
-        String number = connection.getAddress();
-        if (!isIncoming) {
-            RawGatewayInfo rawInfo = mCallGatewayManager.getGatewayInfo(connection);
-            if (!rawInfo.isEmpty()) {
-                number = rawInfo.trueNumber;
-            }
-        }
-        int type = -1;
-        if (number != null) {
-            type = PhoneNumberUtils.toaFromString(number);
-        } else {
-            number = "";
-        }
-
-        if (mBluetoothHeadset != null) {
-            mBluetoothHeadset.clccResponse(index + 1, isIncoming ? 1 : 0,
-                    state, 0, mpty, number, type);
-        }
-    }
-
-    /** Build the +CLCC result for CDMA
-     *  The complexity arises from the fact that we need to maintain the same
-     *  CLCC index even as a call moves between states. */
-    private synchronized void listCurrentCallsCdma() {
-        // In CDMA at one time a user can have only two live/active connections
-        Connection[] clccConnections = new Connection[CDMA_MAX_CONNECTIONS];// indexed by CLCC index
-        Call foregroundCall = mCM.getActiveFgCall();
-        Call ringingCall = mCM.getFirstActiveRingingCall();
-
-        Call.State ringingCallState = ringingCall.getState();
-        // If the Ringing Call state is INCOMING, that means this is the very first call
-        // hence there should not be any Foreground Call
-        if (ringingCallState == Call.State.INCOMING) {
-            if (VDBG) log("Filling clccConnections[0] for INCOMING state");
-            clccConnections[0] = ringingCall.getLatestConnection();
-        } else if (foregroundCall.getState().isAlive()) {
-            // Getting Foreground Call connection based on Call state
-            if (ringingCall.isRinging()) {
-                if (VDBG) log("Filling clccConnections[0] & [1] for CALL WAITING state");
-                clccConnections[0] = foregroundCall.getEarliestConnection();
-                clccConnections[1] = ringingCall.getLatestConnection();
-            } else {
-                if (foregroundCall.getConnections().size() <= 1) {
-                    // Single call scenario
-                    if (VDBG) {
-                        log("Filling clccConnections[0] with ForgroundCall latest connection");
-                    }
-                    clccConnections[0] = foregroundCall.getLatestConnection();
-                } else {
-                    // Multiple Call scenario. This would be true for both
-                    // CONF_CALL and THRWAY_ACTIVE state
-                    if (VDBG) {
-                        log("Filling clccConnections[0] & [1] with ForgroundCall connections");
-                    }
-                    clccConnections[0] = foregroundCall.getEarliestConnection();
-                    clccConnections[1] = foregroundCall.getLatestConnection();
-                }
-            }
-        }
-
-        // Update the mCdmaIsSecondCallActive flag based on the Phone call state
-        if (PhoneGlobals.getInstance().cdmaPhoneCallState.getCurrentCallState()
-                == CdmaPhoneCallState.PhoneCallState.SINGLE_ACTIVE) {
-            Message msg = mHandler.obtainMessage(CDMA_SET_SECOND_CALL_STATE, false);
-            mHandler.sendMessage(msg);
-        } else if (PhoneGlobals.getInstance().cdmaPhoneCallState.getCurrentCallState()
-                == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
-            Message msg = mHandler.obtainMessage(CDMA_SET_SECOND_CALL_STATE, true);
-            mHandler.sendMessage(msg);
-        }
-
-        // send CLCC result
-        for (int i = 0; (i < clccConnections.length) && (clccConnections[i] != null); i++) {
-            sendClccResponseCdma(i, clccConnections[i]);
-        }
-    }
-
-    /** Send ClCC results for a Connection object for CDMA phone */
-    private void sendClccResponseCdma(int index, Connection connection) {
-        int state;
-        PhoneGlobals app = PhoneGlobals.getInstance();
-        CdmaPhoneCallState.PhoneCallState currCdmaCallState =
-                app.cdmaPhoneCallState.getCurrentCallState();
-        CdmaPhoneCallState.PhoneCallState prevCdmaCallState =
-                app.cdmaPhoneCallState.getPreviousCallState();
-
-        if ((prevCdmaCallState == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE)
-                && (currCdmaCallState == CdmaPhoneCallState.PhoneCallState.CONF_CALL)) {
-            // If the current state is reached after merging two calls
-            // we set the state of all the connections as ACTIVE
-            state = CALL_STATE_ACTIVE;
-        } else {
-            Call.State callState = connection.getState();
-            switch (callState) {
-            case ACTIVE:
-                // For CDMA since both the connections are set as active by FW after accepting
-                // a Call waiting or making a 3 way call, we need to set the state specifically
-                // to ACTIVE/HOLDING based on the mCdmaIsSecondCallActive flag. This way the
-                // CLCC result will allow BT devices to enable the swap or merge options
-                if (index == 0) { // For the 1st active connection
-                    state = mCdmaIsSecondCallActive ? CALL_STATE_HELD : CALL_STATE_ACTIVE;
-                } else { // for the 2nd active connection
-                    state = mCdmaIsSecondCallActive ? CALL_STATE_ACTIVE : CALL_STATE_HELD;
-                }
-                break;
-            case HOLDING:
-                state = CALL_STATE_HELD;
-                break;
-            case DIALING:
-                state = CALL_STATE_DIALING;
-                break;
-            case ALERTING:
-                state = CALL_STATE_ALERTING;
-                break;
-            case INCOMING:
-                state = CALL_STATE_INCOMING;
-                break;
-            case WAITING:
-                state = CALL_STATE_WAITING;
-                break;
-            default:
-                Log.e(TAG, "bad call state: " + callState);
-                return;
-            }
-        }
-
-        boolean mpty = false;
-        if (currCdmaCallState == CdmaPhoneCallState.PhoneCallState.CONF_CALL) {
-            if (prevCdmaCallState == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
-                // If the current state is reached after merging two calls
-                // we set the multiparty call true.
-                mpty = true;
-            } // else
-                // CALL_CONF state is not from merging two calls, but from
-                // accepting the second call. In this case first will be on
-                // hold in most cases but in some cases its already merged.
-                // However, we will follow the common case and the test case
-                // as per Bluetooth SIG PTS
-        }
-
-        boolean isIncoming = connection.isIncoming();
-
-        // For GV outgoing calls send the contact phone #, not the gateway #.
-        String number = connection.getAddress();
-        if (!isIncoming) {
-            RawGatewayInfo rawInfo = mCallGatewayManager.getGatewayInfo(connection);
-            if (!rawInfo.isEmpty()) {
-                number = rawInfo.trueNumber;
-            }
-        }
-        int type = -1;
-        if (number != null) {
-            type = PhoneNumberUtils.toaFromString(number);
-        } else {
-            number = "";
-        }
-
-        if (mBluetoothHeadset != null) {
-            mBluetoothHeadset.clccResponse(index + 1, isIncoming ? 1 : 0,
-                    state, 0, mpty, number, type);
-        }
-    }
-
-    private void handleCdmaSwapSecondCallState() {
-        if (VDBG) log("cdmaSwapSecondCallState: Toggling mCdmaIsSecondCallActive");
-        mCdmaIsSecondCallActive = !mCdmaIsSecondCallActive;
-        mCdmaCallsSwapped = true;
-    }
-
-    private void handleCdmaSetSecondCallState(boolean state) {
-        if (VDBG) log("cdmaSetSecondCallState: Setting mCdmaIsSecondCallActive to " + state);
-        mCdmaIsSecondCallActive = state;
-
-        if (!mCdmaIsSecondCallActive) {
-            mCdmaCallsSwapped = false;
-        }
-    }
-
-    private final IBluetoothHeadsetPhone.Stub mBinder = new IBluetoothHeadsetPhone.Stub() {
-        public boolean answerCall() {
-            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
-            return PhoneUtils.answerCall(mCM.getFirstActiveRingingCall());
-        }
-
-        public boolean hangupCall() {
-            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
-            if (mCM.hasActiveFgCall()) {
-                return PhoneUtils.hangupActiveCall(mCM.getActiveFgCall());
-            } else if (mCM.hasActiveRingingCall()) {
-                return PhoneUtils.hangupRingingCall(mCM.getFirstActiveRingingCall());
-            } else if (mCM.hasActiveBgCall()) {
-                return PhoneUtils.hangupHoldingCall(mCM.getFirstActiveBgCall());
-            }
-            // TODO(BT) handle virtual voice call
-            return false;
-        }
-
-        public boolean sendDtmf(int dtmf) {
-            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
-            return mCM.sendDtmf((char) dtmf);
-        }
-
-        public boolean processChld(int chld) {
-            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
-            Phone phone = mCM.getDefaultPhone();
-            int phoneType = phone.getPhoneType();
-            Call ringingCall = mCM.getFirstActiveRingingCall();
-            Call backgroundCall = mCM.getFirstActiveBgCall();
-
-            if (chld == CHLD_TYPE_RELEASEHELD) {
-                if (ringingCall.isRinging()) {
-                    return PhoneUtils.hangupRingingCall(ringingCall);
-                } else {
-                    return PhoneUtils.hangupHoldingCall(backgroundCall);
-                }
-            } else if (chld == CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD) {
-                if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-                    if (ringingCall.isRinging()) {
-                        // Hangup the active call and then answer call waiting call.
-                        if (VDBG) log("CHLD:1 Callwaiting Answer call");
-                        PhoneUtils.hangupRingingAndActive(phone);
-                    } else {
-                        // If there is no Call waiting then just hangup
-                        // the active call. In CDMA this mean that the complete
-                        // call session would be ended
-                        if (VDBG) log("CHLD:1 Hangup Call");
-                        PhoneUtils.hangup(PhoneGlobals.getInstance().mCM);
-                    }
-                    return true;
-                } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
-                    if (ringingCall.isRinging() && (mNumHeld > 0 && mNumActive == 0)) {
-                       if (VDBG) log("CHLD:1 Answer the Call");
-                       return PhoneUtils.answerCall(ringingCall);
-                    }
-                    // Hangup active call, answer held call
-                    return PhoneUtils.answerAndEndActive(PhoneGlobals.getInstance().mCM, ringingCall);
-                } else {
-                    Log.e(TAG, "bad phone type: " + phoneType);
-                    return false;
-                }
-            } else if (chld == CHLD_TYPE_HOLDACTIVE_ACCEPTHELD) {
-                if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-                    // For CDMA, the way we switch to a new incoming call is by
-                    // calling PhoneUtils.answerCall(). switchAndHoldActive() won't
-                    // properly update the call state within telephony.
-                    // If the Phone state is already in CONF_CALL then we simply send
-                    // a flash cmd by calling switchHoldingAndActive()
-                    if (ringingCall.isRinging()) {
-                        if (VDBG) log("CHLD:2 Callwaiting Answer call");
-                        PhoneUtils.answerCall(ringingCall);
-                        // Setting the second callers state flag to TRUE (i.e. active)
-                        cdmaSetSecondCallState(true);
-                        return true;
-                    } else if (PhoneGlobals.getInstance().cdmaPhoneCallState
-                               .getCurrentCallState()
-                               == CdmaPhoneCallState.PhoneCallState.CONF_CALL) {
-                        if (VDBG) log("CHLD:2 Swap Calls");
-                        PhoneUtils.switchHoldingAndActive(backgroundCall);
-                        // Toggle the second callers active state flag
-                        cdmaSwapSecondCallState();
-                        return true;
-                    }
-                    Log.e(TAG, "CDMA fail to do hold active and accept held");
-                    return false;
-                } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
-                    if (ringingCall.isRinging() && (mNumHeld > 0 && mNumActive == 0)) {
-                       PhoneUtils.answerCall(ringingCall);
-                    } else {
-                       PhoneUtils.switchHoldingAndActive(backgroundCall);
-                    }
-                    return true;
-                } else {
-                    Log.e(TAG, "Unexpected phone type: " + phoneType);
-                    return false;
-                }
-            } else if (chld == CHLD_TYPE_ADDHELDTOCONF) {
-                if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
-                    CdmaPhoneCallState.PhoneCallState state =
-                        PhoneGlobals.getInstance().cdmaPhoneCallState.getCurrentCallState();
-                    // For CDMA, we need to check if the call is in THRWAY_ACTIVE state
-                    if (state == CdmaPhoneCallState.PhoneCallState.THRWAY_ACTIVE) {
-                        if (VDBG) log("CHLD:3 Merge Calls");
-                        PhoneUtils.mergeCalls();
-                        return true;
-                    }   else if (state == CdmaPhoneCallState.PhoneCallState.CONF_CALL) {
-                        // State is CONF_CALL already and we are getting a merge call
-                        // This can happen when CONF_CALL was entered from a Call Waiting
-                        // TODO(BT)
-                        return false;
-                    }
-                    Log.e(TAG, "GSG no call to add conference");
-                    return false;
-                } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
-                    if (mCM.hasActiveFgCall() && mCM.hasActiveBgCall()) {
-                        PhoneUtils.mergeCalls();
-                        return true;
-                    } else {
-                        Log.e(TAG, "GSG no call to merge");
-                        return false;
-                    }
-                } else {
-                    Log.e(TAG, "Unexpected phone type: " + phoneType);
-                    return false;
-                }
-            } else {
-                Log.e(TAG, "bad CHLD value: " + chld);
-                return false;
-            }
-        }
-
-        public String getNetworkOperator() {
-            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
-            return mCM.getDefaultPhone().getServiceState().getOperatorAlphaLong();
-        }
-
-        public String getSubscriberNumber() {
-            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
-            return mCM.getDefaultPhone().getLine1Number();
-        }
-
-        public boolean listCurrentCalls() {
-            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
-            Message msg = Message.obtain(mHandler, LIST_CURRENT_CALLS);
-            mHandler.sendMessage(msg);
-            return true;
-        }
-
-        public boolean queryPhoneState() {
-            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
-            Message msg = Message.obtain(mHandler, QUERY_PHONE_STATE);
-            mHandler.sendMessage(msg);
-            return true;
-        }
-
-        public void updateBtHandsfreeAfterRadioTechnologyChange() {
-            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
-            if (VDBG) Log.d(TAG, "updateBtHandsfreeAfterRadioTechnologyChange...");
-            updateBtPhoneStateAfterRadioTechnologyChange();
-        }
-
-        public void cdmaSwapSecondCallState() {
-            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
-            Message msg = Message.obtain(mHandler, CDMA_SWAP_SECOND_CALL_STATE);
-            mHandler.sendMessage(msg);
-        }
-
-        public void cdmaSetSecondCallState(boolean state) {
-            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, null);
-            Message msg = mHandler.obtainMessage(CDMA_SET_SECOND_CALL_STATE, state);
-            mHandler.sendMessage(msg);
-        }
-    };
-
-    // match up with bthf_call_state_t of bt_hf.h
-    final static int CALL_STATE_ACTIVE = 0;
-    final static int CALL_STATE_HELD = 1;
-    final static int CALL_STATE_DIALING = 2;
-    final static int CALL_STATE_ALERTING = 3;
-    final static int CALL_STATE_INCOMING = 4;
-    final static int CALL_STATE_WAITING = 5;
-    final static int CALL_STATE_IDLE = 6;
-
-    // match up with bthf_chld_type_t of bt_hf.h
-    final static int CHLD_TYPE_RELEASEHELD = 0;
-    final static int CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD = 1;
-    final static int CHLD_TYPE_HOLDACTIVE_ACCEPTHELD = 2;
-    final static int CHLD_TYPE_ADDHELDTOCONF = 3;
-
-     /* Convert telephony phone call state into hf hal call state */
-    static int convertCallState(Call.State ringingState, Call.State foregroundState) {
-        int retval = CALL_STATE_IDLE;
-
-        if ((ringingState == Call.State.INCOMING) ||
-            (ringingState == Call.State.WAITING) )
-            retval = CALL_STATE_INCOMING;
-        else if (foregroundState == Call.State.DIALING)
-            retval = CALL_STATE_DIALING;
-        else if (foregroundState == Call.State.ALERTING)
-            retval = CALL_STATE_ALERTING;
-        else
-            retval = CALL_STATE_IDLE;
-
-        if (VDBG) {
-            Log.v(TAG, "Call state Converted2: " + ringingState + "/" + foregroundState + " -> " +
-                    retval);
-        }
-        return retval;
-    }
-
-    static int convertCallState(Call.State callState) {
-        int retval = CALL_STATE_IDLE;
-
-        switch (callState) {
-        case IDLE:
-        case DISCONNECTED:
-        case DISCONNECTING:
-            retval = CALL_STATE_IDLE;
-            break;
-        case ACTIVE:
-            retval = CALL_STATE_ACTIVE;
-            break;
-        case HOLDING:
-            retval = CALL_STATE_HELD;
-            break;
-        case DIALING:
-            retval = CALL_STATE_DIALING;
-            break;
-        case ALERTING:
-            retval = CALL_STATE_ALERTING;
-            break;
-        case INCOMING:
-            retval = CALL_STATE_INCOMING;
-            break;
-        case WAITING:
-            retval = CALL_STATE_WAITING;
-            break;
-        default:
-            Log.e(TAG, "bad call state: " + callState);
-            retval = CALL_STATE_IDLE;
-            break;
-        }
-
-        if (VDBG) {
-            Log.v(TAG, "Call state Converted2: " + callState + " -> " + retval);
-        }
-
-        return retval;
-    }
-
-    private static void log(String msg) {
-        Log.d(TAG, msg);
-    }
-}
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index b2e1332..4dd8ee2 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -143,7 +143,6 @@
     private BluetoothManager bluetoothManager;
     private CallGatewayManager callGatewayManager;
     private CallStateMonitor callStateMonitor;
-    private IBluetoothHeadsetPhone mBluetoothPhone;
 
     static int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
     static boolean sVoiceCapable = true;
@@ -350,17 +349,6 @@
                 cdmaPhoneCallState.CdmaPhoneCallStateInit();
             }
 
-            if (BluetoothAdapter.getDefaultAdapter() != null) {
-                // Start BluetoothPhoneService even if device is not voice capable.
-                // The device can still support VOIP.
-                startService(new Intent(this, BluetoothPhoneService.class));
-                bindService(new Intent(this, BluetoothPhoneService.class),
-                            mBluetoothPhoneConnection, 0);
-            } else {
-                // Device is not bluetooth capable
-                mBluetoothPhone = null;
-            }
-
             // before registering for phone state changes
             mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
             mWakeLock = mPowerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, LOG_TAG);
@@ -499,10 +487,6 @@
         return getInstance().phone;
     }
 
-    IBluetoothHeadsetPhone getBluetoothPhoneService() {
-        return mBluetoothPhone;
-    }
-
     /* package */ BluetoothManager getBluetoothManager() {
         return bluetoothManager;
     }
@@ -797,14 +781,6 @@
         notifier.updateCallNotifierRegistrationsAfterRadioTechnologyChange();
         callStateMonitor.updateAfterRadioTechnologyChange();
 
-        if (mBluetoothPhone != null) {
-            try {
-                mBluetoothPhone.updateBtHandsfreeAfterRadioTechnologyChange();
-            } catch (RemoteException e) {
-                Log.e(LOG_TAG, Log.getStackTraceString(new Throwable()));
-            }
-        }
-
         // Update registration for ICC status after radio technology change
         IccCard sim = phone.getIccCard();
         if (sim != null) {
@@ -967,21 +943,4 @@
      * Used to determine if the preserved call origin is fresh enough.
      */
     private static final long CALL_ORIGIN_EXPIRATION_MILLIS = 30 * 1000;
-
-    /** Service connection */
-    private final ServiceConnection mBluetoothPhoneConnection = new ServiceConnection() {
-
-        /** Handle the task of binding the local object to the service */
-        public void onServiceConnected(ComponentName className, IBinder service) {
-            Log.i(LOG_TAG, "Headset phone created, binding local service.");
-            mBluetoothPhone = IBluetoothHeadsetPhone.Stub.asInterface(service);
-        }
-
-        /** Handle the task of cleaning up the local binding */
-        public void onServiceDisconnected(ComponentName className) {
-            Log.i(LOG_TAG, "Headset phone disconnected, cleaning local binding.");
-            mBluetoothPhone = null;
-        }
-    };
-
 }
diff --git a/src/com/android/phone/PhoneUtils.java b/src/com/android/phone/PhoneUtils.java
index fa3d18b..56d26c9 100644
--- a/src/com/android/phone/PhoneUtils.java
+++ b/src/com/android/phone/PhoneUtils.java
@@ -227,19 +227,7 @@
                         // should be allowed to add another call in case one of the parties
                         // drops off
                         app.cdmaPhoneCallState.setAddCallMenuStateAfterCallWaiting(true);
-
-                        // If a BluetoothPhoneService is valid we need to set the second call state
-                        // so that the Bluetooth client can update the Call state correctly when
-                        // a call waiting is answered from the Phone.
-                        btPhone = app.getBluetoothPhoneService();
-                        if (btPhone != null) {
-                            try {
-                                btPhone.cdmaSetSecondCallState(true);
-                            } catch (RemoteException e) {
-                                Log.e(LOG_TAG, Log.getStackTraceString(new Throwable()));
-                            }
-                        }
-                  }
+                    }
                 }
 
                 final boolean isRealIncomingCall = isRealIncomingCall(ringingCall.getState());
@@ -737,20 +725,6 @@
         // In the future we may provide some way for user to choose among
         // multiple background calls, for now, always act on the first background call.
         PhoneUtils.switchHoldingAndActive(mApp.mCM.getFirstActiveBgCall());
-
-        // If we have a valid BluetoothPhoneService then since CDMA network or
-        // Telephony FW does not send us information on which caller got swapped
-        // we need to update the second call active state in BluetoothPhoneService internally
-        if (mApp.mCM.getBgPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
-            final IBluetoothHeadsetPhone btPhone = mApp.getBluetoothPhoneService();
-            if (btPhone != null) {
-                try {
-                    btPhone.cdmaSwapSecondCallState();
-                } catch (RemoteException e) {
-                    Log.e(LOG_TAG, Log.getStackTraceString(new Throwable()));
-                }
-            }
-        }
     }
 
     /**
