/*
 * 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.
 */

/**
 * Bluetooth Handset StateMachine
 *                      (Disconnected)
 *                           |    ^
 *                   CONNECT |    | DISCONNECTED
 *                           V    |
 *                         (Pending)
 *                           |    ^
 *                 CONNECTED |    | CONNECT
 *                           V    |
 *                        (Connected)
 *                           |    ^
 *             CONNECT_AUDIO |    | DISCONNECT_AUDIO
 *                           V    |
 *                         (AudioOn)
 */
package com.android.bluetooth.hfp;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothAssignedNumbers;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothUuid;
import android.bluetooth.IBluetoothHeadsetPhone;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.ActivityNotFoundException;
import android.media.AudioManager;
import android.net.Uri;
import android.os.IBinder;
import android.os.IDeviceIdleController;
import android.os.Message;
import android.os.ParcelUuid;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.PowerManager;
import android.os.UserHandle;
import android.os.PowerManager.WakeLock;
import android.telephony.PhoneNumberUtils;
import android.util.Log;
import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.ProfileService;
import com.android.internal.util.IState;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import android.os.SystemProperties;

final class HeadsetStateMachine extends StateMachine {
    private static final String TAG = "HeadsetStateMachine";
    private static final boolean DBG = false;
    // For Debugging only
    private static int sRefCount = 0;

    private static final String HEADSET_NAME = "bt_headset_name";
    private static final String HEADSET_NREC = "bt_headset_nrec";
    private static final String HEADSET_WBS = "bt_wbs";

    static final int CONNECT = 1;
    static final int DISCONNECT = 2;
    static final int CONNECT_AUDIO = 3;
    static final int DISCONNECT_AUDIO = 4;
    static final int VOICE_RECOGNITION_START = 5;
    static final int VOICE_RECOGNITION_STOP = 6;

    // message.obj is an intent AudioManager.VOLUME_CHANGED_ACTION
    // EXTRA_VOLUME_STREAM_TYPE is STREAM_BLUETOOTH_SCO
    static final int INTENT_SCO_VOLUME_CHANGED = 7;
    static final int SET_MIC_VOLUME = 8;
    static final int CALL_STATE_CHANGED = 9;
    static final int INTENT_BATTERY_CHANGED = 10;
    static final int DEVICE_STATE_CHANGED = 11;
    static final int SEND_CCLC_RESPONSE = 12;
    static final int SEND_VENDOR_SPECIFIC_RESULT_CODE = 13;

    static final int VIRTUAL_CALL_START = 14;
    static final int VIRTUAL_CALL_STOP = 15;

    static final int ENABLE_WBS = 16;
    static final int DISABLE_WBS = 17;

    static final int BIND_RESPONSE = 18;

    private static final int STACK_EVENT = 101;
    private static final int DIALING_OUT_TIMEOUT = 102;
    private static final int START_VR_TIMEOUT = 103;
    private static final int CLCC_RSP_TIMEOUT = 104;

    private static final int CONNECT_TIMEOUT = 201;

    private static final int DIALING_OUT_TIMEOUT_VALUE = 10000;
    private static final int START_VR_TIMEOUT_VALUE = 5000;
    private static final int CLCC_RSP_TIMEOUT_VALUE = 5000;
    private static final int CONNECT_TIMEOUT_MILLIS = 30000;

    // Max number of HF connections at any time
    private int max_hf_connections = 1;

    private static final int NBS_CODEC = 1;
    private static final int WBS_CODEC = 2;

    // Keys are AT commands, and values are the company IDs.
    private static final Map<String, Integer> VENDOR_SPECIFIC_AT_COMMAND_COMPANY_ID;
    // Hash for storing the Audio Parameters like NREC for connected headsets
    private HashMap<BluetoothDevice, HashMap> mHeadsetAudioParam =
            new HashMap<BluetoothDevice, HashMap>();
    // Hash for storing the Remotedevice BRSF
    private HashMap<BluetoothDevice, Integer> mHeadsetBrsf =
            new HashMap<BluetoothDevice, Integer>();

    private static final ParcelUuid[] HEADSET_UUIDS = {
            BluetoothUuid.HSP, BluetoothUuid.Handsfree,
    };

    private Disconnected mDisconnected;
    private Pending mPending;
    private Connected mConnected;
    private AudioOn mAudioOn;
    // Multi HFP: add new class object
    private MultiHFPending mMultiHFPending;

    private HeadsetService mService;
    private PowerManager mPowerManager;
    private boolean mVirtualCallStarted = false;
    private boolean mVoiceRecognitionStarted = false;
    private boolean mWaitingForVoiceRecognition = false;
    private WakeLock mStartVoiceRecognitionWakeLock; // held while waiting for voice recognition

    private boolean mDialingOut = false;
    private AudioManager mAudioManager;
    private AtPhonebook mPhonebook;

    private static Intent sVoiceCommandIntent;

    private HeadsetPhoneState mPhoneState;
    private int mAudioState;
    private BluetoothAdapter mAdapter;
    private IBluetoothHeadsetPhone mPhoneProxy;
    private boolean mNativeAvailable;

    // Indicates whether audio can be routed to the device.
    private boolean mAudioRouteAllowed = true;

    // Indicates whether SCO audio needs to be forced to open regardless ANY OTHER restrictions
    private boolean mForceScoAudio = false;

    // mCurrentDevice is the device connected before the state changes
    // mTargetDevice is the device to be connected
    // mIncomingDevice is the device connecting to us, valid only in Pending state
    //                when mIncomingDevice is not null, both mCurrentDevice
    //                  and mTargetDevice are null
    //                when either mCurrentDevice or mTargetDevice is not null,
    //                  mIncomingDevice is null
    // Stable states
    //   No connection, Disconnected state
    //                  both mCurrentDevice and mTargetDevice are null
    //   Connected, Connected state
    //              mCurrentDevice is not null, mTargetDevice is null
    // Interim states
    //   Connecting to a device, Pending
    //                           mCurrentDevice is null, mTargetDevice is not null
    //   Disconnecting device, Connecting to new device
    //     Pending
    //     Both mCurrentDevice and mTargetDevice are not null
    //   Disconnecting device Pending
    //                        mCurrentDevice is not null, mTargetDevice is null
    //   Incoming connections Pending
    //                        Both mCurrentDevice and mTargetDevice are null
    private BluetoothDevice mCurrentDevice = null;
    private BluetoothDevice mTargetDevice = null;
    private BluetoothDevice mIncomingDevice = null;
    private BluetoothDevice mActiveScoDevice = null;
    private BluetoothDevice mMultiDisconnectDevice = null;

    // Multi HFP: Connected devices list holds all currently connected headsets
    private ArrayList<BluetoothDevice> mConnectedDevicesList = new ArrayList<BluetoothDevice>();

    static {
        classInitNative();

        VENDOR_SPECIFIC_AT_COMMAND_COMPANY_ID = new HashMap<String, Integer>();
        VENDOR_SPECIFIC_AT_COMMAND_COMPANY_ID.put(
                BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_XEVENT,
                BluetoothAssignedNumbers.PLANTRONICS);
        VENDOR_SPECIFIC_AT_COMMAND_COMPANY_ID.put(
                BluetoothHeadset.VENDOR_RESULT_CODE_COMMAND_ANDROID,
                BluetoothAssignedNumbers.GOOGLE);
        VENDOR_SPECIFIC_AT_COMMAND_COMPANY_ID.put(
                BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_XAPL,
                BluetoothAssignedNumbers.APPLE);
        VENDOR_SPECIFIC_AT_COMMAND_COMPANY_ID.put(
                BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV,
                BluetoothAssignedNumbers.APPLE);
    }

    private HeadsetStateMachine(HeadsetService context) {
        super(TAG);
        mService = context;
        mVoiceRecognitionStarted = false;
        mWaitingForVoiceRecognition = false;

        mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        mStartVoiceRecognitionWakeLock = mPowerManager.newWakeLock(
                PowerManager.PARTIAL_WAKE_LOCK, TAG + ":VoiceRecognition");
        mStartVoiceRecognitionWakeLock.setReferenceCounted(false);

        mDialingOut = false;
        mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        mPhonebook = new AtPhonebook(mService, this);
        mPhoneState = new HeadsetPhoneState(context, this);
        mAudioState = BluetoothHeadset.STATE_AUDIO_DISCONNECTED;
        mAdapter = BluetoothAdapter.getDefaultAdapter();
        Intent intent = new Intent(IBluetoothHeadsetPhone.class.getName());
        intent.setComponent(intent.resolveSystemService(context.getPackageManager(), 0));
        if (intent.getComponent() == null || !context.bindService(intent, mConnection, 0)) {
            Log.e(TAG, "Could not bind to Bluetooth Headset Phone Service");
        }

        String max_hfp_clients = SystemProperties.get("bt.max.hfpclient.connections");
        if (!max_hfp_clients.isEmpty() && (Integer.parseInt(max_hfp_clients) == 2)) {
            max_hf_connections = Integer.parseInt(max_hfp_clients);
        }
        Log.d(TAG, "max_hf_connections = " + max_hf_connections);
        Log.d(TAG,
                "in-band_ringing_support = " + BluetoothHeadset.isInbandRingingSupported(mService));
        initializeNative(max_hf_connections, BluetoothHeadset.isInbandRingingSupported(mService));
        mNativeAvailable = true;

        mDisconnected = new Disconnected();
        mPending = new Pending();
        mConnected = new Connected();
        mAudioOn = new AudioOn();
        // Multi HFP: initialise new class variable
        mMultiHFPending = new MultiHFPending();

        if (sVoiceCommandIntent == null) {
            sVoiceCommandIntent = new Intent(Intent.ACTION_VOICE_COMMAND);
            sVoiceCommandIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        }

        addState(mDisconnected);
        addState(mPending);
        addState(mConnected);
        addState(mAudioOn);
        // Multi HFP: add State
        addState(mMultiHFPending);

        setInitialState(mDisconnected);
    }

    static HeadsetStateMachine make(HeadsetService context) {
        Log.d(TAG, "make");
        HeadsetStateMachine hssm = new HeadsetStateMachine(context);
        hssm.start();
        return hssm;
    }

    public void doQuit() {
        quitNow();
    }

    public void cleanup() {
        if (mPhoneProxy != null) {
            if (DBG) Log.d(TAG, "Unbinding service...");
            synchronized (mConnection) {
                try {
                    mPhoneProxy = null;
                    mService.unbindService(mConnection);
                } catch (Exception re) {
                    Log.e(TAG, "Error unbinding from IBluetoothHeadsetPhone", re);
                }
            }
        }
        if (mPhoneState != null) {
            mPhoneState.listenForPhoneState(false);
            mPhoneState.cleanup();
        }
        if (mPhonebook != null) {
            mPhonebook.cleanup();
        }
        if (mHeadsetAudioParam != null) {
            mHeadsetAudioParam.clear();
        }
        if (mHeadsetBrsf != null) {
            mHeadsetBrsf.clear();
        }
        if (mConnectedDevicesList != null) {
            mConnectedDevicesList.clear();
        }
        if (mNativeAvailable) {
            cleanupNative();
            mNativeAvailable = false;
        }
    }

    public void dump(StringBuilder sb) {
        ProfileService.println(sb, "mCurrentDevice: " + mCurrentDevice);
        ProfileService.println(sb, "mTargetDevice: " + mTargetDevice);
        ProfileService.println(sb, "mIncomingDevice: " + mIncomingDevice);
        ProfileService.println(sb, "mActiveScoDevice: " + mActiveScoDevice);
        ProfileService.println(sb, "mMultiDisconnectDevice: " + mMultiDisconnectDevice);
        ProfileService.println(sb, "mVirtualCallStarted: " + mVirtualCallStarted);
        ProfileService.println(sb, "mVoiceRecognitionStarted: " + mVoiceRecognitionStarted);
        ProfileService.println(sb, "mWaitingForVoiceRecognition: " + mWaitingForVoiceRecognition);
        ProfileService.println(sb, "StateMachine: " + this.toString());
        ProfileService.println(sb, "mPhoneState: " + mPhoneState);
        ProfileService.println(sb, "mAudioState: " + mAudioState);
    }

    private class Disconnected extends State {
        @Override
        public void enter() {
            log("Enter Disconnected: " + getCurrentMessage().what + ", size: "
                    + mConnectedDevicesList.size());
            mPhonebook.resetAtState();
            mPhoneState.listenForPhoneState(false);
            mVoiceRecognitionStarted = false;
            mWaitingForVoiceRecognition = false;
        }

        @Override
        public boolean processMessage(Message message) {
            log("Disconnected process message: " + message.what + ", size: "
                    + mConnectedDevicesList.size());
            if (mConnectedDevicesList.size() != 0 || mTargetDevice != null
                    || mIncomingDevice != null) {
                Log.e(TAG, "ERROR: mConnectedDevicesList is not empty,"
                                + "target, or mIncomingDevice not null in Disconnected");
                return NOT_HANDLED;
            }

            switch (message.what) {
                case CONNECT:
                    BluetoothDevice device = (BluetoothDevice) message.obj;
                    Log.d(TAG, "Disconnected: connecting to device=" + device);
                    broadcastConnectionState(device, BluetoothProfile.STATE_CONNECTING,
                            BluetoothProfile.STATE_DISCONNECTED);
                    if (!connectHfpNative(getByteAddress(device))) {
                        broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED,
                                BluetoothProfile.STATE_CONNECTING);
                        break;
                    }
                    synchronized (HeadsetStateMachine.this) {
                        mTargetDevice = device;
                        transitionTo(mPending);
                    }
                    Message m = obtainMessage(CONNECT_TIMEOUT);
                    m.obj = device;
                    sendMessageDelayed(m, CONNECT_TIMEOUT_MILLIS);
                    break;
                case DISCONNECT:
                    // ignore
                    break;
                case INTENT_BATTERY_CHANGED:
                    processIntentBatteryChanged((Intent) message.obj);
                    break;
                case CALL_STATE_CHANGED:
                    processCallState((HeadsetCallState) message.obj, message.arg1 == 1);
                    break;
                case DEVICE_STATE_CHANGED:
                    log("Disconnected: ignoring DEVICE_STATE_CHANGED event");
                    break;
                case STACK_EVENT:
                    StackEvent event = (StackEvent) message.obj;
                    log("Disconnected: event type: " + event.type);
                    switch (event.type) {
                        case EVENT_TYPE_CONNECTION_STATE_CHANGED:
                            processConnectionEvent(event.valueInt, event.device);
                            break;
                        default:
                            Log.e(TAG, "Disconnected: unexpected stack event: " + event.type);
                            break;
                    }
                    break;
                default:
                    Log.e(TAG, "Disconnected: unexpected message " + message.what);
                    return NOT_HANDLED;
            }
            return HANDLED;
        }

        @Override
        public void exit() {
            log("Exit Disconnected: " + getCurrentMessage().what);
        }

        // in Disconnected state
        private void processConnectionEvent(int state, BluetoothDevice device) {
            Log.d(TAG,
                    "Disconnected: processConnectionEvent, state=" + state + ", device=" + device);
            switch (state) {
                case HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED:
                    Log.w(TAG, "Disconnected: ignore DISCONNECTED event, device=" + device);
                    break;
                // Both events result in Pending state as SLC establishment is still required
                case HeadsetHalConstants.CONNECTION_STATE_CONNECTED:
                case HeadsetHalConstants.CONNECTION_STATE_CONNECTING:
                    if (okToConnect(device)) {
                        Log.i(TAG,
                                "Disconnected: connected/connecting incoming HF, device=" + device);
                        broadcastConnectionState(device, BluetoothProfile.STATE_CONNECTING,
                                BluetoothProfile.STATE_DISCONNECTED);
                        synchronized (HeadsetStateMachine.this) {
                            mIncomingDevice = device;
                            transitionTo(mPending);
                        }
                    } else {
                        Log.i(TAG,
                                "Disconnected: rejected incoming HF, priority="
                                        + mService.getPriority(device) + " bondState="
                                        + device.getBondState() + ", device=" + device);
                        // reject the connection and stay in Disconnected state itself
                        disconnectHfpNative(getByteAddress(device));
                        // the other profile connection should be initiated
                        broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED,
                                BluetoothProfile.STATE_DISCONNECTED);
                    }
                    break;
                case HeadsetHalConstants.CONNECTION_STATE_DISCONNECTING:
                    Log.w(TAG, "Disconnected: ignore DISCONNECTING event, device=" + device);
                    break;
                default:
                    Log.e(TAG, "Disconnected: incorrect state: " + state);
                    break;
            }
        }
    }

    // Per HFP 1.7.1 spec page 23/144, Pending state needs to handle
    //      AT+BRSF, AT+CIND, AT+CMER, AT+BIND, +CHLD
    // commands during SLC establishment
    private class Pending extends State {
        @Override
        public void enter() {
            log("Enter Pending: " + getCurrentMessage().what);
        }

        @Override
        public boolean processMessage(Message message) {
            log("Pending: processMessage=" + message.what
                    + ", numConnectedDevices=" + mConnectedDevicesList.size());
            switch (message.what) {
                case CONNECT:
                case CONNECT_AUDIO:
                    deferMessage(message);
                    break;
                case CONNECT_TIMEOUT:
                    onConnectionStateChanged(HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED,
                            getByteAddress(mTargetDevice));
                    break;
                case DISCONNECT: {
                    BluetoothDevice device = (BluetoothDevice) message.obj;
                    Log.d(TAG, "Pending: DISCONNECT, device=" + device);
                    if (mCurrentDevice != null && mTargetDevice != null
                            && mTargetDevice.equals(device)) {
                        // cancel connection to the mTargetDevice
                        broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED,
                                BluetoothProfile.STATE_CONNECTING);
                        synchronized (HeadsetStateMachine.this) {
                            mTargetDevice = null;
                        }
                    } else {
                        deferMessage(message);
                    }
                    break;
                }
                case INTENT_BATTERY_CHANGED:
                    processIntentBatteryChanged((Intent) message.obj);
                    break;
                case CALL_STATE_CHANGED:
                    processCallState((HeadsetCallState) message.obj, message.arg1 == 1);
                    break;
                case BIND_RESPONSE: {
                    BluetoothDevice device = (BluetoothDevice) message.obj;
                    bindResponseNative(message.arg1, message.arg2 == 1, getByteAddress(device));
                    break;
                }
                case DEVICE_STATE_CHANGED:
                    log("Pending: ignoring DEVICE_STATE_CHANGED event");
                    break;
                case STACK_EVENT:
                    StackEvent event = (StackEvent) message.obj;
                    log("Pending: event type: " + event.type);
                    switch (event.type) {
                        case EVENT_TYPE_CONNECTION_STATE_CHANGED:
                            processConnectionEvent(event.valueInt, event.device);
                            break;
                        case EVENT_TYPE_AT_CHLD:
                            processAtChld(event.valueInt, event.device);
                            break;
                        case EVENT_TYPE_AT_CIND:
                            processAtCind(event.device);
                            break;
                        case EVENT_TYPE_WBS:
                            processWBSEvent(event.valueInt, event.device);
                            break;
                        case EVENT_TYPE_BIND:
                            processAtBind(event.valueString, event.device);
                            break;
                        // Unexpected AT commands, we only handle them for comparability reasons
                        case EVENT_TYPE_VR_STATE_CHANGED:
                            Log.w(TAG,
                                    "Pending: Unexpected VR event, device=" + event.device
                                            + ", state=" + event.valueInt);
                            processVrEvent(event.valueInt, event.device);
                            break;
                        case EVENT_TYPE_DIAL_CALL:
                            Log.w(TAG, "Pending: Unexpected dial event, device=" + event.device);
                            processDialCall(event.valueString, event.device);
                            break;
                        case EVENT_TYPE_SUBSCRIBER_NUMBER_REQUEST:
                            Log.w(TAG,
                                    "Pending: Unexpected subscriber number event for" + event.device
                                            + ", state=" + event.valueInt);
                            processSubscriberNumberRequest(event.device);
                            break;
                        case EVENT_TYPE_AT_COPS:
                            Log.w(TAG, "Pending: Unexpected COPS event for " + event.device);
                            processAtCops(event.device);
                            break;
                        case EVENT_TYPE_AT_CLCC:
                            Log.w(TAG, "Pending: Unexpected CLCC event for" + event.device);
                            processAtClcc(event.device);
                            break;
                        case EVENT_TYPE_UNKNOWN_AT:
                            Log.w(TAG,
                                    "Pending: Unexpected unknown AT event for" + event.device
                                            + ", cmd=" + event.valueString);
                            processUnknownAt(event.valueString, event.device);
                            break;
                        case EVENT_TYPE_KEY_PRESSED:
                            Log.w(TAG, "Pending: Unexpected key-press event for " + event.device);
                            processKeyPressed(event.device);
                            break;
                        case EVENT_TYPE_BIEV:
                            Log.w(TAG,
                                    "Pending: Unexpected BIEV event for " + event.device
                                            + ", indId=" + event.valueInt
                                            + ", indVal=" + event.valueInt2);
                            processAtBiev(event.valueInt, event.valueInt2, event.device);
                            break;
                        case EVENT_TYPE_VOLUME_CHANGED:
                            Log.w(TAG, "Pending: Unexpected volume event for " + event.device);
                            processVolumeEvent(event.valueInt, event.valueInt2, event.device);
                            break;
                        case EVENT_TYPE_ANSWER_CALL:
                            Log.w(TAG, "Pending: Unexpected answer event for " + event.device);
                            processAnswerCall(event.device);
                            break;
                        case EVENT_TYPE_HANGUP_CALL:
                            Log.w(TAG, "Pending: Unexpected hangup event for " + event.device);
                            processHangupCall(event.device);
                            break;
                        default:
                            Log.e(TAG, "Pending: Unexpected event: " + event.type);
                            break;
                    }
                    break;
                default:
                    Log.e(TAG, "Pending: unexpected message " + message.what);
                    return NOT_HANDLED;
            }
            return HANDLED;
        }

        // in Pending state
        private void processConnectionEvent(int state, BluetoothDevice device) {
            Log.d(TAG, "Pending: processConnectionEvent, state=" + state + ", device=" + device);
            BluetoothDevice pendingDevice = getDeviceForMessage(CONNECT_TIMEOUT);
            switch (state) {
                case HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED:
                    if (mConnectedDevicesList.contains(device)) {
                        synchronized (HeadsetStateMachine.this) {
                            mConnectedDevicesList.remove(device);
                            mHeadsetAudioParam.remove(device);
                            mHeadsetBrsf.remove(device);
                            Log.d(TAG,
                                    "Pending: device " + device.getAddress()
                                            + " is removed in Pending state");
                        }
                        broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED,
                                BluetoothProfile.STATE_DISCONNECTING);
                        synchronized (HeadsetStateMachine.this) {
                            mCurrentDevice = null;
                        }

                        processWBSEvent(0, device); /* disable WBS audio parameters */

                        if (mTargetDevice != null) {
                            if (!connectHfpNative(getByteAddress(mTargetDevice))) {
                                broadcastConnectionState(mTargetDevice,
                                        BluetoothProfile.STATE_DISCONNECTED,
                                        BluetoothProfile.STATE_CONNECTING);
                                synchronized (HeadsetStateMachine.this) {
                                    mTargetDevice = null;
                                    transitionTo(mDisconnected);
                                }
                            }
                        } else {
                            synchronized (HeadsetStateMachine.this) {
                                mIncomingDevice = null;
                                if (mConnectedDevicesList.size() == 0) {
                                    transitionTo(mDisconnected);
                                } else {
                                    processMultiHFConnected(device);
                                }
                            }
                        }
                    } else if (device.equals(mTargetDevice)) {
                        // outgoing connection failed
                        broadcastConnectionState(mTargetDevice, BluetoothProfile.STATE_DISCONNECTED,
                                BluetoothProfile.STATE_CONNECTING);
                        synchronized (HeadsetStateMachine.this) {
                            mTargetDevice = null;
                            if (mConnectedDevicesList.size() == 0) {
                                transitionTo(mDisconnected);
                            } else {
                                transitionTo(mConnected);
                            }
                        }
                    } else if (device.equals(mIncomingDevice)) {
                        broadcastConnectionState(mIncomingDevice,
                                BluetoothProfile.STATE_DISCONNECTED,
                                BluetoothProfile.STATE_CONNECTING);
                        synchronized (HeadsetStateMachine.this) {
                            mIncomingDevice = null;
                            if (mConnectedDevicesList.size() == 0) {
                                transitionTo(mDisconnected);
                            } else {
                                transitionTo(mConnected);
                            }
                        }
                    } else {
                        Log.e(TAG, "Pending: unknown device disconnected: " + device);
                    }
                    break;
                case HeadsetHalConstants.CONNECTION_STATE_CONNECTED:
                    if (mConnectedDevicesList.contains(device)) {
                        // Disconnection failure does not go through SLC establishment
                        Log.w(TAG, "Pending: disconnection failed for device " + device);
                        broadcastConnectionState(device, BluetoothProfile.STATE_CONNECTED,
                                BluetoothProfile.STATE_DISCONNECTING);
                        if (mTargetDevice != null) {
                            broadcastConnectionState(mTargetDevice,
                                    BluetoothProfile.STATE_DISCONNECTED,
                                    BluetoothProfile.STATE_CONNECTING);
                        }
                        synchronized (HeadsetStateMachine.this) {
                            mTargetDevice = null;
                            transitionTo(mConnected);
                        }
                    } else if (!device.equals(mTargetDevice) && !device.equals(mIncomingDevice)) {
                        Log.w(TAG,
                                "Pending: unknown incoming HF connected on RFCOMM, device="
                                        + device);
                        if (!okToConnect(device)) {
                            // reject the connection and stay in Pending state itself
                            Log.i(TAG,
                                    "Pending: unknown incoming HF rejected on RFCOMM, priority="
                                            + mService.getPriority(device)
                                            + " bondState=" + device.getBondState());
                            disconnectHfpNative(getByteAddress(device));
                        }
                    } else {
                        // Do nothing in normal case, wait for SLC connected event
                        pendingDevice = null;
                    }
                    break;
                case HeadsetHalConstants.CONNECTION_STATE_SLC_CONNECTED:
                    int previousConnectionState = BluetoothProfile.STATE_CONNECTING;
                    synchronized (HeadsetStateMachine.this) {
                        mCurrentDevice = device;
                        mConnectedDevicesList.add(device);
                        if (device.equals(mTargetDevice)) {
                            Log.d(TAG,
                                    "Pending: added " + device
                                            + " to mConnectedDevicesList, requested by us");
                            mTargetDevice = null;
                            transitionTo(mConnected);
                        } else if (device.equals(mIncomingDevice)) {
                            Log.d(TAG,
                                    "Pending: added " + device
                                            + " to mConnectedDevicesList, requested by remote");
                            mIncomingDevice = null;
                            transitionTo(mConnected);
                        } else {
                            Log.d(TAG,
                                    "Pending: added " + device
                                            + "to mConnectedDevicesList, unknown source");
                            previousConnectionState = BluetoothProfile.STATE_DISCONNECTED;
                        }
                    }
                    configAudioParameters(device);
                    queryPhoneState();
                    broadcastConnectionState(
                            device, BluetoothProfile.STATE_CONNECTED, previousConnectionState);
                    break;
                case HeadsetHalConstants.CONNECTION_STATE_CONNECTING:
                    if ((mCurrentDevice != null) && mCurrentDevice.equals(device)) {
                        log("current device tries to connect back");
                        // TODO(BT) ignore or reject
                    } else if (mTargetDevice != null && mTargetDevice.equals(device)) {
                        // The stack is connecting to target device or
                        // there is an incoming connection from the target device at the same time
                        // we already broadcasted the intent, doing nothing here
                        log("Stack and target device are connecting");
                    } else if (mIncomingDevice != null && mIncomingDevice.equals(device)) {
                        Log.e(TAG, "Another connecting event on the incoming device");
                    } else {
                        // We get an incoming connecting request while Pending
                        // TODO(BT) is stack handing this case? let's ignore it for now
                        log("Incoming connection while pending, ignore");
                    }
                    break;
                case HeadsetHalConstants.CONNECTION_STATE_DISCONNECTING:
                    if ((mCurrentDevice != null) && mCurrentDevice.equals(device)) {
                        // we already broadcasted the intent, doing nothing here
                        log("stack is disconnecting mCurrentDevice");
                    } else if (mTargetDevice != null && mTargetDevice.equals(device)) {
                        Log.e(TAG, "TargetDevice is getting disconnected");
                    } else if (mIncomingDevice != null && mIncomingDevice.equals(device)) {
                        Log.e(TAG, "IncomingDevice is getting disconnected");
                    } else {
                        Log.e(TAG, "Disconnecting unknow device: " + device);
                    }
                    break;
                default:
                    Log.e(TAG, "Incorrect state: " + state);
                    break;
            }
            if (pendingDevice != null && pendingDevice.equals(device)) {
                removeMessages(CONNECT_TIMEOUT);
                Log.d(TAG, "Pending: removed CONNECT_TIMEOUT for device=" + pendingDevice);
            }
        }

        private void processMultiHFConnected(BluetoothDevice device) {
            log("Pending state: processMultiHFConnected");
            /* Assign the current activedevice again if the disconnected
                         device equals to the current active device*/
            if (mCurrentDevice != null && mCurrentDevice.equals(device)) {
                transitionTo(mConnected);
                int deviceSize = mConnectedDevicesList.size();
                mCurrentDevice = mConnectedDevicesList.get(deviceSize - 1);
            } else {
                // The disconnected device is not current active device
                if (mAudioState == BluetoothHeadset.STATE_AUDIO_CONNECTED)
                    transitionTo(mAudioOn);
                else
                    transitionTo(mConnected);
            }
            log("processMultiHFConnected , the latest mCurrentDevice is:" + mCurrentDevice);
            log("Pending state: processMultiHFConnected ,"
                    + "fake broadcasting for mCurrentDevice");
            broadcastConnectionState(mCurrentDevice, BluetoothProfile.STATE_CONNECTED,
                    BluetoothProfile.STATE_DISCONNECTED);
        }
    }

    private class Connected extends State {
        @Override
        public void enter() {
            // Remove pending connection attempts that were deferred during the pending
            // state. This is to prevent auto connect attempts from disconnecting
            // devices that previously successfully connected.
            // TODO: This needs to check for multiple HFP connections, once supported...
            removeDeferredMessages(CONNECT);

            log("Enter Connected: " + getCurrentMessage().what + ", size: "
                    + mConnectedDevicesList.size());
            // start phone state listener here so that the CIND response as part of SLC can be
            // responded to, correctly.
            // we may enter Connected from Disconnected/Pending/AudioOn. listenForPhoneState
            // internally handles multiple calls to start listen
            mPhoneState.listenForPhoneState(true);
        }

        @Override
        public boolean processMessage(Message message) {
            log("Connected process message=" + message.what
                    + ", numConnectedDevices=" + mConnectedDevicesList.size());
            switch (message.what) {
                case CONNECT: {
                    BluetoothDevice device = (BluetoothDevice) message.obj;
                    Log.d(TAG, "Connected: CONNECT, device=" + device);
                    if (mConnectedDevicesList.contains(device)) {
                        Log.w(TAG, "Connected: CONNECT, device " + device + " is connected");
                        break;
                    }
                    if (mConnectedDevicesList.size() >= max_hf_connections) {
                        BluetoothDevice disconnectDevice = mConnectedDevicesList.get(0);
                        Log.d(TAG, "Connected: Reach to max size, disconnect " + disconnectDevice);
                        broadcastConnectionState(device, BluetoothProfile.STATE_CONNECTING,
                                BluetoothProfile.STATE_DISCONNECTED);
                        if (disconnectHfpNative(getByteAddress(disconnectDevice))) {
                            broadcastConnectionState(disconnectDevice,
                                    BluetoothProfile.STATE_DISCONNECTING,
                                    BluetoothProfile.STATE_CONNECTED);
                        } else {
                            Log.w(TAG, "Connected: failed to disconnect " + disconnectDevice);
                            broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED,
                                    BluetoothProfile.STATE_CONNECTING);
                            break;
                        }
                        synchronized (HeadsetStateMachine.this) {
                            mTargetDevice = device;
                            if (max_hf_connections == 1) {
                                transitionTo(mPending);
                            } else {
                                mMultiDisconnectDevice = disconnectDevice;
                                transitionTo(mMultiHFPending);
                            }
                        }
                    } else if (mConnectedDevicesList.size() < max_hf_connections) {
                        broadcastConnectionState(device, BluetoothProfile.STATE_CONNECTING,
                                BluetoothProfile.STATE_DISCONNECTED);
                        if (!connectHfpNative(getByteAddress(device))) {
                            broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED,
                                    BluetoothProfile.STATE_CONNECTING);
                            break;
                        }
                        synchronized (HeadsetStateMachine.this) {
                            mTargetDevice = device;
                            // Transition to MultiHFPending state for Multi HF connection
                            transitionTo(mMultiHFPending);
                        }
                    }
                    Message m = obtainMessage(CONNECT_TIMEOUT);
                    m.obj = device;
                    sendMessageDelayed(m, CONNECT_TIMEOUT_MILLIS);
                } break;
                case DISCONNECT: {
                    BluetoothDevice device = (BluetoothDevice) message.obj;
                    Log.d(TAG, "Connected: DISCONNECT from device=" + device);
                    if (!mConnectedDevicesList.contains(device)) {
                        Log.w(TAG, "Connected: DISCONNECT, device " + device + " not connected");
                        break;
                    }
                    broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTING,
                            BluetoothProfile.STATE_CONNECTED);
                    if (!disconnectHfpNative(getByteAddress(device))) {
                        // Failed disconnection request
                        broadcastConnectionState(device, BluetoothProfile.STATE_CONNECTED,
                                BluetoothProfile.STATE_DISCONNECTING);
                        break;
                    }
                    // Pending disconnection confirmation
                    if (mConnectedDevicesList.size() > 1) {
                        mMultiDisconnectDevice = device;
                        transitionTo(mMultiHFPending);
                    } else {
                        transitionTo(mPending);
                    }
                } break;
                case CONNECT_AUDIO: {
                    BluetoothDevice device = mCurrentDevice;
                    Log.d(TAG, "Connected: CONNECT_AUDIO, device=" + device);
                    if (!isScoAcceptable()) {
                        Log.w(TAG,
                                "No Active/Held call, no call setup, and no in-band ringing,"
                                        + " not allowing SCO, device=" + device);
                        break;
                    }
                    // TODO(BT) when failure, broadcast audio connecting to disconnected intent
                    //          check if device matches mCurrentDevice
                    if (mActiveScoDevice != null) {
                        Log.w(TAG, "Connected: CONNECT_AUDIO, mActiveScoDevice is not null");
                        device = mActiveScoDevice;
                    }
                    connectAudioNative(getByteAddress(device));
                } break;
                case VOICE_RECOGNITION_START:
                    processLocalVrEvent(HeadsetHalConstants.VR_STATE_STARTED);
                    break;
                case VOICE_RECOGNITION_STOP:
                    processLocalVrEvent(HeadsetHalConstants.VR_STATE_STOPPED);
                    break;
                case CALL_STATE_CHANGED:
                    processCallState((HeadsetCallState) message.obj, message.arg1 == 1);
                    break;
                case INTENT_BATTERY_CHANGED:
                    processIntentBatteryChanged((Intent) message.obj);
                    break;
                case DEVICE_STATE_CHANGED:
                    processDeviceStateChanged((HeadsetDeviceState) message.obj);
                    break;
                case SEND_CCLC_RESPONSE:
                    processSendClccResponse((HeadsetClccResponse) message.obj);
                    break;
                case CLCC_RSP_TIMEOUT: {
                    BluetoothDevice device = (BluetoothDevice) message.obj;
                    clccResponseNative(0, 0, 0, 0, false, "", 0, getByteAddress(device));
                } break;
                case SEND_VENDOR_SPECIFIC_RESULT_CODE:
                    processSendVendorSpecificResultCode(
                            (HeadsetVendorSpecificResultCode) message.obj);
                    break;
                case DIALING_OUT_TIMEOUT: {
                    BluetoothDevice device = (BluetoothDevice) message.obj;
                    if (mDialingOut) {
                        mDialingOut = false;
                        atResponseCodeNative(
                                HeadsetHalConstants.AT_RESPONSE_ERROR, 0, getByteAddress(device));
                    }
                } break;
                case VIRTUAL_CALL_START:
                    initiateScoUsingVirtualVoiceCall();
                    break;
                case VIRTUAL_CALL_STOP:
                    terminateScoUsingVirtualVoiceCall();
                    break;
                case ENABLE_WBS: {
                    BluetoothDevice device = (BluetoothDevice) message.obj;
                    configureWBSNative(getByteAddress(device), WBS_CODEC);
                    break;
                }
                case DISABLE_WBS: {
                    BluetoothDevice device = (BluetoothDevice) message.obj;
                    configureWBSNative(getByteAddress(device), NBS_CODEC);
                    break;
                }
                case BIND_RESPONSE: {
                    BluetoothDevice device = (BluetoothDevice) message.obj;
                    bindResponseNative(message.arg1, message.arg2 == 1, getByteAddress(device));
                    break;
                }
                case START_VR_TIMEOUT: {
                    BluetoothDevice device = (BluetoothDevice) message.obj;
                    if (mWaitingForVoiceRecognition) {
                        device = (BluetoothDevice) message.obj;
                        mWaitingForVoiceRecognition = false;
                        Log.e(TAG, "Timeout waiting for voice recognition to start");
                        atResponseCodeNative(
                                HeadsetHalConstants.AT_RESPONSE_ERROR, 0, getByteAddress(device));
                    }
                } break;
                case STACK_EVENT:
                    StackEvent event = (StackEvent) message.obj;
                    log("Connected: event type: " + event.type + "event device : " + event.device);
                    switch (event.type) {
                        case EVENT_TYPE_CONNECTION_STATE_CHANGED:
                            processConnectionEvent(event.valueInt, event.device);
                            break;
                        case EVENT_TYPE_AUDIO_STATE_CHANGED:
                            processAudioEvent(event.valueInt, event.device);
                            break;
                        case EVENT_TYPE_VR_STATE_CHANGED:
                            processVrEvent(event.valueInt, event.device);
                            break;
                        case EVENT_TYPE_ANSWER_CALL:
                            processAnswerCall(event.device);
                            break;
                        case EVENT_TYPE_HANGUP_CALL:
                            processHangupCall(event.device);
                            break;
                        case EVENT_TYPE_VOLUME_CHANGED:
                            processVolumeEvent(event.valueInt, event.valueInt2, event.device);
                            break;
                        case EVENT_TYPE_DIAL_CALL:
                            processDialCall(event.valueString, event.device);
                            break;
                        case EVENT_TYPE_SEND_DTMF:
                            processSendDtmf(event.valueInt, event.device);
                            break;
                        case EVENT_TYPE_NOICE_REDUCTION:
                            processNoiceReductionEvent(event.valueInt, event.device);
                            break;
                        case EVENT_TYPE_WBS:
                            processWBSEvent(event.valueInt, event.device);
                            break;
                        case EVENT_TYPE_AT_CHLD:
                            processAtChld(event.valueInt, event.device);
                            break;
                        case EVENT_TYPE_SUBSCRIBER_NUMBER_REQUEST:
                            processSubscriberNumberRequest(event.device);
                            break;
                        case EVENT_TYPE_AT_CIND:
                            processAtCind(event.device);
                            break;
                        case EVENT_TYPE_AT_COPS:
                            processAtCops(event.device);
                            break;
                        case EVENT_TYPE_AT_CLCC:
                            processAtClcc(event.device);
                            break;
                        case EVENT_TYPE_UNKNOWN_AT:
                            processUnknownAt(event.valueString, event.device);
                            break;
                        case EVENT_TYPE_KEY_PRESSED:
                            processKeyPressed(event.device);
                            break;
                        case EVENT_TYPE_BIND:
                            processAtBind(event.valueString, event.device);
                            break;
                        case EVENT_TYPE_BIEV:
                            processAtBiev(event.valueInt, event.valueInt2, event.device);
                            break;
                        default:
                            Log.e(TAG, "Connected: Unknown stack event: " + event.type);
                            break;
                    }
                    break;
                default:
                    Log.e(TAG, "Connected: unexpected message " + message.what);
                    return NOT_HANDLED;
            }
            return HANDLED;
        }

        // in Connected state
        private void processConnectionEvent(int state, BluetoothDevice device) {
            Log.d(TAG, "Connected: processConnectionEvent, state=" + state + ", device=" + device);
            switch (state) {
                case HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED:
                    if (mConnectedDevicesList.contains(device)) {
                        processWBSEvent(0, device); /* disable WBS audio parameters */
                        synchronized (HeadsetStateMachine.this) {
                            mConnectedDevicesList.remove(device);
                            mHeadsetAudioParam.remove(device);
                            mHeadsetBrsf.remove(device);
                            Log.d(TAG, "device " + device.getAddress()
                                            + " is removed in Connected state");

                            if (mConnectedDevicesList.size() == 0) {
                                mCurrentDevice = null;
                                transitionTo(mDisconnected);
                            } else {
                                processMultiHFConnected(device);
                            }
                        }
                        broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED,
                                BluetoothProfile.STATE_CONNECTED);
                    } else {
                        Log.e(TAG, "Disconnected from unknown device: " + device);
                    }
                    break;
                case HeadsetHalConstants.CONNECTION_STATE_SLC_CONNECTED:
                    // Should have been rejected in CONNECTION_STATE_CONNECTED
                    if (okToConnect(device)
                            && (mConnectedDevicesList.size() < max_hf_connections)) {
                        broadcastConnectionState(device, BluetoothProfile.STATE_CONNECTED,
                                BluetoothProfile.STATE_DISCONNECTED);
                        synchronized (HeadsetStateMachine.this) {
                            if (!mConnectedDevicesList.contains(device)) {
                                mCurrentDevice = device;
                                mConnectedDevicesList.add(device);
                                Log.d(TAG,
                                        "device " + device.getAddress()
                                                + " is added in Connected state");
                            }
                            transitionTo(mConnected);
                        }
                        configAudioParameters(device);
                    }
                    queryPhoneState();
                    break;
                case HeadsetHalConstants.CONNECTION_STATE_CONNECTED:
                    if (mConnectedDevicesList.contains(device)) {
                        mIncomingDevice = null;
                        mTargetDevice = null;
                        break;
                    }
                    Log.w(TAG, "HFP to be Connected in Connected state");
                    if (!okToConnect(device)
                            || (mConnectedDevicesList.size() >= max_hf_connections)) {
                        // reject the connection and stay in Connected state itself
                        Log.i(TAG, "Incoming Hf rejected. priority=" + mService.getPriority(device)
                                        + " bondState=" + device.getBondState());
                        disconnectHfpNative(getByteAddress(device));
                    }
                    break;
                default:
                    Log.e(TAG, "Connection State Device: " + device + " bad state: " + state);
                    break;
            }
        }

        // in Connected state
        private void processAudioEvent(int state, BluetoothDevice device) {
            if (!mConnectedDevicesList.contains(device)) {
                Log.e(TAG, "Audio changed on disconnected device: " + device);
                return;
            }

            switch (state) {
                case HeadsetHalConstants.AUDIO_STATE_CONNECTED:
                    if (!isScoAcceptable()) {
                        Log.e(TAG, "Audio Connected without any listener");
                        disconnectAudioNative(getByteAddress(device));
                        break;
                    }

                    // TODO(BT) should I save the state for next broadcast as the prevState?
                    mAudioState = BluetoothHeadset.STATE_AUDIO_CONNECTED;
                    setAudioParameters(device); /*Set proper Audio Paramters.*/
                    mAudioManager.setBluetoothScoOn(true);
                    mActiveScoDevice = device;
                    broadcastAudioState(device, BluetoothHeadset.STATE_AUDIO_CONNECTED,
                            BluetoothHeadset.STATE_AUDIO_CONNECTING);
                    transitionTo(mAudioOn);
                    break;
                case HeadsetHalConstants.AUDIO_STATE_CONNECTING:
                    mAudioState = BluetoothHeadset.STATE_AUDIO_CONNECTING;
                    broadcastAudioState(device, BluetoothHeadset.STATE_AUDIO_CONNECTING,
                            BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
                    break;
                // TODO(BT) process other states
                default:
                    Log.e(TAG, "Audio State Device: " + device + " bad state: " + state);
                    break;
            }
        }

        private void processMultiHFConnected(BluetoothDevice device) {
            log("Connect state: processMultiHFConnected");
            if (mActiveScoDevice != null && mActiveScoDevice.equals(device)) {
                log("mActiveScoDevice is disconnected, setting it to null");
                mActiveScoDevice = null;
            }
            /* Assign the current activedevice again if the disconnected
                         device equals to the current active device */
            if (mCurrentDevice != null && mCurrentDevice.equals(device)) {
                transitionTo(mConnected);
                int deviceSize = mConnectedDevicesList.size();
                mCurrentDevice = mConnectedDevicesList.get(deviceSize - 1);
            } else {
                // The disconnected device is not current active device
                transitionTo(mConnected);
            }
            log("processMultiHFConnected , the latest mCurrentDevice is:" + mCurrentDevice);
            log("Connect state: processMultiHFConnected ,"
                    + "fake broadcasting for mCurrentDevice");
            broadcastConnectionState(mCurrentDevice, BluetoothProfile.STATE_CONNECTED,
                    BluetoothProfile.STATE_DISCONNECTED);
        }
    }

    private class AudioOn extends State {
        @Override
        public void enter() {
            log("Enter AudioOn: " + getCurrentMessage().what + ", size: "
                    + mConnectedDevicesList.size());
        }

        @Override
        public boolean processMessage(Message message) {
            log("AudioOn process message: " + message.what + ", size: "
                    + mConnectedDevicesList.size());
            switch (message.what) {
                case CONNECT: {
                    BluetoothDevice device = (BluetoothDevice) message.obj;
                    Log.d(TAG, "AudioOn: CONNECT, device=" + device);
                    if (mConnectedDevicesList.contains(device)) {
                        Log.w(TAG, "AudioOn: CONNECT, device " + device + " is connected");
                        break;
                    }

                    if (max_hf_connections == 1) {
                        deferMessage(obtainMessage(DISCONNECT, mCurrentDevice));
                        deferMessage(obtainMessage(CONNECT, device));
                        if (disconnectAudioNative(getByteAddress(mCurrentDevice))) {
                            Log.d(TAG, "AudioOn: disconnecting SCO, device=" + mCurrentDevice);
                        } else {
                            Log.e(TAG, "AudioOn: disconnect SCO failed, device=" + mCurrentDevice);
                        }
                        break;
                    }

                    if (mConnectedDevicesList.size() >= max_hf_connections) {
                        BluetoothDevice disconnectDevice = mConnectedDevicesList.get(0);
                        Log.d(TAG, "AudioOn: Reach to max size, disconnect " + disconnectDevice);

                        if (mActiveScoDevice.equals(disconnectDevice)) {
                            disconnectDevice = mConnectedDevicesList.get(1);
                        }

                        broadcastConnectionState(device, BluetoothProfile.STATE_CONNECTING,
                                BluetoothProfile.STATE_DISCONNECTED);

                        if (disconnectHfpNative(getByteAddress(disconnectDevice))) {
                            broadcastConnectionState(disconnectDevice,
                                    BluetoothProfile.STATE_DISCONNECTING,
                                    BluetoothProfile.STATE_CONNECTED);
                        } else {
                            Log.e(TAG, "AudioOn: Failed to disconnect " + disconnectDevice);
                            broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED,
                                    BluetoothProfile.STATE_CONNECTING);
                            break;
                        }

                        synchronized (HeadsetStateMachine.this) {
                            mTargetDevice = device;
                            mMultiDisconnectDevice = disconnectDevice;
                            transitionTo(mMultiHFPending);
                        }
                    } else if (mConnectedDevicesList.size() < max_hf_connections) {
                        broadcastConnectionState(device, BluetoothProfile.STATE_CONNECTING,
                                BluetoothProfile.STATE_DISCONNECTED);
                        if (!connectHfpNative(getByteAddress(device))) {
                            broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED,
                                    BluetoothProfile.STATE_CONNECTING);
                            break;
                        }
                        synchronized (HeadsetStateMachine.this) {
                            mTargetDevice = device;
                            // Transtion to MultilHFPending state for Multi handsfree connection
                            transitionTo(mMultiHFPending);
                        }
                    }
                    Message m = obtainMessage(CONNECT_TIMEOUT);
                    m.obj = device;
                    sendMessageDelayed(m, CONNECT_TIMEOUT_MILLIS);
                } break;
                case CONNECT_TIMEOUT:
                    onConnectionStateChanged(HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED,
                            getByteAddress(mTargetDevice));
                    break;
                case DISCONNECT: {
                    BluetoothDevice device = (BluetoothDevice) message.obj;
                    Log.d(TAG, "AudioOn: DISCONNECT, device=" + device);
                    if (!mConnectedDevicesList.contains(device)) {
                        Log.w(TAG, "AudioOn: DISCONNECT, device " + device + " not connected");
                        break;
                    }
                    if (mActiveScoDevice != null && mActiveScoDevice.equals(device)) {
                        // The disconnected device is active SCO device
                        Log.d(TAG, "AudioOn, DISCONNECT mActiveScoDevice=" + mActiveScoDevice);
                        deferMessage(obtainMessage(DISCONNECT, message.obj));
                        // Disconnect BT SCO first
                        if (disconnectAudioNative(getByteAddress(mActiveScoDevice))) {
                            log("Disconnecting SCO audio");
                        } else {
                            Log.w(TAG, "AudioOn, DISCONNECT failed, device=" + mActiveScoDevice);
                            // if disconnect BT SCO failed, transition to mConnected state
                            transitionTo(mConnected);
                        }
                    } else {
                        /* Do not disconnect BT SCO if the disconnected
                           device is not active SCO device */
                        Log.d(TAG, "AudioOn, DISCONNECT, none active SCO device=" + device);
                        broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTING,
                                BluetoothProfile.STATE_CONNECTED);
                        // Should be still in AudioOn state
                        if (!disconnectHfpNative(getByteAddress(device))) {
                            Log.w(TAG, "AudioOn, DISCONNECT failed, device=" + device);
                            broadcastConnectionState(device, BluetoothProfile.STATE_CONNECTED,
                                    BluetoothProfile.STATE_DISCONNECTING);
                            break;
                        }
                        /* Transtion to MultiHFPending state for Multi handsfree connection */
                        if (mConnectedDevicesList.size() > 1) {
                            mMultiDisconnectDevice = device;
                            transitionTo(mMultiHFPending);
                        }
                    }
                } break;
                case DISCONNECT_AUDIO:
                    if (mActiveScoDevice != null) {
                        if (disconnectAudioNative(getByteAddress(mActiveScoDevice))) {
                            Log.d(TAG, "AudioOn: DISCONNECT_AUDIO, device=" + mActiveScoDevice);
                        } else {
                            Log.e(TAG,
                                    "AudioOn: DISCONNECT_AUDIO failed, device=" + mActiveScoDevice);
                        }
                    } else {
                        Log.w(TAG, "AudioOn: DISCONNECT_AUDIO, mActiveScoDevice is null");
                    }
                    break;
                case VOICE_RECOGNITION_START:
                    processLocalVrEvent(HeadsetHalConstants.VR_STATE_STARTED);
                    break;
                case VOICE_RECOGNITION_STOP:
                    processLocalVrEvent(HeadsetHalConstants.VR_STATE_STOPPED);
                    break;
                case INTENT_SCO_VOLUME_CHANGED:
                    if (mActiveScoDevice != null) {
                        processIntentScoVolume((Intent) message.obj, mActiveScoDevice);
                    }
                    break;
                case CALL_STATE_CHANGED:
                    processCallState((HeadsetCallState) message.obj, message.arg1 == 1);
                    break;
                case INTENT_BATTERY_CHANGED:
                    processIntentBatteryChanged((Intent) message.obj);
                    break;
                case DEVICE_STATE_CHANGED:
                    processDeviceStateChanged((HeadsetDeviceState) message.obj);
                    break;
                case SEND_CCLC_RESPONSE:
                    processSendClccResponse((HeadsetClccResponse) message.obj);
                    break;
                case CLCC_RSP_TIMEOUT: {
                    BluetoothDevice device = (BluetoothDevice) message.obj;
                    clccResponseNative(0, 0, 0, 0, false, "", 0, getByteAddress(device));
                    break;
                }
                case SEND_VENDOR_SPECIFIC_RESULT_CODE:
                    processSendVendorSpecificResultCode(
                            (HeadsetVendorSpecificResultCode) message.obj);
                    break;

                case VIRTUAL_CALL_START:
                    initiateScoUsingVirtualVoiceCall();
                    break;
                case VIRTUAL_CALL_STOP:
                    terminateScoUsingVirtualVoiceCall();
                    break;

                case DIALING_OUT_TIMEOUT: {
                    if (mDialingOut) {
                        BluetoothDevice device = (BluetoothDevice) message.obj;
                        mDialingOut = false;
                        atResponseCodeNative(
                                HeadsetHalConstants.AT_RESPONSE_ERROR, 0, getByteAddress(device));
                    }
                    break;
                }
                case START_VR_TIMEOUT: {
                    if (mWaitingForVoiceRecognition) {
                        BluetoothDevice device = (BluetoothDevice) message.obj;
                        mWaitingForVoiceRecognition = false;
                        Log.e(TAG, "Timeout waiting for voice recognition"
                                        + "to start");
                        atResponseCodeNative(
                                HeadsetHalConstants.AT_RESPONSE_ERROR, 0, getByteAddress(device));
                    }
                    break;
                }
                case STACK_EVENT:
                    StackEvent event = (StackEvent) message.obj;
                    log("AudioOn: event type: " + event.type);
                    switch (event.type) {
                        case EVENT_TYPE_CONNECTION_STATE_CHANGED:
                            processConnectionEvent(event.valueInt, event.device);
                            break;
                        case EVENT_TYPE_AUDIO_STATE_CHANGED:
                            processAudioEvent(event.valueInt, event.device);
                            break;
                        case EVENT_TYPE_VR_STATE_CHANGED:
                            processVrEvent(event.valueInt, event.device);
                            break;
                        case EVENT_TYPE_ANSWER_CALL:
                            processAnswerCall(event.device);
                            break;
                        case EVENT_TYPE_HANGUP_CALL:
                            processHangupCall(event.device);
                            break;
                        case EVENT_TYPE_VOLUME_CHANGED:
                            processVolumeEvent(event.valueInt, event.valueInt2, event.device);
                            break;
                        case EVENT_TYPE_DIAL_CALL:
                            processDialCall(event.valueString, event.device);
                            break;
                        case EVENT_TYPE_SEND_DTMF:
                            processSendDtmf(event.valueInt, event.device);
                            break;
                        case EVENT_TYPE_NOICE_REDUCTION:
                            processNoiceReductionEvent(event.valueInt, event.device);
                            break;
                        case EVENT_TYPE_AT_CHLD:
                            processAtChld(event.valueInt, event.device);
                            break;
                        case EVENT_TYPE_SUBSCRIBER_NUMBER_REQUEST:
                            processSubscriberNumberRequest(event.device);
                            break;
                        case EVENT_TYPE_AT_CIND:
                            processAtCind(event.device);
                            break;
                        case EVENT_TYPE_AT_COPS:
                            processAtCops(event.device);
                            break;
                        case EVENT_TYPE_AT_CLCC:
                            processAtClcc(event.device);
                            break;
                        case EVENT_TYPE_UNKNOWN_AT:
                            processUnknownAt(event.valueString, event.device);
                            break;
                        case EVENT_TYPE_KEY_PRESSED:
                            processKeyPressed(event.device);
                            break;
                        case EVENT_TYPE_BIND:
                            processAtBind(event.valueString, event.device);
                            break;
                        case EVENT_TYPE_BIEV:
                            processAtBiev(event.valueInt, event.valueInt2, event.device);
                            break;
                        default:
                            Log.e(TAG, "AudioOn: Unknown stack event: " + event.type);
                            break;
                    }
                    break;
                default:
                    Log.e(TAG, "AudioOn: unexpected message " + message.what);
                    return NOT_HANDLED;
            }
            return HANDLED;
        }

        // in AudioOn state. Some headsets disconnect RFCOMM prior to SCO down. Handle this
        private void processConnectionEvent(int state, BluetoothDevice device) {
            Log.d(TAG, "AudioOn: processConnectionEvent, state=" + state + ", device=" + device);
            BluetoothDevice pendingDevice = getDeviceForMessage(CONNECT_TIMEOUT);
            switch (state) {
                case HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED:
                    if (mConnectedDevicesList.contains(device)) {
                        if (mActiveScoDevice != null && mActiveScoDevice.equals(device)
                                && mAudioState != BluetoothHeadset.STATE_AUDIO_DISCONNECTED) {
                            processAudioEvent(HeadsetHalConstants.AUDIO_STATE_DISCONNECTED, device);
                        }

                        synchronized (HeadsetStateMachine.this) {
                            mConnectedDevicesList.remove(device);
                            mHeadsetAudioParam.remove(device);
                            mHeadsetBrsf.remove(device);
                            Log.d(TAG, "device " + device.getAddress()
                                            + " is removed in AudioOn state");
                            broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED,
                                    BluetoothProfile.STATE_CONNECTED);
                            processWBSEvent(0, device); /* disable WBS audio parameters */
                            if (mConnectedDevicesList.size() == 0) {
                                transitionTo(mDisconnected);
                            } else {
                                processMultiHFConnected(device);
                            }
                        }
                    } else {
                        Log.e(TAG, "Disconnected from unknown device: " + device);
                    }
                    break;
                case HeadsetHalConstants.CONNECTION_STATE_SLC_CONNECTED:
                    // Should have been rejected in CONNECTION_STATE_CONNECTED
                    if (okToConnect(device)
                            && (mConnectedDevicesList.size() < max_hf_connections)) {
                        Log.i(TAG, "AudioOn: accepted incoming HF");
                        broadcastConnectionState(device, BluetoothProfile.STATE_CONNECTED,
                                BluetoothProfile.STATE_DISCONNECTED);
                        synchronized (HeadsetStateMachine.this) {
                            if (!mConnectedDevicesList.contains(device)) {
                                mCurrentDevice = device;
                                mConnectedDevicesList.add(device);
                                Log.d(TAG,
                                        "device " + device.getAddress()
                                                + " is added in AudioOn state");
                            }
                        }
                        configAudioParameters(device);
                    }
                    queryPhoneState();
                    break;
                case HeadsetHalConstants.CONNECTION_STATE_CONNECTED:
                    if (mConnectedDevicesList.contains(device)) {
                        mIncomingDevice = null;
                        mTargetDevice = null;
                        break;
                    }
                    Log.w(TAG, "AudioOn: HFP to be connected device=" + device);
                    if (!okToConnect(device)
                            || (mConnectedDevicesList.size() >= max_hf_connections)) {
                        // reject the connection and stay in Connected state itself
                        Log.i(TAG,
                                "AudioOn: rejected incoming HF, priority="
                                        + mService.getPriority(device)
                                        + " bondState=" + device.getBondState());
                        disconnectHfpNative(getByteAddress(device));
                    } else {
                        // Do nothing in normal case, wait for SLC connected event
                        pendingDevice = null;
                    }
                    break;
                default:
                    Log.e(TAG, "Connection State Device: " + device + " bad state: " + state);
                    break;
            }
            if (pendingDevice != null && pendingDevice.equals(device)) {
                removeMessages(CONNECT_TIMEOUT);
                Log.d(TAG, "AudioOn: removed CONNECT_TIMEOUT for device=" + pendingDevice);
            }
        }

        // in AudioOn state
        private void processAudioEvent(int state, BluetoothDevice device) {
            if (!mConnectedDevicesList.contains(device)) {
                Log.e(TAG, "Audio changed on disconnected device: " + device);
                return;
            }

            switch (state) {
                case HeadsetHalConstants.AUDIO_STATE_DISCONNECTED:
                    if (mAudioState != BluetoothHeadset.STATE_AUDIO_DISCONNECTED) {
                        mAudioState = BluetoothHeadset.STATE_AUDIO_DISCONNECTED;
                        if (device.equals(mActiveScoDevice)) {
                            mActiveScoDevice = null;
                        }
                        mAudioManager.setBluetoothScoOn(false);
                        broadcastAudioState(device, BluetoothHeadset.STATE_AUDIO_DISCONNECTED,
                                BluetoothHeadset.STATE_AUDIO_CONNECTED);
                    }
                    transitionTo(mConnected);
                    break;
                case HeadsetHalConstants.AUDIO_STATE_DISCONNECTING:
                    // TODO(BT) adding STATE_AUDIO_DISCONNECTING in BluetoothHeadset?
                    // broadcastAudioState(device, BluetoothHeadset.STATE_AUDIO_DISCONNECTING,
                    //                    BluetoothHeadset.STATE_AUDIO_CONNECTED);
                    break;
                default:
                    Log.e(TAG, "Audio State Device: " + device + " bad state: " + state);
                    break;
            }
        }

        private void processIntentScoVolume(Intent intent, BluetoothDevice device) {
            int volumeValue = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, 0);
            if (mPhoneState.getSpeakerVolume() != volumeValue) {
                mPhoneState.setSpeakerVolume(volumeValue);
                setVolumeNative(
                        HeadsetHalConstants.VOLUME_TYPE_SPK, volumeValue, getByteAddress(device));
            }
        }

        private void processMultiHFConnected(BluetoothDevice device) {
            log("AudioOn state: processMultiHFConnected");
            /* Assign the current activedevice again if the disconnected
                          device equals to the current active device */
            if (mCurrentDevice != null && mCurrentDevice.equals(device)) {
                int deviceSize = mConnectedDevicesList.size();
                mCurrentDevice = mConnectedDevicesList.get(deviceSize - 1);
            }
            if (mAudioState != BluetoothHeadset.STATE_AUDIO_CONNECTED) transitionTo(mConnected);

            log("processMultiHFConnected , the latest mCurrentDevice is:" + mCurrentDevice);
            log("AudioOn state: processMultiHFConnected ,"
                    + "fake broadcasting for mCurrentDevice");
            broadcastConnectionState(mCurrentDevice, BluetoothProfile.STATE_CONNECTED,
                    BluetoothProfile.STATE_DISCONNECTED);
        }
    }

    /* Add MultiHFPending state when atleast 1 HS is connected
            and disconnect/connect new HS */
    private class MultiHFPending extends State {
        @Override
        public void enter() {
            log("Enter MultiHFPending: " + getCurrentMessage().what + ", size: "
                    + mConnectedDevicesList.size());
        }

        @Override
        public boolean processMessage(Message message) {
            log("MultiHFPending process message: " + message.what + ", size: "
                    + mConnectedDevicesList.size());

            switch (message.what) {
                case CONNECT:
                    deferMessage(message);
                    break;

                case CONNECT_AUDIO:
                    if (mCurrentDevice != null) {
                        connectAudioNative(getByteAddress(mCurrentDevice));
                    }
                    break;
                case CONNECT_TIMEOUT:
                    onConnectionStateChanged(HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED,
                            getByteAddress(mTargetDevice));
                    break;

                case DISCONNECT_AUDIO:
                    if (mActiveScoDevice != null) {
                        if (disconnectAudioNative(getByteAddress(mActiveScoDevice))) {
                            Log.d(TAG, "MultiHFPending, Disconnecting SCO audio for "
                                            + mActiveScoDevice);
                        } else {
                            Log.e(TAG, "disconnectAudioNative failed"
                                            + "for device = " + mActiveScoDevice);
                        }
                    }
                    break;
                case DISCONNECT:
                    BluetoothDevice device = (BluetoothDevice) message.obj;
                    Log.d(TAG, "MultiPending: DISCONNECT, device=" + device);
                    if (mConnectedDevicesList.contains(device) && mTargetDevice != null
                            && mTargetDevice.equals(device)) {
                        // cancel connection to the mTargetDevice
                        broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED,
                                BluetoothProfile.STATE_CONNECTING);
                        synchronized (HeadsetStateMachine.this) {
                            mTargetDevice = null;
                        }
                    } else {
                        deferMessage(message);
                    }
                    break;
                case VOICE_RECOGNITION_START:
                    device = (BluetoothDevice) message.obj;
                    if (mConnectedDevicesList.contains(device)) {
                        processLocalVrEvent(HeadsetHalConstants.VR_STATE_STARTED);
                    }
                    break;
                case VOICE_RECOGNITION_STOP:
                    device = (BluetoothDevice) message.obj;
                    if (mConnectedDevicesList.contains(device)) {
                        processLocalVrEvent(HeadsetHalConstants.VR_STATE_STOPPED);
                    }
                    break;
                case INTENT_SCO_VOLUME_CHANGED:
                    if (mActiveScoDevice != null) {
                        processIntentScoVolume((Intent) message.obj, mActiveScoDevice);
                    }
                    break;
                case INTENT_BATTERY_CHANGED:
                    processIntentBatteryChanged((Intent) message.obj);
                    break;
                case CALL_STATE_CHANGED:
                    processCallState((HeadsetCallState) message.obj, message.arg1 == 1);
                    break;
                case DEVICE_STATE_CHANGED:
                    processDeviceStateChanged((HeadsetDeviceState) message.obj);
                    break;
                case SEND_CCLC_RESPONSE:
                    processSendClccResponse((HeadsetClccResponse) message.obj);
                    break;
                case CLCC_RSP_TIMEOUT: {
                    device = (BluetoothDevice) message.obj;
                    clccResponseNative(0, 0, 0, 0, false, "", 0, getByteAddress(device));
                } break;
                case DIALING_OUT_TIMEOUT:
                    if (mDialingOut) {
                        device = (BluetoothDevice) message.obj;
                        mDialingOut = false;
                        atResponseCodeNative(
                                HeadsetHalConstants.AT_RESPONSE_ERROR, 0, getByteAddress(device));
                    }
                    break;
                case VIRTUAL_CALL_START:
                    device = (BluetoothDevice) message.obj;
                    if (mConnectedDevicesList.contains(device)) {
                        initiateScoUsingVirtualVoiceCall();
                    }
                    break;
                case VIRTUAL_CALL_STOP:
                    device = (BluetoothDevice) message.obj;
                    if (mConnectedDevicesList.contains(device)) {
                        terminateScoUsingVirtualVoiceCall();
                    }
                    break;
                case START_VR_TIMEOUT:
                    if (mWaitingForVoiceRecognition) {
                        device = (BluetoothDevice) message.obj;
                        mWaitingForVoiceRecognition = false;
                        Log.e(TAG, "Timeout waiting for voice"
                                        + "recognition to start");
                        atResponseCodeNative(
                                HeadsetHalConstants.AT_RESPONSE_ERROR, 0, getByteAddress(device));
                    }
                    break;
                case STACK_EVENT:
                    StackEvent event = (StackEvent) message.obj;
                    log("MultiHFPending: event type: " + event.type);
                    switch (event.type) {
                        case EVENT_TYPE_CONNECTION_STATE_CHANGED:
                            processConnectionEvent(event.valueInt, event.device);
                            break;
                        case EVENT_TYPE_AUDIO_STATE_CHANGED:
                            processAudioEvent(event.valueInt, event.device);
                            break;
                        case EVENT_TYPE_VR_STATE_CHANGED:
                            processVrEvent(event.valueInt, event.device);
                            break;
                        case EVENT_TYPE_ANSWER_CALL:
                            // TODO(BT) could answer call happen on Connected state?
                            processAnswerCall(event.device);
                            break;
                        case EVENT_TYPE_HANGUP_CALL:
                            // TODO(BT) could hangup call happen on Connected state?
                            processHangupCall(event.device);
                            break;
                        case EVENT_TYPE_VOLUME_CHANGED:
                            processVolumeEvent(event.valueInt, event.valueInt2, event.device);
                            break;
                        case EVENT_TYPE_DIAL_CALL:
                            processDialCall(event.valueString, event.device);
                            break;
                        case EVENT_TYPE_SEND_DTMF:
                            processSendDtmf(event.valueInt, event.device);
                            break;
                        case EVENT_TYPE_NOICE_REDUCTION:
                            processNoiceReductionEvent(event.valueInt, event.device);
                            break;
                        case EVENT_TYPE_SUBSCRIBER_NUMBER_REQUEST:
                            processSubscriberNumberRequest(event.device);
                            break;
                        case EVENT_TYPE_AT_CIND:
                            processAtCind(event.device);
                            break;
                        case EVENT_TYPE_AT_CHLD:
                            processAtChld(event.valueInt, event.device);
                            break;
                        case EVENT_TYPE_AT_COPS:
                            processAtCops(event.device);
                            break;
                        case EVENT_TYPE_AT_CLCC:
                            processAtClcc(event.device);
                            break;
                        case EVENT_TYPE_UNKNOWN_AT:
                            processUnknownAt(event.valueString, event.device);
                            break;
                        case EVENT_TYPE_KEY_PRESSED:
                            processKeyPressed(event.device);
                            break;
                        case EVENT_TYPE_BIND:
                            processAtBind(event.valueString, event.device);
                            break;
                        case EVENT_TYPE_BIEV:
                            processAtBiev(event.valueInt, event.valueInt2, event.device);
                            break;
                        default:
                            Log.e(TAG, "MultiHFPending: Unexpected event: " + event.type);
                            break;
                    }
                    break;
                default:
                    Log.e(TAG, "MultiHFPending: unexpected message " + message.what);
                    return NOT_HANDLED;
            }
            return HANDLED;
        }

        // in MultiHFPending state
        private void processConnectionEvent(int state, BluetoothDevice device) {
            Log.d(TAG,
                    "MultiPending: processConnectionEvent, state=" + state + ", device=" + device);
            BluetoothDevice pendingDevice = getDeviceForMessage(CONNECT_TIMEOUT);
            switch (state) {
                case HeadsetHalConstants.CONNECTION_STATE_DISCONNECTED:
                    if (mConnectedDevicesList.contains(device)) {
                        if (mMultiDisconnectDevice != null
                                && mMultiDisconnectDevice.equals(device)) {
                            mMultiDisconnectDevice = null;

                            synchronized (HeadsetStateMachine.this) {
                                mConnectedDevicesList.remove(device);
                                mHeadsetAudioParam.remove(device);
                                mHeadsetBrsf.remove(device);
                                Log.d(TAG, "MultiHFPending: removed device=" + device);
                                broadcastConnectionState(device,
                                        BluetoothProfile.STATE_DISCONNECTED,
                                        BluetoothProfile.STATE_DISCONNECTING);
                            }

                            if (mTargetDevice != null) {
                                if (!connectHfpNative(getByteAddress(mTargetDevice))) {
                                    broadcastConnectionState(mTargetDevice,
                                            BluetoothProfile.STATE_DISCONNECTED,
                                            BluetoothProfile.STATE_CONNECTING);
                                    synchronized (HeadsetStateMachine.this) {
                                        mTargetDevice = null;
                                        if (mConnectedDevicesList.size() == 0) {
                                            // Should be not in this state since it has at least
                                            // one HF connected in MultiHFPending state
                                            Log.w(TAG, "MultiHFPending: should not be here");
                                            transitionTo(mDisconnected);
                                        } else {
                                            processMultiHFConnected(device);
                                        }
                                    }
                                }
                            } else {
                                synchronized (HeadsetStateMachine.this) {
                                    mIncomingDevice = null;
                                    if (mConnectedDevicesList.size() == 0) {
                                        transitionTo(mDisconnected);
                                    } else {
                                        processMultiHFConnected(device);
                                    }
                                }
                            }
                        } else {
                            /* Another HF disconnected when one HF is connecting */
                            synchronized (HeadsetStateMachine.this) {
                                mConnectedDevicesList.remove(device);
                                mHeadsetAudioParam.remove(device);
                                mHeadsetBrsf.remove(device);
                                Log.d(TAG, "device " + device.getAddress()
                                                + " is removed in MultiHFPending state");
                            }
                            broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED,
                                    BluetoothProfile.STATE_CONNECTED);
                        }
                    } else if (mTargetDevice != null && mTargetDevice.equals(device)) {
                        broadcastConnectionState(mTargetDevice, BluetoothProfile.STATE_DISCONNECTED,
                                BluetoothProfile.STATE_CONNECTING);
                        synchronized (HeadsetStateMachine.this) {
                            mTargetDevice = null;
                            if (mConnectedDevicesList.size() == 0) {
                                transitionTo(mDisconnected);
                            } else {
                                if (mAudioState == BluetoothHeadset.STATE_AUDIO_CONNECTED)
                                    transitionTo(mAudioOn);
                                else
                                    transitionTo(mConnected);
                            }
                        }
                    } else {
                        Log.e(TAG, "Unknown device Disconnected: " + device);
                    }
                    break;
                case HeadsetHalConstants.CONNECTION_STATE_CONNECTED:
                    if (mConnectedDevicesList.contains(device)) {
                        // Disconnection failure does not go through SLC establishment
                        Log.w(TAG, "MultiPending: disconnection failed for device " + device);
                        broadcastConnectionState(device, BluetoothProfile.STATE_CONNECTED,
                                BluetoothProfile.STATE_DISCONNECTING);
                        if (mTargetDevice != null) {
                            broadcastConnectionState(mTargetDevice,
                                    BluetoothProfile.STATE_DISCONNECTED,
                                    BluetoothProfile.STATE_CONNECTING);
                        }
                        synchronized (HeadsetStateMachine.this) {
                            mTargetDevice = null;
                            if (mAudioState == BluetoothHeadset.STATE_AUDIO_CONNECTED)
                                transitionTo(mAudioOn);
                            else
                                transitionTo(mConnected);
                        }
                    } else if (!device.equals(mTargetDevice)) {
                        Log.w(TAG,
                                "MultiPending: unknown incoming HF connected on RFCOMM"
                                        + ", device=" + device);
                        if (!okToConnect(device)
                                || (mConnectedDevicesList.size() >= max_hf_connections)) {
                            // reject the connection and stay in Pending state itself
                            Log.i(TAG,
                                    "MultiPending: unknown incoming HF rejected on RFCOMM"
                                            + ", priority=" + mService.getPriority(device)
                                            + ", bondState=" + device.getBondState());
                            disconnectHfpNative(getByteAddress(device));
                        } else {
                            // Ok to connect, keep waiting for SLC connected event
                            pendingDevice = null;
                        }
                    } else {
                        // Do nothing in normal case, keep waiting for SLC connected event
                        pendingDevice = null;
                    }
                    break;
                case HeadsetHalConstants.CONNECTION_STATE_SLC_CONNECTED:
                    int previousConnectionState = BluetoothProfile.STATE_CONNECTING;
                    synchronized (HeadsetStateMachine.this) {
                        mCurrentDevice = device;
                        mConnectedDevicesList.add(device);
                        if (device.equals(mTargetDevice)) {
                            Log.d(TAG,
                                    "MultiPending: added " + device
                                            + " to mConnectedDevicesList, requested by us");
                            mTargetDevice = null;
                            if (mAudioState == BluetoothHeadset.STATE_AUDIO_CONNECTED)
                                transitionTo(mAudioOn);
                            else
                                transitionTo(mConnected);
                        } else {
                            Log.d(TAG,
                                    "MultiPending: added " + device
                                            + "to mConnectedDevicesList, unknown source");
                            previousConnectionState = BluetoothProfile.STATE_DISCONNECTED;
                        }
                    }
                    configAudioParameters(device);
                    queryPhoneState();
                    broadcastConnectionState(
                            device, BluetoothProfile.STATE_CONNECTED, previousConnectionState);
                    break;
                case HeadsetHalConstants.CONNECTION_STATE_CONNECTING:
                    if (mConnectedDevicesList.contains(device)) {
                        Log.e(TAG, "MultiPending: current device tries to connect back");
                    } else if (mTargetDevice != null && mTargetDevice.equals(device)) {
                        log("Stack and target device are connecting");
                    } else if (mIncomingDevice != null && mIncomingDevice.equals(device)) {
                        Log.e(TAG, "MultiPending: Another connecting event on the incoming device");
                    }
                    break;
                case HeadsetHalConstants.CONNECTION_STATE_DISCONNECTING:
                    if (mConnectedDevicesList.contains(device)) {
                        log("stack is disconnecting mCurrentDevice");
                    } else if (mTargetDevice != null && mTargetDevice.equals(device)) {
                        Log.e(TAG, "MultiPending: TargetDevice is getting disconnected");
                    } else if (mIncomingDevice != null && mIncomingDevice.equals(device)) {
                        Log.e(TAG, "MultiPending: IncomingDevice is getting disconnected");
                    } else {
                        Log.e(TAG, "MultiPending: Disconnecting unknow device: " + device);
                    }
                    break;
                default:
                    Log.e(TAG, "MultiPending: Incorrect state: " + state);
                    break;
            }
            if (pendingDevice != null && pendingDevice.equals(device)) {
                removeMessages(CONNECT_TIMEOUT);
                Log.d(TAG, "MultiPending: removed CONNECT_TIMEOUT for device=" + pendingDevice);
            }
        }

        private void processAudioEvent(int state, BluetoothDevice device) {
            if (!mConnectedDevicesList.contains(device)) {
                Log.e(TAG, "MultiPending: Audio changed on disconnected device: " + device);
                return;
            }

            switch (state) {
                case HeadsetHalConstants.AUDIO_STATE_CONNECTED:
                    if (!isScoAcceptable()) {
                        Log.e(TAG, "MultiPending: Audio Connected without any listener");
                        disconnectAudioNative(getByteAddress(device));
                        break;
                    }
                    mAudioState = BluetoothHeadset.STATE_AUDIO_CONNECTED;
                    setAudioParameters(device); /* Set proper Audio Parameters. */
                    mAudioManager.setBluetoothScoOn(true);
                    mActiveScoDevice = device;
                    broadcastAudioState(device, BluetoothHeadset.STATE_AUDIO_CONNECTED,
                            BluetoothHeadset.STATE_AUDIO_CONNECTING);
                    /* The state should be still in MultiHFPending state when
                       audio connected since other device is still connecting/
                       disconnecting */
                    break;
                case HeadsetHalConstants.AUDIO_STATE_CONNECTING:
                    mAudioState = BluetoothHeadset.STATE_AUDIO_CONNECTING;
                    broadcastAudioState(device, BluetoothHeadset.STATE_AUDIO_CONNECTING,
                            BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
                    break;
                case HeadsetHalConstants.AUDIO_STATE_DISCONNECTED:
                    if (mAudioState != BluetoothHeadset.STATE_AUDIO_DISCONNECTED) {
                        mAudioState = BluetoothHeadset.STATE_AUDIO_DISCONNECTED;
                        if (device.equals(mActiveScoDevice)) {
                            mActiveScoDevice = null;
                        }
                        mAudioManager.setBluetoothScoOn(false);
                        broadcastAudioState(device, BluetoothHeadset.STATE_AUDIO_DISCONNECTED,
                                BluetoothHeadset.STATE_AUDIO_CONNECTED);
                    }
                    /* The state should be still in MultiHFPending state when audio
                       disconnected since other device is still connecting/
                       disconnecting */
                    break;

                default:
                    Log.e(TAG,
                            "MultiPending: Audio State Device: " + device + " bad state: " + state);
                    break;
            }
        }

        private void processMultiHFConnected(BluetoothDevice device) {
            log("MultiHFPending: processMultiHFConnected, device=" + device);
            if (mActiveScoDevice != null && mActiveScoDevice.equals(device)) {
                log("mActiveScoDevice is disconnected, setting it to null");
                mActiveScoDevice = null;
            }
            /* Assign the current activedevice again if the disconnected
               device equals to the current active device */
            if (mCurrentDevice != null && mCurrentDevice.equals(device)) {
                int deviceSize = mConnectedDevicesList.size();
                mCurrentDevice = mConnectedDevicesList.get(deviceSize - 1);
            }
            // The disconnected device is not current active device
            if (mAudioState == BluetoothHeadset.STATE_AUDIO_CONNECTED)
                transitionTo(mAudioOn);
            else
                transitionTo(mConnected);
            log("processMultiHFConnected , the latest mCurrentDevice is:" + mCurrentDevice);
            log("MultiHFPending state: processMultiHFConnected ,"
                    + "fake broadcasting for mCurrentDevice");
            broadcastConnectionState(mCurrentDevice, BluetoothProfile.STATE_CONNECTED,
                    BluetoothProfile.STATE_DISCONNECTED);
        }

        private void processIntentScoVolume(Intent intent, BluetoothDevice device) {
            int volumeValue = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, 0);
            if (mPhoneState.getSpeakerVolume() != volumeValue) {
                mPhoneState.setSpeakerVolume(volumeValue);
                setVolumeNative(
                        HeadsetHalConstants.VOLUME_TYPE_SPK, volumeValue, getByteAddress(device));
            }
        }
    }

    private final ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            if (DBG) Log.d(TAG, "Proxy object connected");
            mPhoneProxy = IBluetoothHeadsetPhone.Stub.asInterface(service);
        }

        public void onServiceDisconnected(ComponentName className) {
            if (DBG) Log.d(TAG, "Proxy object disconnected");
            mPhoneProxy = null;
        }
    };

    // HFP Connection state of the device could be changed by the state machine
    // in separate thread while this method is executing.
    int getConnectionState(BluetoothDevice device) {
        if (getCurrentState() == mDisconnected) {
            if (DBG) Log.d(TAG, "currentState is Disconnected");
            return BluetoothProfile.STATE_DISCONNECTED;
        }

        synchronized (this) {
            IState currentState = getCurrentState();
            if (DBG) Log.d(TAG, "currentState = " + currentState);
            if (currentState == mPending) {
                if ((mTargetDevice != null) && mTargetDevice.equals(device)) {
                    return BluetoothProfile.STATE_CONNECTING;
                }
                if (mConnectedDevicesList.contains(device)) {
                    return BluetoothProfile.STATE_DISCONNECTING;
                }
                if ((mIncomingDevice != null) && mIncomingDevice.equals(device)) {
                    return BluetoothProfile.STATE_CONNECTING; // incoming connection
                }
                return BluetoothProfile.STATE_DISCONNECTED;
            }

            if (currentState == mMultiHFPending) {
                if ((mTargetDevice != null) && mTargetDevice.equals(device)) {
                    return BluetoothProfile.STATE_CONNECTING;
                }
                if ((mIncomingDevice != null) && mIncomingDevice.equals(device)) {
                    return BluetoothProfile.STATE_CONNECTING; // incoming connection
                }
                if (mConnectedDevicesList.contains(device)) {
                    if ((mMultiDisconnectDevice != null)
                            && (!mMultiDisconnectDevice.equals(device))) {
                        // The device is still connected
                        return BluetoothProfile.STATE_CONNECTED;
                    }
                    return BluetoothProfile.STATE_DISCONNECTING;
                }
                return BluetoothProfile.STATE_DISCONNECTED;
            }

            if (currentState == mConnected || currentState == mAudioOn) {
                if (mConnectedDevicesList.contains(device)) {
                    return BluetoothProfile.STATE_CONNECTED;
                }
                return BluetoothProfile.STATE_DISCONNECTED;
            } else {
                Log.e(TAG, "Bad currentState: " + currentState);
                return BluetoothProfile.STATE_DISCONNECTED;
            }
        }
    }

    List<BluetoothDevice> getConnectedDevices() {
        List<BluetoothDevice> devices = new ArrayList<BluetoothDevice>();
        synchronized (this) {
            devices.addAll(mConnectedDevicesList);
        }
        return devices;
    }

    boolean isAudioOn() {
        return (getCurrentState() == mAudioOn);
    }

    boolean isAudioConnected(BluetoothDevice device) {
        synchronized (this) {
            /*  Additional check for audio state included for the case when PhoneApp queries
            Bluetooth Audio state, before we receive the close event from the stack for the
            sco disconnect issued in AudioOn state. This was causing a mismatch in the
            Incall screen UI. */

            if (mActiveScoDevice != null && mActiveScoDevice.equals(device)
                    && mAudioState != BluetoothHeadset.STATE_AUDIO_DISCONNECTED) {
                return true;
            }
        }
        return false;
    }

    public void setAudioRouteAllowed(boolean allowed) {
        mAudioRouteAllowed = allowed;
        setScoAllowedNative(allowed);
    }

    public boolean getAudioRouteAllowed() {
        return mAudioRouteAllowed;
    }

    public void setForceScoAudio(boolean forced) {
        mForceScoAudio = forced;
    }

    int getAudioState(BluetoothDevice device) {
        synchronized (this) {
            if (mConnectedDevicesList.size() == 0) {
                return BluetoothHeadset.STATE_AUDIO_DISCONNECTED;
            }
        }
        return mAudioState;
    }

    private void processVrEvent(int state, BluetoothDevice device) {
        if (device == null) {
            Log.w(TAG, "processVrEvent device is null");
            return;
        }
        Log.d(TAG, "processVrEvent: state=" + state + " mVoiceRecognitionStarted: "
                        + mVoiceRecognitionStarted + " mWaitingforVoiceRecognition: "
                        + mWaitingForVoiceRecognition + " isInCall: " + isInCall());
        if (state == HeadsetHalConstants.VR_STATE_STARTED) {
            if (!isVirtualCallInProgress() && !isInCall()) {
                IDeviceIdleController dic = IDeviceIdleController.Stub.asInterface(
                        ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER));
                if (dic != null) {
                    try {
                        dic.exitIdle("voice-command");
                    } catch (RemoteException e) {
                    }
                }
                try {
                    mService.startActivity(sVoiceCommandIntent);
                } catch (ActivityNotFoundException e) {
                    atResponseCodeNative(
                            HeadsetHalConstants.AT_RESPONSE_ERROR, 0, getByteAddress(device));
                    return;
                }
                expectVoiceRecognition(device);
            } else {
                // send error response if call is ongoing
                atResponseCodeNative(
                        HeadsetHalConstants.AT_RESPONSE_ERROR, 0, getByteAddress(device));
                return;
            }
        } else if (state == HeadsetHalConstants.VR_STATE_STOPPED) {
            if (mVoiceRecognitionStarted || mWaitingForVoiceRecognition) {
                atResponseCodeNative(HeadsetHalConstants.AT_RESPONSE_OK, 0, getByteAddress(device));
                mVoiceRecognitionStarted = false;
                mWaitingForVoiceRecognition = false;
                if (!isInCall() && (mActiveScoDevice != null)) {
                    disconnectAudioNative(getByteAddress(mActiveScoDevice));
                    mAudioManager.setParameters("A2dpSuspended=false");
                }
            } else {
                atResponseCodeNative(
                        HeadsetHalConstants.AT_RESPONSE_ERROR, 0, getByteAddress(device));
            }
        } else {
            Log.e(TAG, "Bad Voice Recognition state: " + state);
        }
    }

    private void processLocalVrEvent(int state) {
        BluetoothDevice device = null;
        if (state == HeadsetHalConstants.VR_STATE_STARTED) {
            boolean needAudio = true;
            if (mVoiceRecognitionStarted || isInCall()) {
                Log.e(TAG, "Voice recognition started when call is active. isInCall:" + isInCall()
                                + " mVoiceRecognitionStarted: " + mVoiceRecognitionStarted);
                return;
            }
            mVoiceRecognitionStarted = true;

            if (mWaitingForVoiceRecognition) {
                device = getDeviceForMessage(START_VR_TIMEOUT);
                if (device == null) return;

                Log.d(TAG, "Voice recognition started successfully");
                mWaitingForVoiceRecognition = false;
                atResponseCodeNative(HeadsetHalConstants.AT_RESPONSE_OK, 0, getByteAddress(device));
                removeMessages(START_VR_TIMEOUT);
            } else {
                Log.d(TAG, "Voice recognition started locally");
                needAudio = startVoiceRecognitionNative(getByteAddress(mCurrentDevice));
                if (mCurrentDevice != null) device = mCurrentDevice;
            }

            if (needAudio && !isAudioOn()) {
                Log.d(TAG, "Initiating audio connection for Voice Recognition");
                // At this stage, we need to be sure that AVDTP is not streaming. This is needed
                // to be compliant with the AV+HFP Whitepaper as we cannot have A2DP in
                // streaming state while a SCO connection is established.
                // This is needed for VoiceDial scenario alone and not for
                // incoming call/outgoing call scenarios as the phone enters MODE_RINGTONE
                // or MODE_IN_CALL which shall automatically suspend the AVDTP stream if needed.
                // Whereas for VoiceDial we want to activate the SCO connection but we are still
                // in MODE_NORMAL and hence the need to explicitly suspend the A2DP stream
                mAudioManager.setParameters("A2dpSuspended=true");
                if (device != null) {
                    connectAudioNative(getByteAddress(device));
                } else {
                    Log.e(TAG, "device not found for VR");
                }
            }

            if (mStartVoiceRecognitionWakeLock.isHeld()) {
                mStartVoiceRecognitionWakeLock.release();
            }
        } else {
            Log.d(TAG, "Voice Recognition stopped. mVoiceRecognitionStarted: "
                            + mVoiceRecognitionStarted + " mWaitingForVoiceRecognition: "
                            + mWaitingForVoiceRecognition);
            if (mVoiceRecognitionStarted || mWaitingForVoiceRecognition) {
                mVoiceRecognitionStarted = false;
                mWaitingForVoiceRecognition = false;

                if (stopVoiceRecognitionNative(getByteAddress(mCurrentDevice)) && !isInCall()
                        && mActiveScoDevice != null) {
                    disconnectAudioNative(getByteAddress(mActiveScoDevice));
                    mAudioManager.setParameters("A2dpSuspended=false");
                }
            }
        }
    }

    private synchronized void expectVoiceRecognition(BluetoothDevice device) {
        mWaitingForVoiceRecognition = true;
        Message m = obtainMessage(START_VR_TIMEOUT);
        m.obj = getMatchingDevice(device);
        sendMessageDelayed(m, START_VR_TIMEOUT_VALUE);

        if (!mStartVoiceRecognitionWakeLock.isHeld()) {
            mStartVoiceRecognitionWakeLock.acquire(START_VR_TIMEOUT_VALUE);
        }
    }

    List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
        List<BluetoothDevice> deviceList = new ArrayList<BluetoothDevice>();
        Set<BluetoothDevice> bondedDevices = mAdapter.getBondedDevices();
        int connectionState;
        synchronized (this) {
            for (BluetoothDevice device : bondedDevices) {
                ParcelUuid[] featureUuids = device.getUuids();
                if (!BluetoothUuid.containsAnyUuid(featureUuids, HEADSET_UUIDS)) {
                    continue;
                }
                connectionState = getConnectionState(device);
                for (int i = 0; i < states.length; i++) {
                    if (connectionState == states[i]) {
                        deviceList.add(device);
                    }
                }
            }
        }
        return deviceList;
    }

    private BluetoothDevice getDeviceForMessage(int what) {
        if (what == CONNECT_TIMEOUT) {
            log("getDeviceForMessage: returning mTargetDevice for what=" + what);
            return mTargetDevice;
        }
        if (mConnectedDevicesList.size() == 0) {
            log("getDeviceForMessage: No connected device. what=" + what);
            return null;
        }
        for (BluetoothDevice device : mConnectedDevicesList) {
            if (getHandler().hasMessages(what, device)) {
                log("getDeviceForMessage: returning " + device);
                return device;
            }
        }
        log("getDeviceForMessage: No matching device for " + what + ". Returning null");
        return null;
    }

    private BluetoothDevice getMatchingDevice(BluetoothDevice device) {
        for (BluetoothDevice matchingDevice : mConnectedDevicesList) {
            if (matchingDevice.equals(device)) {
                return matchingDevice;
            }
        }
        return null;
    }

    // This method does not check for error conditon (newState == prevState)
    private void broadcastConnectionState(BluetoothDevice device, int newState, int prevState) {
        log("Connection state " + device + ": " + prevState + "->" + newState);
        if (prevState == BluetoothProfile.STATE_CONNECTED) {
            // Headset is disconnecting, stop Virtual call if active.
            terminateScoUsingVirtualVoiceCall();
        }

        Intent intent = new Intent(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
        intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState);
        intent.putExtra(BluetoothProfile.EXTRA_STATE, newState);
        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
        intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
        mService.sendBroadcastAsUser(intent, UserHandle.ALL,
                HeadsetService.BLUETOOTH_PERM);
    }

    private void broadcastAudioState(BluetoothDevice device, int newState, int prevState) {
        if (prevState == BluetoothHeadset.STATE_AUDIO_CONNECTED) {
            // When SCO gets disconnected during call transfer, Virtual call
            // needs to be cleaned up.So call terminateScoUsingVirtualVoiceCall.
            terminateScoUsingVirtualVoiceCall();
        }
        Intent intent = new Intent(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
        intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState);
        intent.putExtra(BluetoothProfile.EXTRA_STATE, newState);
        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
        mService.sendBroadcastAsUser(intent, UserHandle.ALL, HeadsetService.BLUETOOTH_PERM);
        log("Audio state " + device + ": " + prevState + "->" + newState);
    }

    /*
     * Put the AT command, company ID, arguments, and device in an Intent and broadcast it.
     */
    private void broadcastVendorSpecificEventIntent(String command, int companyId, int commandType,
            Object[] arguments, BluetoothDevice device) {
        log("broadcastVendorSpecificEventIntent(" + command + ")");
        Intent intent = new Intent(BluetoothHeadset.ACTION_VENDOR_SPECIFIC_HEADSET_EVENT);
        intent.putExtra(BluetoothHeadset.EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD, command);
        intent.putExtra(BluetoothHeadset.EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE, commandType);
        // assert: all elements of args are Serializable
        intent.putExtra(BluetoothHeadset.EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS, arguments);
        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);

        intent.addCategory(BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY + "."
                + Integer.toString(companyId));

        mService.sendBroadcastAsUser(intent, UserHandle.ALL, HeadsetService.BLUETOOTH_PERM);
    }

    private void configAudioParameters(BluetoothDevice device) {
        // Reset NREC on connect event. Headset will override later
        HashMap<String, Integer> AudioParamConfig = new HashMap<String, Integer>();
        AudioParamConfig.put("NREC", 1);
        mHeadsetAudioParam.put(device, AudioParamConfig);
        mAudioManager.setParameters(
                HEADSET_NAME + "=" + getCurrentDeviceName(device) + ";" + HEADSET_NREC + "=on");
        Log.d(TAG, "configAudioParameters for device:" + device + " are: nrec = "
                        + AudioParamConfig.get("NREC"));
    }

    private void setAudioParameters(BluetoothDevice device) {
        // 1. update nrec value
        // 2. update headset name
        int mNrec = 0;
        HashMap<String, Integer> AudioParam = mHeadsetAudioParam.get(device);
        if (AudioParam != null && !AudioParam.isEmpty()) {
            mNrec = AudioParam.get("NREC");
        } else {
            Log.e(TAG, "setAudioParameters: AudioParam not found");
        }

        if (mNrec == 1) {
            Log.d(TAG, "Set NREC: 1 for device:" + device);
            mAudioManager.setParameters(HEADSET_NREC + "=on");
        } else {
            Log.d(TAG, "Set NREC: 0 for device:" + device);
            mAudioManager.setParameters(HEADSET_NREC + "=off");
        }
        mAudioManager.setParameters(HEADSET_NAME + "=" + getCurrentDeviceName(device));
    }

    private String parseUnknownAt(String atString) {
        StringBuilder atCommand = new StringBuilder(atString.length());
        String result = null;

        for (int i = 0; i < atString.length(); i++) {
            char c = atString.charAt(i);
            if (c == '"') {
                int j = atString.indexOf('"', i + 1); // search for closing "
                if (j == -1) { // unmatched ", insert one.
                    atCommand.append(atString.substring(i, atString.length()));
                    atCommand.append('"');
                    break;
                }
                atCommand.append(atString.substring(i, j + 1));
                i = j;
            } else if (c != ' ') {
                atCommand.append(Character.toUpperCase(c));
            }
        }
        result = atCommand.toString();
        return result;
    }

    private int getAtCommandType(String atCommand) {
        int commandType = mPhonebook.TYPE_UNKNOWN;
        String atString = null;
        atCommand = atCommand.trim();
        if (atCommand.length() > 5) {
            atString = atCommand.substring(5);
            if (atString.startsWith("?")) // Read
                commandType = mPhonebook.TYPE_READ;
            else if (atString.startsWith("=?")) // Test
                commandType = mPhonebook.TYPE_TEST;
            else if (atString.startsWith("=")) // Set
                commandType = mPhonebook.TYPE_SET;
            else
                commandType = mPhonebook.TYPE_UNKNOWN;
        }
        return commandType;
    }

    /* Method to check if Virtual Call in Progress */
    private boolean isVirtualCallInProgress() {
        return mVirtualCallStarted;
    }

    void setVirtualCallInProgress(boolean state) {
        mVirtualCallStarted = state;
    }

    /* NOTE: Currently the VirtualCall API does not support handling of
    call transfers. If it is initiated from the handsfree device,
    HeadsetStateMachine will end the virtual call by calling
    terminateScoUsingVirtualVoiceCall() in broadcastAudioState() */
    synchronized boolean initiateScoUsingVirtualVoiceCall() {
        log("initiateScoUsingVirtualVoiceCall: Received");
        // 1. Check if the SCO state is idle
        if (isInCall() || mVoiceRecognitionStarted) {
            Log.e(TAG, "initiateScoUsingVirtualVoiceCall: Call in progress.");
            return false;
        }

        // 2. Send virtual phone state changed to initialize SCO
        processCallState(
                new HeadsetCallState(0, 0, HeadsetHalConstants.CALL_STATE_DIALING, "", 0), true);
        processCallState(
                new HeadsetCallState(0, 0, HeadsetHalConstants.CALL_STATE_ALERTING, "", 0), true);
        processCallState(
                new HeadsetCallState(1, 0, HeadsetHalConstants.CALL_STATE_IDLE, "", 0), true);
        setVirtualCallInProgress(true);
        // Done
        log("initiateScoUsingVirtualVoiceCall: Done");
        return true;
    }

    synchronized boolean terminateScoUsingVirtualVoiceCall() {
        log("terminateScoUsingVirtualVoiceCall: Received");

        if (!isVirtualCallInProgress()) {
            Log.w(TAG, "terminateScoUsingVirtualVoiceCall: No present call to terminate");
            return false;
        }

        // 2. Send virtual phone state changed to close SCO
        processCallState(
                new HeadsetCallState(0, 0, HeadsetHalConstants.CALL_STATE_IDLE, "", 0), true);
        setVirtualCallInProgress(false);
        // Done
        log("terminateScoUsingVirtualVoiceCall: Done");
        return true;
    }

    private void processAnswerCall(BluetoothDevice device) {
        if (device == null) {
            Log.w(TAG, "processAnswerCall device is null");
            return;
        }

        if (mPhoneProxy != null) {
            try {
                mPhoneProxy.answerCall();
            } catch (RemoteException e) {
                Log.e(TAG, Log.getStackTraceString(new Throwable()));
            }
        } else {
            Log.e(TAG, "Handsfree phone proxy null for answering call");
        }
    }

    private void processHangupCall(BluetoothDevice device) {
        if (device == null) {
            Log.w(TAG, "processHangupCall device is null");
            return;
        }
        // Close the virtual call if active. Virtual call should be
        // terminated for CHUP callback event
        if (isVirtualCallInProgress()) {
            terminateScoUsingVirtualVoiceCall();
        } else {
            if (mPhoneProxy != null) {
                try {
                    mPhoneProxy.hangupCall();
                } catch (RemoteException e) {
                    Log.e(TAG, Log.getStackTraceString(new Throwable()));
                }
            } else {
                Log.e(TAG, "Handsfree phone proxy null for hanging up call");
            }
        }
    }

    private void processDialCall(String number, BluetoothDevice device) {
        if (device == null) {
            Log.w(TAG, "processDialCall device is null");
            return;
        }

        String dialNumber;
        if (mDialingOut) {
            log("processDialCall, already dialling");
            atResponseCodeNative(HeadsetHalConstants.AT_RESPONSE_ERROR, 0, getByteAddress(device));
            return;
        }
        if ((number == null) || (number.length() == 0)) {
            dialNumber = mPhonebook.getLastDialledNumber();
            if (dialNumber == null) {
                log("processDialCall, last dial number null");
                atResponseCodeNative(
                        HeadsetHalConstants.AT_RESPONSE_ERROR, 0, getByteAddress(device));
                return;
            }
        } else if (number.charAt(0) == '>') {
            // Yuck - memory dialling requested.
            // Just dial last number for now
            if (number.startsWith(">9999")) { // for PTS test
                atResponseCodeNative(
                        HeadsetHalConstants.AT_RESPONSE_ERROR, 0, getByteAddress(device));
                return;
            }
            log("processDialCall, memory dial do last dial for now");
            dialNumber = mPhonebook.getLastDialledNumber();
            if (dialNumber == null) {
                log("processDialCall, last dial number null");
                atResponseCodeNative(
                        HeadsetHalConstants.AT_RESPONSE_ERROR, 0, getByteAddress(device));
                return;
            }
        } else {
            // Remove trailing ';'
            if (number.charAt(number.length() - 1) == ';') {
                number = number.substring(0, number.length() - 1);
            }

            dialNumber = PhoneNumberUtils.convertPreDial(number);
        }
        // Check for virtual call to terminate before sending Call Intent
        terminateScoUsingVirtualVoiceCall();

        Intent intent = new Intent(
                Intent.ACTION_CALL_PRIVILEGED, Uri.fromParts(SCHEME_TEL, dialNumber, null));
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        mService.startActivity(intent);
        // TODO(BT) continue send OK reults code after call starts
        //          hold wait lock, start a timer, set wait call flag
        //          Get call started indication from bluetooth phone
        mDialingOut = true;
        Message m = obtainMessage(DIALING_OUT_TIMEOUT);
        m.obj = getMatchingDevice(device);
        sendMessageDelayed(m, DIALING_OUT_TIMEOUT_VALUE);
    }

    private void processVolumeEvent(int volumeType, int volume, BluetoothDevice device) {
        if (device != null && !device.equals(mActiveScoDevice) && mPhoneState.isInCall()) {
            Log.w(TAG, "ignore processVolumeEvent");
            return;
        }

        if (volumeType == HeadsetHalConstants.VOLUME_TYPE_SPK) {
            mPhoneState.setSpeakerVolume(volume);
            int flag = (getCurrentState() == mAudioOn) ? AudioManager.FLAG_SHOW_UI : 0;
            mAudioManager.setStreamVolume(AudioManager.STREAM_BLUETOOTH_SCO, volume, flag);
        } else if (volumeType == HeadsetHalConstants.VOLUME_TYPE_MIC) {
            mPhoneState.setMicVolume(volume);
        } else {
            Log.e(TAG, "Bad voluem type: " + volumeType);
        }
    }

    private void processSendDtmf(int dtmf, BluetoothDevice device) {
        if (device == null) {
            Log.w(TAG, "processSendDtmf device is null");
            return;
        }

        if (mPhoneProxy != null) {
            try {
                mPhoneProxy.sendDtmf(dtmf);
            } catch (RemoteException e) {
                Log.e(TAG, Log.getStackTraceString(new Throwable()));
            }
        } else {
            Log.e(TAG, "Handsfree phone proxy null for sending DTMF");
        }
    }

    private void processCallState(HeadsetCallState callState) {
        processCallState(callState, false);
    }

    private void processCallState(HeadsetCallState callState, boolean isVirtualCall) {
        mPhoneState.setNumActiveCall(callState.mNumActive);
        mPhoneState.setNumHeldCall(callState.mNumHeld);
        mPhoneState.setCallState(callState.mCallState);
        if (mDialingOut) {
            if (callState.mCallState == HeadsetHalConstants.CALL_STATE_DIALING) {
                BluetoothDevice device = getDeviceForMessage(DIALING_OUT_TIMEOUT);
                if (device == null) {
                    return;
                }
                atResponseCodeNative(HeadsetHalConstants.AT_RESPONSE_OK, 0, getByteAddress(device));
                removeMessages(DIALING_OUT_TIMEOUT);
            } else if (callState.mCallState == HeadsetHalConstants.CALL_STATE_ACTIVE
                    || callState.mCallState == HeadsetHalConstants.CALL_STATE_IDLE) {
                mDialingOut = false;
            }
        }

        /* Set ActiveScoDevice to null when call ends */
        if ((mActiveScoDevice != null) && !isInCall()
                && callState.mCallState == HeadsetHalConstants.CALL_STATE_IDLE)
            mActiveScoDevice = null;

        log("mNumActive: " + callState.mNumActive + " mNumHeld: " + callState.mNumHeld
                + " mCallState: " + callState.mCallState);
        log("mNumber: " + callState.mNumber + " mType: " + callState.mType);

        if (isVirtualCall) {
            // virtual call state update
            if (getCurrentState() != mDisconnected) {
                phoneStateChangeNative(callState.mNumActive, callState.mNumHeld,
                        callState.mCallState, callState.mNumber, callState.mType);
            }
        } else {
            // circuit-switch voice call update
            // stop virtual voice call if there is a CSV call ongoing
            if (callState.mNumActive > 0 || callState.mNumHeld > 0
                    || callState.mCallState != HeadsetHalConstants.CALL_STATE_IDLE) {
                terminateScoUsingVirtualVoiceCall();
            }

            // Specific handling for case of starting MO/MT call while VOIP
            // ongoing, terminateScoUsingVirtualVoiceCall() resets callState
            // INCOMING/DIALING to IDLE. Some HS send AT+CIND? to read call
            // and get wrong value of callsetup. This case is hit only
            // SCO for VOIP call is not terminated via SDK API call.
            if (mPhoneState.getCallState() != callState.mCallState) {
                mPhoneState.setCallState(callState.mCallState);
            }

            // at this step: if there is virtual call ongoing, it means there is no CSV call
            // let virtual call continue and skip phone state update
            if (!isVirtualCallInProgress()) {
                if (getCurrentState() != mDisconnected) {
                    phoneStateChangeNative(callState.mNumActive, callState.mNumHeld,
                            callState.mCallState, callState.mNumber, callState.mType);
                }
            }
        }
    }

    // 1 enable noice reduction
    // 0 disable noice reduction
    private void processNoiceReductionEvent(int enable, BluetoothDevice device) {
        HashMap<String, Integer> AudioParamNrec = mHeadsetAudioParam.get(device);
        if (AudioParamNrec != null && !AudioParamNrec.isEmpty()) {
            if (enable == 1)
                AudioParamNrec.put("NREC", 1);
            else
                AudioParamNrec.put("NREC", 0);
            log("NREC value for device :" + device + " is: " + AudioParamNrec.get("NREC"));
        } else {
            Log.e(TAG, "processNoiceReductionEvent: AudioParamNrec is null ");
        }

        if (mActiveScoDevice != null && mActiveScoDevice.equals(device)
                && mAudioState == BluetoothHeadset.STATE_AUDIO_CONNECTED) {
            setAudioParameters(device);
        }
    }

    // 2 - WBS on
    // 1 - NBS on
    private void processWBSEvent(int enable, BluetoothDevice device) {
        if (enable == 2) {
            Log.d(TAG,
                    "AudioManager.setParameters: bt_wbs=on, device=" + device.getName() + "["
                            + device.getAddress() + "]");
            mAudioManager.setParameters(HEADSET_WBS + "=on");
        } else {
            Log.d(TAG,
                    "AudioManager.setParameters: bt_wbs=off, enable=" + enable
                            + ", device=" + device.getName() + "[" + device.getAddress() + "]");
            mAudioManager.setParameters(HEADSET_WBS + "=off");
        }
    }

    private void processAtChld(int chld, BluetoothDevice device) {
        if (device == null) {
            Log.w(TAG, "processAtChld device is null");
            return;
        }

        if (mPhoneProxy != null) {
            try {
                if (mPhoneProxy.processChld(chld)) {
                    atResponseCodeNative(
                            HeadsetHalConstants.AT_RESPONSE_OK, 0, getByteAddress(device));
                } else {
                    atResponseCodeNative(
                            HeadsetHalConstants.AT_RESPONSE_ERROR, 0, getByteAddress(device));
                }
            } catch (RemoteException e) {
                Log.e(TAG, Log.getStackTraceString(new Throwable()));
                atResponseCodeNative(
                        HeadsetHalConstants.AT_RESPONSE_ERROR, 0, getByteAddress(device));
            }
        } else {
            Log.e(TAG, "Handsfree phone proxy null for At+Chld");
            atResponseCodeNative(HeadsetHalConstants.AT_RESPONSE_ERROR, 0, getByteAddress(device));
        }
    }

    private void processSubscriberNumberRequest(BluetoothDevice device) {
        if (device == null) {
            Log.w(TAG, "processSubscriberNumberRequest device is null");
            return;
        }

        if (mPhoneProxy != null) {
            try {
                String number = mPhoneProxy.getSubscriberNumber();
                if (number != null) {
                    atResponseStringNative("+CNUM: ,\"" + number + "\","
                                    + PhoneNumberUtils.toaFromString(number) + ",,4",
                            getByteAddress(device));
                    atResponseCodeNative(
                            HeadsetHalConstants.AT_RESPONSE_OK, 0, getByteAddress(device));
                } else {
                    Log.e(TAG, "getSubscriberNumber returns null");
                    atResponseCodeNative(
                            HeadsetHalConstants.AT_RESPONSE_ERROR, 0, getByteAddress(device));
                }
            } catch (RemoteException e) {
                Log.e(TAG, Log.getStackTraceString(new Throwable()));
                atResponseCodeNative(
                        HeadsetHalConstants.AT_RESPONSE_ERROR, 0, getByteAddress(device));
            }
        } else {
            Log.e(TAG, "Handsfree phone proxy null for At+CNUM");
        }
    }

    private void processAtCind(BluetoothDevice device) {
        int call, call_setup;

        if (device == null) {
            Log.w(TAG, "processAtCind device is null");
            return;
        }

        /* Handsfree carkits expect that +CIND is properly responded to
         Hence we ensure that a proper response is sent
         for the virtual call too.*/
        if (isVirtualCallInProgress()) {
            call = 1;
            call_setup = 0;
        } else {
            // regular phone call
            call = mPhoneState.getNumActiveCall();
            call_setup = mPhoneState.getNumHeldCall();
        }

        cindResponseNative(mPhoneState.getService(), call, call_setup, mPhoneState.getCallState(),
                mPhoneState.getSignal(), mPhoneState.getRoam(), mPhoneState.getBatteryCharge(),
                getByteAddress(device));
    }

    private void processAtCops(BluetoothDevice device) {
        if (device == null) {
            Log.w(TAG, "processAtCops device is null");
            return;
        }

        if (mPhoneProxy != null) {
            try {
                String operatorName = mPhoneProxy.getNetworkOperator();
                if (operatorName == null) {
                    operatorName = "";
                }
                copsResponseNative(operatorName, getByteAddress(device));
            } catch (RemoteException e) {
                Log.e(TAG, Log.getStackTraceString(new Throwable()));
                copsResponseNative("", getByteAddress(device));
            }
        } else {
            Log.e(TAG, "Handsfree phone proxy null for At+COPS");
            copsResponseNative("", getByteAddress(device));
        }
    }

    private void processAtClcc(BluetoothDevice device) {
        if (device == null) {
            Log.w(TAG, "processAtClcc device is null");
            return;
        }

        if (mPhoneProxy != null) {
            try {
                if (isVirtualCallInProgress()) {
                    String phoneNumber = "";
                    int type = PhoneNumberUtils.TOA_Unknown;
                    try {
                        phoneNumber = mPhoneProxy.getSubscriberNumber();
                        type = PhoneNumberUtils.toaFromString(phoneNumber);
                    } catch (RemoteException ee) {
                        Log.e(TAG, "Unable to retrieve phone number"
                                        + "using IBluetoothHeadsetPhone proxy");
                        phoneNumber = "";
                    }
                    clccResponseNative(
                            1, 0, 0, 0, false, phoneNumber, type, getByteAddress(device));
                    clccResponseNative(0, 0, 0, 0, false, "", 0, getByteAddress(device));
                } else if (!mPhoneProxy.listCurrentCalls()) {
                    clccResponseNative(0, 0, 0, 0, false, "", 0, getByteAddress(device));
                } else {
                    Log.d(TAG, "Starting CLCC response timeout for device: " + device);
                    Message m = obtainMessage(CLCC_RSP_TIMEOUT);
                    m.obj = getMatchingDevice(device);
                    sendMessageDelayed(m, CLCC_RSP_TIMEOUT_VALUE);
                }
            } catch (RemoteException e) {
                Log.e(TAG, Log.getStackTraceString(new Throwable()));
                clccResponseNative(0, 0, 0, 0, false, "", 0, getByteAddress(device));
            }
        } else {
            Log.e(TAG, "Handsfree phone proxy null for At+CLCC");
            clccResponseNative(0, 0, 0, 0, false, "", 0, getByteAddress(device));
        }
    }

    private void processAtCscs(String atString, int type, BluetoothDevice device) {
        log("processAtCscs - atString = " + atString);
        if (mPhonebook != null) {
            mPhonebook.handleCscsCommand(atString, type, device);
        } else {
            Log.e(TAG, "Phonebook handle null for At+CSCS");
            atResponseCodeNative(HeadsetHalConstants.AT_RESPONSE_ERROR, 0, getByteAddress(device));
        }
    }

    private void processAtCpbs(String atString, int type, BluetoothDevice device) {
        log("processAtCpbs - atString = " + atString);
        if (mPhonebook != null) {
            mPhonebook.handleCpbsCommand(atString, type, device);
        } else {
            Log.e(TAG, "Phonebook handle null for At+CPBS");
            atResponseCodeNative(HeadsetHalConstants.AT_RESPONSE_ERROR, 0, getByteAddress(device));
        }
    }

    private void processAtCpbr(String atString, int type, BluetoothDevice device) {
        log("processAtCpbr - atString = " + atString);
        if (mPhonebook != null) {
            mPhonebook.handleCpbrCommand(atString, type, device);
        } else {
            Log.e(TAG, "Phonebook handle null for At+CPBR");
            atResponseCodeNative(HeadsetHalConstants.AT_RESPONSE_ERROR, 0, getByteAddress(device));
        }
    }

    private void queryPhoneState() {
        if (mPhoneProxy != null) {
            try {
                mPhoneProxy.queryPhoneState();
            } catch (RemoteException e) {
                Log.e(TAG, Log.getStackTraceString(new Throwable()));
            }
        } else {
            Log.e(TAG, "Handsfree phone proxy null for query phone state");
        }
    }

    /**
     * Find a character ch, ignoring quoted sections.
     * Return input.length() if not found.
     */
    static private int findChar(char ch, String input, int fromIndex) {
        for (int i = fromIndex; i < input.length(); i++) {
            char c = input.charAt(i);
            if (c == '"') {
                i = input.indexOf('"', i + 1);
                if (i == -1) {
                    return input.length();
                }
            } else if (c == ch) {
                return i;
            }
        }
        return input.length();
    }

    /**
     * Break an argument string into individual arguments (comma delimited).
     * Integer arguments are turned into Integer objects. Otherwise a String
     * object is used.
     */
    static private Object[] generateArgs(String input) {
        int i = 0;
        int j;
        ArrayList<Object> out = new ArrayList<Object>();
        while (i <= input.length()) {
            j = findChar(',', input, i);

            String arg = input.substring(i, j);
            try {
                out.add(new Integer(arg));
            } catch (NumberFormatException e) {
                out.add(arg);
            }

            i = j + 1; // move past comma
        }
        return out.toArray();
    }

    /**
     * Process vendor specific AT commands
     * @param atString AT command after the "AT+" prefix
     * @param device Remote device that has sent this command
     */
    private void processVendorSpecificAt(String atString, BluetoothDevice device) {
        log("processVendorSpecificAt - atString = " + atString);

        // Currently we accept only SET type commands.
        int indexOfEqual = atString.indexOf("=");
        if (indexOfEqual == -1) {
            Log.e(TAG, "processVendorSpecificAt: command type error in " + atString);
            atResponseCodeNative(HeadsetHalConstants.AT_RESPONSE_ERROR, 0, getByteAddress(device));
            return;
        }

        String command = atString.substring(0, indexOfEqual);
        Integer companyId = VENDOR_SPECIFIC_AT_COMMAND_COMPANY_ID.get(command);
        if (companyId == null) {
            Log.e(TAG, "processVendorSpecificAt: unsupported command: " + atString);
            atResponseCodeNative(HeadsetHalConstants.AT_RESPONSE_ERROR, 0, getByteAddress(device));
            return;
        }

        String arg = atString.substring(indexOfEqual + 1);
        if (arg.startsWith("?")) {
            Log.e(TAG, "processVendorSpecificAt: command type error in " + atString);
            atResponseCodeNative(HeadsetHalConstants.AT_RESPONSE_ERROR, 0, getByteAddress(device));
            return;
        }

        Object[] args = generateArgs(arg);
        if (command.equals(BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_XAPL)) {
            processAtXapl(args, device);
        }
        broadcastVendorSpecificEventIntent(
                command, companyId, BluetoothHeadset.AT_CMD_TYPE_SET, args, device);
        atResponseCodeNative(HeadsetHalConstants.AT_RESPONSE_OK, 0, getByteAddress(device));
    }

    /**
     * Process AT+XAPL AT command
     * @param args command arguments after the equal sign
     * @param device Remote device that has sent this command
     */
    private void processAtXapl(Object[] args, BluetoothDevice device) {
        if (args.length != 2) {
            Log.w(TAG, "processAtXapl() args length must be 2: " + String.valueOf(args.length));
            return;
        }
        if (!(args[0] instanceof String) || !(args[1] instanceof Integer)) {
            Log.w(TAG, "processAtXapl() argument types not match");
            return;
        }
        // feature = 2 indicates that we support battery level reporting only
        atResponseStringNative("+XAPL=iPhone," + String.valueOf(2), getByteAddress(device));
    }

    private void processUnknownAt(String atString, BluetoothDevice device) {
        if (device == null) {
            Log.w(TAG, "processUnknownAt device is null");
            return;
        }
        log("processUnknownAt - atString = " + atString);
        String atCommand = parseUnknownAt(atString);
        int commandType = getAtCommandType(atCommand);
        if (atCommand.startsWith("+CSCS")) {
            processAtCscs(atCommand.substring(5), commandType, device);
        } else if (atCommand.startsWith("+CPBS")) {
            processAtCpbs(atCommand.substring(5), commandType, device);
        } else if (atCommand.startsWith("+CPBR")) {
            processAtCpbr(atCommand.substring(5), commandType, device);
        } else {
            processVendorSpecificAt(atCommand, device);
        }
    }

    private void processKeyPressed(BluetoothDevice device) {
        if (device == null) {
            Log.w(TAG, "processKeyPressed device is null");
            return;
        }

        if (mPhoneState.getCallState() == HeadsetHalConstants.CALL_STATE_INCOMING) {
            if (mPhoneProxy != null) {
                try {
                    mPhoneProxy.answerCall();
                } catch (RemoteException e) {
                    Log.e(TAG, Log.getStackTraceString(new Throwable()));
                }
            } else {
                Log.e(TAG, "Handsfree phone proxy null for answering call");
            }
        } else if (mPhoneState.getNumActiveCall() > 0) {
            if (!isAudioOn()) {
                connectAudioNative(getByteAddress(mCurrentDevice));
            } else {
                if (mPhoneProxy != null) {
                    try {
                        mPhoneProxy.hangupCall();
                    } catch (RemoteException e) {
                        Log.e(TAG, Log.getStackTraceString(new Throwable()));
                    }
                } else {
                    Log.e(TAG, "Handsfree phone proxy null for hangup call");
                }
            }
        } else {
            String dialNumber = mPhonebook.getLastDialledNumber();
            if (dialNumber == null) {
                log("processKeyPressed, last dial number null");
                return;
            }
            Intent intent = new Intent(
                    Intent.ACTION_CALL_PRIVILEGED, Uri.fromParts(SCHEME_TEL, dialNumber, null));
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            mService.startActivity(intent);
        }
    }

    /**
     * Send HF indicator value changed intent
     * @param device Device whose HF indicator value has changed
     * @param ind_id Indicator ID [0-65535]
     * @param ind_value Indicator Value [0-65535], -1 means invalid but ind_id is supported
     */
    private void sendIndicatorIntent(BluetoothDevice device, int ind_id, int ind_value) {
        Intent intent = new Intent(BluetoothHeadset.ACTION_HF_INDICATORS_VALUE_CHANGED);
        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
        intent.putExtra(BluetoothHeadset.EXTRA_HF_INDICATORS_IND_ID, ind_id);
        intent.putExtra(BluetoothHeadset.EXTRA_HF_INDICATORS_IND_VALUE, ind_value);

        mService.sendBroadcast(intent, HeadsetService.BLUETOOTH_PERM);
    }

    private void processAtBind(String at_string, BluetoothDevice device) {
        log("processAtBind: " + at_string);

        // Parse the AT String to find the Indicator Ids that are supported
        int ind_id = 0;
        int iter = 0;
        int iter1 = 0;

        while (iter < at_string.length()) {
            iter1 = findChar(',', at_string, iter);
            String id = at_string.substring(iter, iter1);

            try {
                ind_id = Integer.valueOf(id);
            } catch (NumberFormatException e) {
                Log.e(TAG, Log.getStackTraceString(new Throwable()));
            }

            switch (ind_id) {
                case HeadsetHalConstants.HF_INDICATOR_ENHANCED_DRIVER_SAFETY:
                    log("Send Broadcast intent for the Enhanced Driver Safety indicator.");
                    sendIndicatorIntent(device, ind_id, -1);
                    break;
                case HeadsetHalConstants.HF_INDICATOR_BATTERY_LEVEL_STATUS:
                    log("Send Broadcast intent for the Battery Level indicator.");
                    sendIndicatorIntent(device, ind_id, -1);
                    break;
                default:
                    log("Invalid HF Indicator Received");
                    break;
            }

            iter = iter1 + 1; // move past comma
        }
    }

    private void processAtBiev(int indId, int indValue, BluetoothDevice device) {
        log("processAtBiev: ind_id=" + indId + ", ind_value=" + indValue);
        sendIndicatorIntent(device, indId, indValue);
    }

    private void onConnectionStateChanged(int state, byte[] address) {
        StackEvent event = new StackEvent(EVENT_TYPE_CONNECTION_STATE_CHANGED);
        event.valueInt = state;
        event.device = getDevice(address);
        sendMessage(STACK_EVENT, event);
    }

    private void onAudioStateChanged(int state, byte[] address) {
        StackEvent event = new StackEvent(EVENT_TYPE_AUDIO_STATE_CHANGED);
        event.valueInt = state;
        event.device = getDevice(address);
        sendMessage(STACK_EVENT, event);
    }

    private void onVrStateChanged(int state, byte[] address) {
        StackEvent event = new StackEvent(EVENT_TYPE_VR_STATE_CHANGED);
        event.valueInt = state;
        event.device = getDevice(address);
        sendMessage(STACK_EVENT, event);
    }

    private void onAnswerCall(byte[] address) {
        StackEvent event = new StackEvent(EVENT_TYPE_ANSWER_CALL);
        event.device = getDevice(address);
        sendMessage(STACK_EVENT, event);
    }

    private void onHangupCall(byte[] address) {
        StackEvent event = new StackEvent(EVENT_TYPE_HANGUP_CALL);
        event.device = getDevice(address);
        sendMessage(STACK_EVENT, event);
    }

    private void onVolumeChanged(int type, int volume, byte[] address) {
        StackEvent event = new StackEvent(EVENT_TYPE_VOLUME_CHANGED);
        event.valueInt = type;
        event.valueInt2 = volume;
        event.device = getDevice(address);
        sendMessage(STACK_EVENT, event);
    }

    private void onDialCall(String number, byte[] address) {
        StackEvent event = new StackEvent(EVENT_TYPE_DIAL_CALL);
        event.valueString = number;
        event.device = getDevice(address);
        sendMessage(STACK_EVENT, event);
    }

    private void onSendDtmf(int dtmf, byte[] address) {
        StackEvent event = new StackEvent(EVENT_TYPE_SEND_DTMF);
        event.valueInt = dtmf;
        event.device = getDevice(address);
        sendMessage(STACK_EVENT, event);
    }

    private void onNoiceReductionEnable(boolean enable, byte[] address) {
        StackEvent event = new StackEvent(EVENT_TYPE_NOICE_REDUCTION);
        event.valueInt = enable ? 1 : 0;
        event.device = getDevice(address);
        sendMessage(STACK_EVENT, event);
    }

    private void onWBS(int codec, byte[] address) {
        StackEvent event = new StackEvent(EVENT_TYPE_WBS);
        event.valueInt = codec;
        event.device = getDevice(address);
        sendMessage(STACK_EVENT, event);
    }

    private void onAtChld(int chld, byte[] address) {
        StackEvent event = new StackEvent(EVENT_TYPE_AT_CHLD);
        event.valueInt = chld;
        event.device = getDevice(address);
        sendMessage(STACK_EVENT, event);
    }

    private void onAtCnum(byte[] address) {
        StackEvent event = new StackEvent(EVENT_TYPE_SUBSCRIBER_NUMBER_REQUEST);
        event.device = getDevice(address);
        sendMessage(STACK_EVENT, event);
    }

    private void onAtCind(byte[] address) {
        StackEvent event = new StackEvent(EVENT_TYPE_AT_CIND);
        event.device = getDevice(address);
        sendMessage(STACK_EVENT, event);
    }

    private void onAtCops(byte[] address) {
        StackEvent event = new StackEvent(EVENT_TYPE_AT_COPS);
        event.device = getDevice(address);
        sendMessage(STACK_EVENT, event);
    }

    private void onAtClcc(byte[] address) {
        StackEvent event = new StackEvent(EVENT_TYPE_AT_CLCC);
        event.device = getDevice(address);
        sendMessage(STACK_EVENT, event);
    }

    private void onUnknownAt(String atString, byte[] address) {
        StackEvent event = new StackEvent(EVENT_TYPE_UNKNOWN_AT);
        event.valueString = atString;
        event.device = getDevice(address);
        sendMessage(STACK_EVENT, event);
    }

    private void onKeyPressed(byte[] address) {
        StackEvent event = new StackEvent(EVENT_TYPE_KEY_PRESSED);
        event.device = getDevice(address);
        sendMessage(STACK_EVENT, event);
    }

    private void onATBind(String atString, byte[] address) {
        StackEvent event = new StackEvent(EVENT_TYPE_BIND);
        event.valueString = atString;
        event.device = getDevice(address);
        sendMessage(STACK_EVENT, event);
    }

    private void onATBiev(int ind_id, int ind_value, byte[] address) {
        StackEvent event = new StackEvent(EVENT_TYPE_BIEV);
        event.valueInt = ind_id;
        event.valueInt2 = ind_value;
        event.device = getDevice(address);
        sendMessage(STACK_EVENT, event);
    }

    private void processIntentBatteryChanged(Intent intent) {
        int batteryLevel = intent.getIntExtra("level", -1);
        int scale = intent.getIntExtra("scale", -1);
        if (batteryLevel == -1 || scale == -1 || scale == 0) {
            Log.e(TAG, "Bad Battery Changed intent: " + batteryLevel + "," + scale);
            return;
        }
        batteryLevel = batteryLevel * 5 / scale;
        mPhoneState.setBatteryCharge(batteryLevel);
    }

    private void processDeviceStateChanged(HeadsetDeviceState deviceState) {
        notifyDeviceStatusNative(deviceState.mService, deviceState.mRoam, deviceState.mSignal,
                deviceState.mBatteryCharge);
    }

    private void processSendClccResponse(HeadsetClccResponse clcc) {
        BluetoothDevice device = getDeviceForMessage(CLCC_RSP_TIMEOUT);
        if (device == null) {
            return;
        }
        if (clcc.mIndex == 0) {
            removeMessages(CLCC_RSP_TIMEOUT);
        }
        clccResponseNative(clcc.mIndex, clcc.mDirection, clcc.mStatus, clcc.mMode, clcc.mMpty,
                clcc.mNumber, clcc.mType, getByteAddress(device));
    }

    private void processSendVendorSpecificResultCode(HeadsetVendorSpecificResultCode resultCode) {
        String stringToSend = resultCode.mCommand + ": ";
        if (resultCode.mArg != null) {
            stringToSend += resultCode.mArg;
        }
        atResponseStringNative(stringToSend, getByteAddress(resultCode.mDevice));
    }

    private String getCurrentDeviceName(BluetoothDevice device) {
        String defaultName = "<unknown>";

        if (device == null) {
            return defaultName;
        }

        String deviceName = device.getName();
        if (deviceName == null) {
            return defaultName;
        }
        return deviceName;
    }

    private byte[] getByteAddress(BluetoothDevice device) {
        return Utils.getBytesFromAddress(device.getAddress());
    }

    private BluetoothDevice getDevice(byte[] address) {
        return mAdapter.getRemoteDevice(Utils.getAddressStringFromByte(address));
    }

    private boolean isInCall() {
        return ((mPhoneState.getNumActiveCall() > 0) || (mPhoneState.getNumHeldCall() > 0)
                || ((mPhoneState.getCallState() != HeadsetHalConstants.CALL_STATE_IDLE)
                           && (mPhoneState.getCallState()
                                      != HeadsetHalConstants.CALL_STATE_INCOMING)));
    }

    private boolean isRinging() {
        return mPhoneState.getCallState() == HeadsetHalConstants.CALL_STATE_INCOMING;
    }

    // Accept incoming SCO only when there is in-band ringing, incoming call,
    // active call, VR activated, active VOIP call
    private boolean isScoAcceptable() {
        if (mForceScoAudio) return true;
        return mAudioRouteAllowed
                && (mVoiceRecognitionStarted || isInCall()
                           || (BluetoothHeadset.isInbandRingingSupported(mService) && isRinging()));
    }

    boolean isConnected() {
        IState currentState = getCurrentState();
        return (currentState == mConnected || currentState == mAudioOn);
    }

    boolean okToConnect(BluetoothDevice device) {
        AdapterService adapterService = AdapterService.getAdapterService();
        int priority = mService.getPriority(device);
        boolean ret = false;
        // check if this is an incoming connection in Quiet mode.
        if ((adapterService == null)
                || ((adapterService.isQuietModeEnabled() == true) && (mTargetDevice == null))) {
            ret = false;
        }
        // check priority and accept or reject the connection. if priority is undefined
        // it is likely that our SDP has not completed and peer is initiating the
        // connection. Allow this connection, provided the device is bonded
        else if ((BluetoothProfile.PRIORITY_OFF < priority)
                || ((BluetoothProfile.PRIORITY_UNDEFINED == priority)
                           && (device.getBondState() != BluetoothDevice.BOND_NONE))) {
            ret = true;
        }
        return ret;
    }

    @Override
    protected void log(String msg) {
        if (DBG) {
            super.log(msg);
        }
    }

    public void handleAccessPermissionResult(Intent intent) {
        log("handleAccessPermissionResult");
        BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
        if (mPhonebook != null) {
            if (!mPhonebook.getCheckingAccessPermission()) {
                return;
            }
            int atCommandResult = 0;
            int atCommandErrorCode = 0;
            // HeadsetBase headset = mHandsfree.getHeadset();
            // ASSERT: (headset != null) && headSet.isConnected()
            // REASON: mCheckingAccessPermission is true, otherwise resetAtState
            // has set mCheckingAccessPermission to false
            if (intent.getAction().equals(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY)) {
                if (intent.getIntExtra(BluetoothDevice.EXTRA_CONNECTION_ACCESS_RESULT,
                            BluetoothDevice.CONNECTION_ACCESS_NO)
                        == BluetoothDevice.CONNECTION_ACCESS_YES) {
                    if (intent.getBooleanExtra(BluetoothDevice.EXTRA_ALWAYS_ALLOWED, false)) {
                        mCurrentDevice.setPhonebookAccessPermission(BluetoothDevice.ACCESS_ALLOWED);
                    }
                    atCommandResult = mPhonebook.processCpbrCommand(device);
                } else {
                    if (intent.getBooleanExtra(BluetoothDevice.EXTRA_ALWAYS_ALLOWED, false)) {
                        mCurrentDevice.setPhonebookAccessPermission(
                                BluetoothDevice.ACCESS_REJECTED);
                    }
                }
            }
            mPhonebook.setCpbrIndex(-1);
            mPhonebook.setCheckingAccessPermission(false);

            if (atCommandResult >= 0) {
                atResponseCodeNative(atCommandResult, atCommandErrorCode, getByteAddress(device));
            } else {
                log("handleAccessPermissionResult - RESULT_NONE");
            }
        } else {
            Log.e(TAG, "Phonebook handle null");
            if (device != null) {
                atResponseCodeNative(
                        HeadsetHalConstants.AT_RESPONSE_ERROR, 0, getByteAddress(device));
            }
        }
    }

    private static final String SCHEME_TEL = "tel";

    // Event types for STACK_EVENT message
    final private static int EVENT_TYPE_NONE = 0;
    final private static int EVENT_TYPE_CONNECTION_STATE_CHANGED = 1;
    final private static int EVENT_TYPE_AUDIO_STATE_CHANGED = 2;
    final private static int EVENT_TYPE_VR_STATE_CHANGED = 3;
    final private static int EVENT_TYPE_ANSWER_CALL = 4;
    final private static int EVENT_TYPE_HANGUP_CALL = 5;
    final private static int EVENT_TYPE_VOLUME_CHANGED = 6;
    final private static int EVENT_TYPE_DIAL_CALL = 7;
    final private static int EVENT_TYPE_SEND_DTMF = 8;
    final private static int EVENT_TYPE_NOICE_REDUCTION = 9;
    final private static int EVENT_TYPE_AT_CHLD = 10;
    final private static int EVENT_TYPE_SUBSCRIBER_NUMBER_REQUEST = 11;
    final private static int EVENT_TYPE_AT_CIND = 12;
    final private static int EVENT_TYPE_AT_COPS = 13;
    final private static int EVENT_TYPE_AT_CLCC = 14;
    final private static int EVENT_TYPE_UNKNOWN_AT = 15;
    final private static int EVENT_TYPE_KEY_PRESSED = 16;
    final private static int EVENT_TYPE_WBS = 17;
    final private static int EVENT_TYPE_BIND = 18;
    final private static int EVENT_TYPE_BIEV = 19;

    private class StackEvent {
        int type = EVENT_TYPE_NONE;
        int valueInt = 0;
        int valueInt2 = 0;
        String valueString = null;
        BluetoothDevice device = null;

        private StackEvent(int type) {
            this.type = type;
        }
    }

    /*package*/ native boolean atResponseCodeNative(
            int responseCode, int errorCode, byte[] address);
    /*package*/ native boolean atResponseStringNative(String responseString, byte[] address);

    private native static void classInitNative();
    private native void initializeNative(int max_hf_clients, boolean inband_ring_enable);
    private native void cleanupNative();
    private native boolean connectHfpNative(byte[] address);
    private native boolean disconnectHfpNative(byte[] address);
    private native boolean connectAudioNative(byte[] address);
    private native boolean disconnectAudioNative(byte[] address);
    private native boolean startVoiceRecognitionNative(byte[] address);
    private native boolean stopVoiceRecognitionNative(byte[] address);
    private native boolean setVolumeNative(int volumeType, int volume, byte[] address);
    private native boolean cindResponseNative(int service, int numActive, int numHeld,
            int callState, int signal, int roam, int batteryCharge, byte[] address);
    private native boolean bindResponseNative(int ind_id, boolean ind_status, byte[] address);
    private native boolean notifyDeviceStatusNative(
            int networkState, int serviceType, int signal, int batteryCharge);

    private native boolean clccResponseNative(int index, int dir, int status, int mode,
            boolean mpty, String number, int type, byte[] address);
    private native boolean copsResponseNative(String operatorName, byte[] address);

    private native boolean phoneStateChangeNative(
            int numActive, int numHeld, int callState, String number, int type);
    private native boolean configureWBSNative(byte[] address, int condec_config);
    private native boolean setScoAllowedNative(boolean value);
}
