/*
 * Copyright (c) 2014 The Android Open Source Project
 * 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 Headset Client StateMachine
 *                      (Disconnected)
 *                           | ^  ^
 *                   CONNECT | |  | DISCONNECTED
 *                           V |  |
 *                   (Connecting) |
 *                           |    |
 *                 CONNECTED |    | DISCONNECT
 *                           V    |
 *                        (Connected)
 *                           |    ^
 *             CONNECT_AUDIO |    | DISCONNECT_AUDIO
 *                           V    |
 *                         (AudioOn)
 */

package com.android.bluetooth.hfpclient;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadsetClient;
import android.bluetooth.BluetoothHeadsetClientCall;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothUuid;
import android.os.Bundle;
import android.os.Message;
import android.os.ParcelUuid;
import android.util.Log;
import android.util.Pair;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.telecom.TelecomManager;

import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.ProfileService;
import com.android.bluetooth.hfpclient.connserv.HfpClientConnectionService;
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.Arrays;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Set;

import com.android.bluetooth.R;

final class HeadsetClientStateMachine extends StateMachine {
    private static final String TAG = "HeadsetClientStateMachine";
    private static final boolean DBG = false;

    static final int NO_ACTION = 0;

    // external actions
    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;
    static final int SET_MIC_VOLUME = 7;
    static final int SET_SPEAKER_VOLUME = 8;
    static final int REDIAL = 9;
    static final int DIAL_NUMBER = 10;
    static final int DIAL_MEMORY = 11;
    static final int ACCEPT_CALL = 12;
    static final int REJECT_CALL = 13;
    static final int HOLD_CALL = 14;
    static final int TERMINATE_CALL = 15;
    static final int ENTER_PRIVATE_MODE = 16;
    static final int SEND_DTMF = 17;
    static final int EXPLICIT_CALL_TRANSFER = 18;
    static final int LAST_VTAG_NUMBER = 19;
    static final int DISABLE_NREC = 20;

    // internal actions
    static final int QUERY_CURRENT_CALLS = 50;
    static final int QUERY_OPERATOR_NAME = 51;
    static final int SUBSCRIBER_INFO = 52;
    // special action to handle terminating specific call from multiparty call
    static final int TERMINATE_SPECIFIC_CALL = 53;

    static final int MAX_HFP_SCO_VOICE_CALL_VOLUME = 15; // HFP 1.5 spec.
    static final int MIN_HFP_SCO_VOICE_CALL_VOLUME = 1; // HFP 1.5 spec.

    private static final int STACK_EVENT = 100;

    private final Disconnected mDisconnected;
    private final Connecting mConnecting;
    private final Connected mConnected;
    private final AudioOn mAudioOn;

    private final HeadsetClientService mService;

    private Hashtable<Integer, BluetoothHeadsetClientCall> mCalls;
    private Hashtable<Integer, BluetoothHeadsetClientCall> mCallsUpdate;
    private boolean mQueryCallsSupported;

    private int mIndicatorNetworkState;
    private int mIndicatorNetworkType;
    private int mIndicatorNetworkSignal;
    private int mIndicatorBatteryLevel;

    private int mIndicatorCall;
    private int mIndicatorCallSetup;
    private int mIndicatorCallHeld;
    private boolean mVgsFromStack = false;
    private boolean mVgmFromStack = false;

    private String mOperatorName;
    private String mSubscriberInfo;

    private int mVoiceRecognitionActive;
    private int mInBandRingtone;

    private int mMaxAmVcVol;
    private int mMinAmVcVol;

    // queue of send actions (pair action, action_data)
    private Queue<Pair<Integer, Object>> mQueuedActions;

    // last executed command, before action is complete e.g. waiting for some
    // indicator
    private Pair<Integer, Object> mPendingAction;

    private final AudioManager mAudioManager;
    private int mAudioState;
    // Indicates whether audio can be routed to the device.
    private boolean mAudioRouteAllowed;
    private boolean mAudioWbs;
    private final BluetoothAdapter mAdapter;
    private boolean mNativeAvailable;
    private TelecomManager mTelecomManager;

    // currently connected device
    private BluetoothDevice mCurrentDevice = null;

    // general peer features and call handling features
    private int mPeerFeatures;
    private int mChldFeatures;

    static {
        classInitNative();
    }

    public void dump(StringBuilder sb) {
        ProfileService.println(sb, "mCurrentDevice: " + mCurrentDevice);
        ProfileService.println(sb, "mAudioOn: " + mAudioOn);
        ProfileService.println(sb, "mAudioState: " + mAudioState);
        ProfileService.println(sb, "mAudioWbs: " + mAudioWbs);
        ProfileService.println(sb, "mIndicatorNetworkState: " + mIndicatorNetworkState);
        ProfileService.println(sb, "mIndicatorNetworkType: " + mIndicatorNetworkType);
        ProfileService.println(sb, "mIndicatorNetworkSignal: " + mIndicatorNetworkSignal);
        ProfileService.println(sb, "mIndicatorBatteryLevel: " + mIndicatorBatteryLevel);
        ProfileService.println(sb, "mIndicatorCall: " + mIndicatorCall);
        ProfileService.println(sb, "mIndicatorCallSetup: " + mIndicatorCallSetup);
        ProfileService.println(sb, "mIndicatorCallHeld: " + mIndicatorCallHeld);
        ProfileService.println(sb, "mVgsFromStack: " + mVgsFromStack);
        ProfileService.println(sb, "mVgmFromStack: " + mVgmFromStack);
        ProfileService.println(sb, "mOperatorName: " + mOperatorName);
        ProfileService.println(sb, "mSubscriberInfo: " + mSubscriberInfo);
        ProfileService.println(sb, "mVoiceRecognitionActive: " + mVoiceRecognitionActive);
        ProfileService.println(sb, "mInBandRingtone: " + mInBandRingtone);

        ProfileService.println(sb, "mCalls:");
        if (mCalls != null) {
            for (BluetoothHeadsetClientCall call : mCalls.values()) {
                ProfileService.println(sb, "  " + call);
            }
        }

        ProfileService.println(sb, "mCallsUpdate:");
        if (mCallsUpdate != null) {
            for (BluetoothHeadsetClientCall call : mCallsUpdate.values()) {
                ProfileService.println(sb, "  " + call);
            }
        }
    }

    private void clearPendingAction() {
        mPendingAction = new Pair<Integer, Object>(NO_ACTION, 0);
    }

    private void addQueuedAction(int action) {
        addQueuedAction(action, 0);
    }

    private void addQueuedAction(int action, Object data) {
        mQueuedActions.add(new Pair<Integer, Object>(action, data));
    }

    private void addQueuedAction(int action, int data) {
        mQueuedActions.add(new Pair<Integer, Object>(action, data));
    }

    private void addCall(int state, String number) {
        Log.d(TAG, "addToCalls state:" + state + " number:" + number);

        boolean outgoing = state == BluetoothHeadsetClientCall.CALL_STATE_DIALING ||
               state == BluetoothHeadsetClientCall.CALL_STATE_ALERTING;

        // new call always takes lowest possible id, starting with 1
        Integer id = 1;
        while (mCalls.containsKey(id)) {
            id++;
        }

        BluetoothHeadsetClientCall c = new BluetoothHeadsetClientCall(mCurrentDevice, id, state,
                number, false, outgoing);
        mCalls.put(id, c);

        sendCallChangedIntent(c);
    }

    private void removeCalls(int... states) {
        Log.d(TAG, "removeFromCalls states:" + Arrays.toString(states));

        Iterator<Hashtable.Entry<Integer, BluetoothHeadsetClientCall>> it;

        it = mCalls.entrySet().iterator();
        while (it.hasNext()) {
            BluetoothHeadsetClientCall c = it.next().getValue();

            for (int s : states) {
                if (c.getState() == s) {
                    it.remove();
                    setCallState(c, BluetoothHeadsetClientCall.CALL_STATE_TERMINATED);
                    break;
                }
            }
        }
    }

    private void changeCallsState(int old_state, int new_state) {
        Log.d(TAG, "changeStateFromCalls old:" + old_state + " new: " + new_state);

        for (BluetoothHeadsetClientCall c : mCalls.values()) {
            if (c.getState() == old_state) {
                setCallState(c, new_state);
            }
        }
    }

    private BluetoothHeadsetClientCall getCall(int... states) {
        Log.d(TAG, "getFromCallsWithStates states:" + Arrays.toString(states));
        for (BluetoothHeadsetClientCall c : mCalls.values()) {
            for (int s : states) {
                if (c.getState() == s) {
                    return c;
                }
            }
        }

        return null;
    }

    private int callsInState(int state) {
        int i = 0;
        for (BluetoothHeadsetClientCall c : mCalls.values()) {
            if (c.getState() == state) {
                i++;
            }
        }

        return i;
    }

    private void updateCallsMultiParty() {
        boolean multi = callsInState(BluetoothHeadsetClientCall.CALL_STATE_ACTIVE) > 1;

        for (BluetoothHeadsetClientCall c : mCalls.values()) {
            if (c.getState() == BluetoothHeadsetClientCall.CALL_STATE_ACTIVE) {
                if (c.isMultiParty() == multi) {
                    continue;
                }

                c.setMultiParty(multi);
                sendCallChangedIntent(c);
            } else {
                if (c.isMultiParty()) {
                    c.setMultiParty(false);
                    sendCallChangedIntent(c);
                }
            }
        }
    }

    private void setCallState(BluetoothHeadsetClientCall c, int state) {
        if (state == c.getState()) {
            return;
        }
        c.setState(state);
        sendCallChangedIntent(c);
    }

    private void sendCallChangedIntent(BluetoothHeadsetClientCall c) {
        Log.d(TAG, "sendCallChangedIntent " + c);
        Intent intent = new Intent(BluetoothHeadsetClient.ACTION_CALL_CHANGED);
        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
        intent.putExtra(BluetoothHeadsetClient.EXTRA_CALL, c);
        mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
    }

    private boolean waitForIndicators(int call, int callsetup, int callheld) {
        // all indicators initial values received
        if (mIndicatorCall != -1 && mIndicatorCallSetup != -1 &&
                mIndicatorCallHeld != -1) {
            return false;
        }

        if (call != -1) {
            mIndicatorCall = call;
        } else if (callsetup != -1) {
            mIndicatorCallSetup = callsetup;
        } else if (callheld != -1) {
            mIndicatorCallHeld = callheld;
        }

        // still waiting for some indicators
        if (mIndicatorCall == -1 || mIndicatorCallSetup == -1 ||
                mIndicatorCallHeld == -1) {
            return true;
        }

        // for start always query calls to define if it is supported
        mQueryCallsSupported = queryCallsStart();

        if (mQueryCallsSupported) {
            return true;
        }

        // no support for querying calls

        switch (mIndicatorCallSetup) {
            case HeadsetClientHalConstants.CALLSETUP_INCOMING:
                addCall(BluetoothHeadsetClientCall.CALL_STATE_INCOMING, "");
                break;
            case HeadsetClientHalConstants.CALLSETUP_OUTGOING:
                addCall(BluetoothHeadsetClientCall.CALL_STATE_DIALING, "");
                break;
            case HeadsetClientHalConstants.CALLSETUP_ALERTING:
                addCall(BluetoothHeadsetClientCall.CALL_STATE_ALERTING, "");
                break;
            case HeadsetClientHalConstants.CALLSETUP_NONE:
            default:
                break;
        }

        switch (mIndicatorCall) {
            case HeadsetClientHalConstants.CALL_CALLS_IN_PROGRESS:
                addCall(BluetoothHeadsetClientCall.CALL_STATE_ACTIVE, "");
                break;
            case HeadsetClientHalConstants.CALL_NO_CALLS_IN_PROGRESS:
            default:
                break;
        }

        switch (mIndicatorCallHeld) {
            case HeadsetClientHalConstants.CALLHELD_HOLD_AND_ACTIVE:
            case HeadsetClientHalConstants.CALLHELD_HOLD:
                addCall(BluetoothHeadsetClientCall.CALL_STATE_HELD, "");
                break;
            case HeadsetClientHalConstants.CALLHELD_NONE:
            default:
                break;
        }

        return true;
    }

    private void updateCallIndicator(int call) {
        Log.d(TAG, "updateCallIndicator " + call);

        if (waitForIndicators(call, -1, -1)) {
            return;
        }

        if (mQueryCallsSupported) {
            sendMessage(QUERY_CURRENT_CALLS);
            return;
        }

        BluetoothHeadsetClientCall c = null;

        switch (call) {
            case HeadsetClientHalConstants.CALL_NO_CALLS_IN_PROGRESS:
                removeCalls(BluetoothHeadsetClientCall.CALL_STATE_ACTIVE,
                        BluetoothHeadsetClientCall.CALL_STATE_HELD,
                        BluetoothHeadsetClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD);

                break;
            case HeadsetClientHalConstants.CALL_CALLS_IN_PROGRESS:
                if (mIndicatorCall == HeadsetClientHalConstants.CALL_CALLS_IN_PROGRESS) {
                    // WP7.8 is sending call=1 before setup=0 when rejecting
                    // waiting call
                    if (mIndicatorCallSetup != HeadsetClientHalConstants.CALLSETUP_NONE) {
                        c = getCall(BluetoothHeadsetClientCall.CALL_STATE_WAITING);
                        if (c != null) {
                            setCallState(c, BluetoothHeadsetClientCall.CALL_STATE_TERMINATED);
                            mCalls.remove(c.getId());
                        }
                    }

                    break;
                }

                // if there is only waiting call it is changed to incoming so
                // don't
                // handle it here
                if (mIndicatorCallSetup != HeadsetClientHalConstants.CALLSETUP_NONE) {
                    c = getCall(BluetoothHeadsetClientCall.CALL_STATE_DIALING,
                            BluetoothHeadsetClientCall.CALL_STATE_ALERTING,
                            BluetoothHeadsetClientCall.CALL_STATE_INCOMING);
                    if (c != null) {
                        setCallState(c, BluetoothHeadsetClientCall.CALL_STATE_ACTIVE);
                    }
                }

                updateCallsMultiParty();
                break;
            default:
                break;
        }

        mIndicatorCall = call;
    }

    private void updateCallSetupIndicator(int callsetup) {
        Log.d(TAG, "updateCallSetupIndicator " + callsetup + " " + mPendingAction.first);

        if (waitForIndicators(-1, callsetup, -1)) {
            return;
        }

        if (mQueryCallsSupported) {
            sendMessage(QUERY_CURRENT_CALLS);
            return;
        }

        switch (callsetup) {
            case HeadsetClientHalConstants.CALLSETUP_NONE:
                switch (mPendingAction.first) {
                    case ACCEPT_CALL:
                        switch ((Integer) mPendingAction.second) {
                            case HeadsetClientHalConstants.CALL_ACTION_ATA:
                                removeCalls(BluetoothHeadsetClientCall.CALL_STATE_DIALING,
                                        BluetoothHeadsetClientCall.CALL_STATE_ALERTING);
                                clearPendingAction();
                                break;
                            case HeadsetClientHalConstants.CALL_ACTION_CHLD_1:
                                removeCalls(BluetoothHeadsetClientCall.CALL_STATE_ACTIVE);
                                changeCallsState(BluetoothHeadsetClientCall.CALL_STATE_WAITING,
                                        BluetoothHeadsetClientCall.CALL_STATE_ACTIVE);
                                clearPendingAction();
                                break;
                            case HeadsetClientHalConstants.CALL_ACTION_CHLD_2:
                                // no specific order for callsetup=0 and
                                // callheld=1
                                if (mIndicatorCallHeld ==
                                        HeadsetClientHalConstants.CALLHELD_HOLD_AND_ACTIVE) {
                                    clearPendingAction();
                                }
                                break;
                            case HeadsetClientHalConstants.CALL_ACTION_CHLD_3:
                                if (mIndicatorCallHeld ==
                                        HeadsetClientHalConstants.CALLHELD_NONE) {
                                    clearPendingAction();
                                }
                                break;
                            default:
                                Log.e(TAG, "Unexpected callsetup=0 while in action ACCEPT_CALL");
                                break;
                        }
                        break;
                    case REJECT_CALL:
                        switch ((Integer) mPendingAction.second) {
                            case HeadsetClientHalConstants.CALL_ACTION_CHUP:
                                removeCalls(BluetoothHeadsetClientCall.CALL_STATE_INCOMING);
                                clearPendingAction();
                                break;
                            case HeadsetClientHalConstants.CALL_ACTION_CHLD_0:
                                removeCalls(BluetoothHeadsetClientCall.CALL_STATE_WAITING);
                                clearPendingAction();
                                break;
                            default:
                                Log.e(TAG, "Unexpected callsetup=0 while in action REJECT_CALL");
                                break;
                        }
                        break;
                    case DIAL_NUMBER:
                    case DIAL_MEMORY:
                    case REDIAL:
                    case NO_ACTION:
                    case TERMINATE_CALL:
                        removeCalls(BluetoothHeadsetClientCall.CALL_STATE_INCOMING,
                                BluetoothHeadsetClientCall.CALL_STATE_DIALING,
                                BluetoothHeadsetClientCall.CALL_STATE_WAITING,
                                BluetoothHeadsetClientCall.CALL_STATE_ALERTING);
                        clearPendingAction();
                        break;
                    default:
                        Log.e(TAG, "Unexpected callsetup=0 while in action " +
                                mPendingAction.first);
                        break;
                }
                break;
            case HeadsetClientHalConstants.CALLSETUP_ALERTING:
                BluetoothHeadsetClientCall c =
                        getCall(BluetoothHeadsetClientCall.CALL_STATE_DIALING);
                if (c == null) {
                    if (mPendingAction.first == DIAL_NUMBER) {
                        addCall(BluetoothHeadsetClientCall.CALL_STATE_ALERTING,
                                (String) mPendingAction.second);
                    } else {
                        addCall(BluetoothHeadsetClientCall.CALL_STATE_ALERTING, "");
                    }
                } else {
                    setCallState(c, BluetoothHeadsetClientCall.CALL_STATE_ALERTING);
                }

                switch (mPendingAction.first) {
                    case DIAL_NUMBER:
                    case DIAL_MEMORY:
                    case REDIAL:
                        clearPendingAction();
                        break;
                    default:
                        break;
                }
                break;
            case HeadsetClientHalConstants.CALLSETUP_OUTGOING:
                if (mPendingAction.first == DIAL_NUMBER) {
                    addCall(BluetoothHeadsetClientCall.CALL_STATE_DIALING,
                            (String) mPendingAction.second);
                } else {
                    addCall(BluetoothHeadsetClientCall.CALL_STATE_DIALING, "");
                }
                break;
            case HeadsetClientHalConstants.CALLSETUP_INCOMING:
                if (getCall(BluetoothHeadsetClientCall.CALL_STATE_WAITING) == null)
                {
                    // will get number in clip if known
                    addCall(BluetoothHeadsetClientCall.CALL_STATE_INCOMING, "");
                }
                break;
            default:
                break;
        }

        updateCallsMultiParty();

        mIndicatorCallSetup = callsetup;
    }

    private void updateCallHeldIndicator(int callheld) {
        Log.d(TAG, "updateCallHeld " + callheld);

        if (waitForIndicators(-1, -1, callheld)) {
            return;
        }

        if (mQueryCallsSupported) {
            sendMessage(QUERY_CURRENT_CALLS);
            return;
        }

        switch (callheld) {
            case HeadsetClientHalConstants.CALLHELD_NONE:
                switch (mPendingAction.first) {
                    case REJECT_CALL:
                        removeCalls(BluetoothHeadsetClientCall.CALL_STATE_HELD);
                        clearPendingAction();
                        break;
                    case ACCEPT_CALL:
                        switch ((Integer) mPendingAction.second) {
                            case HeadsetClientHalConstants.CALL_ACTION_CHLD_1:
                                removeCalls(BluetoothHeadsetClientCall.CALL_STATE_ACTIVE);
                                changeCallsState(BluetoothHeadsetClientCall.CALL_STATE_HELD,
                                        BluetoothHeadsetClientCall.CALL_STATE_ACTIVE);
                                clearPendingAction();
                                break;
                            case HeadsetClientHalConstants.CALL_ACTION_CHLD_3:
                                changeCallsState(BluetoothHeadsetClientCall.CALL_STATE_HELD,
                                        BluetoothHeadsetClientCall.CALL_STATE_ACTIVE);
                                clearPendingAction();
                                break;
                            default:
                                break;
                        }
                        break;
                    case NO_ACTION:
                        if (mIndicatorCall == HeadsetClientHalConstants.CALL_CALLS_IN_PROGRESS &&
                                mIndicatorCallHeld == HeadsetClientHalConstants.CALLHELD_HOLD) {
                            changeCallsState(BluetoothHeadsetClientCall.CALL_STATE_HELD,
                                    BluetoothHeadsetClientCall.CALL_STATE_ACTIVE);
                            break;
                        }

                        removeCalls(BluetoothHeadsetClientCall.CALL_STATE_HELD);
                        break;
                    default:
                        Log.e(TAG, "Unexpected callheld=0 while in action " + mPendingAction.first);
                        break;
                }
                break;
            case HeadsetClientHalConstants.CALLHELD_HOLD_AND_ACTIVE:
                switch (mPendingAction.first) {
                    case ACCEPT_CALL:
                        if ((Integer) mPendingAction.second ==
                                HeadsetClientHalConstants.CALL_ACTION_CHLD_2) {
                            BluetoothHeadsetClientCall c =
                                    getCall(BluetoothHeadsetClientCall.CALL_STATE_WAITING);
                            if (c != null) { // accept
                                changeCallsState(BluetoothHeadsetClientCall.CALL_STATE_ACTIVE,
                                        BluetoothHeadsetClientCall.CALL_STATE_HELD);
                                setCallState(c, BluetoothHeadsetClientCall.CALL_STATE_ACTIVE);
                            } else { // swap
                                for (BluetoothHeadsetClientCall cc : mCalls.values()) {
                                    if (cc.getState() ==
                                            BluetoothHeadsetClientCall.CALL_STATE_ACTIVE) {
                                        setCallState(cc,
                                                BluetoothHeadsetClientCall.CALL_STATE_HELD);
                                    } else if (cc.getState() ==
                                            BluetoothHeadsetClientCall.CALL_STATE_HELD) {
                                        setCallState(cc,
                                                BluetoothHeadsetClientCall.CALL_STATE_ACTIVE);
                                    }
                                }
                            }
                            clearPendingAction();
                        }
                        break;
                    case NO_ACTION:
                        BluetoothHeadsetClientCall c =
                                getCall(BluetoothHeadsetClientCall.CALL_STATE_WAITING);
                        if (c != null) { // accept
                            changeCallsState(BluetoothHeadsetClientCall.CALL_STATE_ACTIVE,
                                    BluetoothHeadsetClientCall.CALL_STATE_HELD);
                            setCallState(c, BluetoothHeadsetClientCall.CALL_STATE_ACTIVE);
                            break;
                        }

                        // swap
                        for (BluetoothHeadsetClientCall cc : mCalls.values()) {
                            if (cc.getState() == BluetoothHeadsetClientCall.CALL_STATE_ACTIVE) {
                                setCallState(cc, BluetoothHeadsetClientCall.CALL_STATE_HELD);
                            } else if (cc.getState() == BluetoothHeadsetClientCall.CALL_STATE_HELD) {
                                setCallState(cc, BluetoothHeadsetClientCall.CALL_STATE_ACTIVE);
                            }
                        }
                        break;
                    case ENTER_PRIVATE_MODE:
                        for (BluetoothHeadsetClientCall cc : mCalls.values()) {
                            if (cc != (BluetoothHeadsetClientCall) mPendingAction.second) {
                                setCallState(cc, BluetoothHeadsetClientCall.CALL_STATE_HELD);
                            }
                        }
                        clearPendingAction();
                        break;
                    default:
                        Log.e(TAG, "Unexpected callheld=0 while in action " + mPendingAction.first);
                        break;
                }
                break;
            case HeadsetClientHalConstants.CALLHELD_HOLD:
                switch (mPendingAction.first) {
                    case DIAL_NUMBER:
                    case DIAL_MEMORY:
                    case REDIAL:
                        changeCallsState(BluetoothHeadsetClientCall.CALL_STATE_ACTIVE,
                                BluetoothHeadsetClientCall.CALL_STATE_HELD);
                        break;
                    case REJECT_CALL:
                        switch ((Integer) mPendingAction.second) {
                            case HeadsetClientHalConstants.CALL_ACTION_CHLD_1:
                                removeCalls(BluetoothHeadsetClientCall.CALL_STATE_ACTIVE);
                                changeCallsState(BluetoothHeadsetClientCall.CALL_STATE_HELD,
                                        BluetoothHeadsetClientCall.CALL_STATE_ACTIVE);
                                clearPendingAction();
                                break;
                            case HeadsetClientHalConstants.CALL_ACTION_CHLD_3:
                                changeCallsState(BluetoothHeadsetClientCall.CALL_STATE_HELD,
                                        BluetoothHeadsetClientCall.CALL_STATE_ACTIVE);
                                clearPendingAction();
                                break;
                            default:
                                break;
                        }
                        break;
                    case TERMINATE_CALL:
                    case NO_ACTION:
                        removeCalls(BluetoothHeadsetClientCall.CALL_STATE_ACTIVE);
                        break;
                    default:
                        Log.e(TAG, "Unexpected callheld=0 while in action " + mPendingAction.first);
                        break;
                }
                break;
            default:
                break;
        }

        updateCallsMultiParty();

        mIndicatorCallHeld = callheld;
    }

    private void updateRespAndHold(int resp_and_hold) {
        Log.d(TAG, "updatRespAndHold " + resp_and_hold);

        if (mQueryCallsSupported) {
            sendMessage(QUERY_CURRENT_CALLS);
            return;
        }

        BluetoothHeadsetClientCall c = null;

        switch (resp_and_hold) {
            case HeadsetClientHalConstants.RESP_AND_HOLD_HELD:
                // might be active if it was resp-and-hold before SLC created
                c = getCall(BluetoothHeadsetClientCall.CALL_STATE_INCOMING,
                        BluetoothHeadsetClientCall.CALL_STATE_ACTIVE);
                if (c != null) {
                    setCallState(c,
                            BluetoothHeadsetClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD);
                } else {
                    addCall(BluetoothHeadsetClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD, "");
                }
                break;
            case HeadsetClientHalConstants.RESP_AND_HOLD_ACCEPT:
                c = getCall(BluetoothHeadsetClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD);
                if (c != null) {
                    setCallState(c, BluetoothHeadsetClientCall.CALL_STATE_ACTIVE);
                }
                if (mPendingAction.first == ACCEPT_CALL &&
                        (Integer) mPendingAction.second ==
                        HeadsetClientHalConstants.CALL_ACTION_BTRH_1) {
                    clearPendingAction();
                }
                break;
            case HeadsetClientHalConstants.RESP_AND_HOLD_REJECT:
                removeCalls(BluetoothHeadsetClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD);
                break;
            default:
                break;
        }
    }

    private void updateClip(String number) {
        BluetoothHeadsetClientCall c = getCall(BluetoothHeadsetClientCall.CALL_STATE_INCOMING);

        if (c == null) {
            // MeeGo sends CLCC indicating waiting call followed by CLIP when call state changes
            // from waiting to incoming in 3WC scenarios. Handle this call state transfer here.
            BluetoothHeadsetClientCall cw = getCall(BluetoothHeadsetClientCall.CALL_STATE_WAITING);
            if(cw != null) {
                setCallState(cw, BluetoothHeadsetClientCall.CALL_STATE_INCOMING);
            }
            else {
                addCall(BluetoothHeadsetClientCall.CALL_STATE_INCOMING, number);
            }
        } else {
            c.setNumber(number);
            sendCallChangedIntent(c);
        }
    }

    private void addCallWaiting(String number) {
        if (getCall(BluetoothHeadsetClientCall.CALL_STATE_WAITING) == null) {
            addCall(BluetoothHeadsetClientCall.CALL_STATE_WAITING, number);
        }
    }

    // use ECS
    private boolean queryCallsStart() {
        Log.d(TAG, "queryCallsStart");

        // not supported
        if (mQueryCallsSupported == false) {
            return false;
        }

        clearPendingAction();

        // already started
        if (mCallsUpdate != null) {
            return true;
        }

        if (queryCurrentCallsNative()) {
            mCallsUpdate = new Hashtable<Integer, BluetoothHeadsetClientCall>();
            addQueuedAction(QUERY_CURRENT_CALLS, 0);
            return true;
        }

        Log.i(TAG, "updateCallsStart queryCurrentCallsNative failed");
        mQueryCallsSupported = false;
        mCallsUpdate = null;
        return false;
    }

    private void queryCallsDone() {
        Log.d(TAG, "queryCallsDone");
        Iterator<Hashtable.Entry<Integer, BluetoothHeadsetClientCall>> it;

        // check if any call was removed
        it = mCalls.entrySet().iterator();
        while (it.hasNext()) {
            Hashtable.Entry<Integer, BluetoothHeadsetClientCall> entry = it.next();

            if (mCallsUpdate.containsKey(entry.getKey())) {
                continue;
            }

            Log.d(TAG, "updateCallsDone call removed id:" + entry.getValue().getId());
            BluetoothHeadsetClientCall c = entry.getValue();

            setCallState(c, BluetoothHeadsetClientCall.CALL_STATE_TERMINATED);
        }

        /* check if any calls changed or new call is present */
        it = mCallsUpdate.entrySet().iterator();
        while (it.hasNext()) {
            Hashtable.Entry<Integer, BluetoothHeadsetClientCall> entry = it.next();

            if (mCalls.containsKey(entry.getKey())) {
                // avoid losing number if was not present in clcc
                if (entry.getValue().getNumber().equals("")) {
                    entry.getValue().setNumber(mCalls.get(entry.getKey()).getNumber());
                }

                if (mCalls.get(entry.getKey()).equals(entry.getValue())) {
                    continue;
                }

                Log.d(TAG, "updateCallsDone call changed id:" + entry.getValue().getId());
                sendCallChangedIntent(entry.getValue());
            } else {
                Log.d(TAG, "updateCallsDone new call id:" + entry.getValue().getId());
                sendCallChangedIntent(entry.getValue());
            }
        }

        mCalls = mCallsUpdate;
        mCallsUpdate = null;

        if (loopQueryCalls()) {
            Log.d(TAG, "queryCallsDone ambigious calls, starting call query loop");
            sendMessageDelayed(QUERY_CURRENT_CALLS, 1523);
        }
    }

    private void queryCallsUpdate(int id, int state, String number, boolean multiParty,
            boolean outgoing) {
        Log.d(TAG, "queryCallsUpdate: " + id);

        // should not happen
        if (mCallsUpdate == null) {
            return;
        }

        mCallsUpdate.put(id, new BluetoothHeadsetClientCall(mCurrentDevice, id, state, number,
                multiParty, outgoing));
    }

    // helper function for determining if query calls should be looped
    private boolean loopQueryCalls() {
        if (callsInState(BluetoothHeadsetClientCall.CALL_STATE_ACTIVE) > 1) {
            return true;
        }

        // Workaround for Windows Phone 7.8 not sending callsetup=0 after
        // rejecting incoming call in 3WC use case (when no active calls present).
        // Fixes both, AG and HF rejecting the call.
        BluetoothHeadsetClientCall c = getCall(BluetoothHeadsetClientCall.CALL_STATE_INCOMING);
        if (c != null && mIndicatorCallSetup == HeadsetClientHalConstants.CALLSETUP_NONE)
            return true;

        return false;
    }

    private void acceptCall(int flag, boolean retry) {
        int action;

        Log.d(TAG, "acceptCall: (" + flag + ")");

        BluetoothHeadsetClientCall c = getCall(BluetoothHeadsetClientCall.CALL_STATE_INCOMING,
                BluetoothHeadsetClientCall.CALL_STATE_WAITING);
        if (c == null) {
            c = getCall(BluetoothHeadsetClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD,
                    BluetoothHeadsetClientCall.CALL_STATE_HELD);

            if (c == null) {
                return;
            }
        }

        switch (c.getState()) {
            case BluetoothHeadsetClientCall.CALL_STATE_INCOMING:
                if (flag != BluetoothHeadsetClient.CALL_ACCEPT_NONE) {
                    return;
                }

                // Some NOKIA phones with Windows Phone 7.8 and MeeGo requires CHLD=1
                // for accepting incoming call if it is the only call present after
                // second active remote has disconnected (3WC scenario - call state
                // changes from waiting to incoming). On the other hand some Android
                // phones and iPhone requires ATA. Try to handle those gently by
                // first issuing ATA. Failing means that AG is probably one of those
                // phones that requires CHLD=1. Handle this case when we are retrying.
                // Accepting incoming calls when there is held one and
                // no active should also be handled by ATA.
                action = HeadsetClientHalConstants.CALL_ACTION_ATA;

                if (mCalls.size() == 1 && retry) {
                    action = HeadsetClientHalConstants.CALL_ACTION_CHLD_1;
                }
                break;
            case BluetoothHeadsetClientCall.CALL_STATE_WAITING:
                if (callsInState(BluetoothHeadsetClientCall.CALL_STATE_ACTIVE) == 0) {
                    // if no active calls present only plain accept is allowed
                    if (flag != BluetoothHeadsetClient.CALL_ACCEPT_NONE) {
                        return;
                    }

                    // Some phones (WP7) require ATA instead of CHLD=2
                    // to accept waiting call if no active calls are present.
                    if (retry) {
                        action = HeadsetClientHalConstants.CALL_ACTION_ATA;
                    } else {
                        action = HeadsetClientHalConstants.CALL_ACTION_CHLD_2;
                    }
                    break;
                }

                // if active calls are present action must be selected
                if (flag == BluetoothHeadsetClient.CALL_ACCEPT_HOLD) {
                    action = HeadsetClientHalConstants.CALL_ACTION_CHLD_2;
                } else if (flag == BluetoothHeadsetClient.CALL_ACCEPT_TERMINATE) {
                    action = HeadsetClientHalConstants.CALL_ACTION_CHLD_1;
                } else {
                    return;
                }
                break;
            case BluetoothHeadsetClientCall.CALL_STATE_HELD:
                if (flag == BluetoothHeadsetClient.CALL_ACCEPT_HOLD) {
                    action = HeadsetClientHalConstants.CALL_ACTION_CHLD_2;
                } else if (flag == BluetoothHeadsetClient.CALL_ACCEPT_TERMINATE) {
                    action = HeadsetClientHalConstants.CALL_ACTION_CHLD_1;
                } else if (getCall(BluetoothHeadsetClientCall.CALL_STATE_ACTIVE) != null) {
                    action = HeadsetClientHalConstants.CALL_ACTION_CHLD_3;
                } else {
                    action = HeadsetClientHalConstants.CALL_ACTION_CHLD_2;
                }
                break;
            case BluetoothHeadsetClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD:
                if (flag != BluetoothHeadsetClient.CALL_ACCEPT_NONE) {
                    return;
                }
                action = HeadsetClientHalConstants.CALL_ACTION_BTRH_1;
                break;
            case BluetoothHeadsetClientCall.CALL_STATE_ALERTING:
            case BluetoothHeadsetClientCall.CALL_STATE_ACTIVE:
            case BluetoothHeadsetClientCall.CALL_STATE_DIALING:
            default:
                return;
        }

        if (flag == BluetoothHeadsetClient.CALL_ACCEPT_HOLD) {
            // HFP is disabled when a call is put on hold to ensure correct audio routing for
            // cellular calls accepted while an HFP call is in progress. Reenable HFP when the HFP
            // call is put off hold.
            Log.d(TAG,"hfp_enable=true");
            mAudioManager.setParameters("hfp_enable=true");
        }

        if (handleCallActionNative(action, 0)) {
            addQueuedAction(ACCEPT_CALL, action);
        } else {
            Log.e(TAG, "ERROR: Couldn't accept a call, action:" + action);
        }
    }

    private void rejectCall() {
        int action;

        Log.d(TAG, "rejectCall");

        BluetoothHeadsetClientCall c =
                getCall(BluetoothHeadsetClientCall.CALL_STATE_INCOMING,
                BluetoothHeadsetClientCall.CALL_STATE_WAITING,
                BluetoothHeadsetClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD,
                BluetoothHeadsetClientCall.CALL_STATE_HELD);
        if (c == null) {
            return;
        }

        switch (c.getState()) {
            case BluetoothHeadsetClientCall.CALL_STATE_INCOMING:
                action = HeadsetClientHalConstants.CALL_ACTION_CHUP;
                break;
            case BluetoothHeadsetClientCall.CALL_STATE_WAITING:
            case BluetoothHeadsetClientCall.CALL_STATE_HELD:
                action = HeadsetClientHalConstants.CALL_ACTION_CHLD_0;
                break;
            case BluetoothHeadsetClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD:
                action = HeadsetClientHalConstants.CALL_ACTION_BTRH_2;
                break;
            case BluetoothHeadsetClientCall.CALL_STATE_ACTIVE:
            case BluetoothHeadsetClientCall.CALL_STATE_DIALING:
            case BluetoothHeadsetClientCall.CALL_STATE_ALERTING:
            default:
                return;
        }

        if (handleCallActionNative(action, 0)) {
            addQueuedAction(REJECT_CALL, action);
        } else {
            Log.e(TAG, "ERROR: Couldn't reject a call, action:" + action);
        }
    }

    private void holdCall() {
        int action;

        Log.d(TAG, "holdCall");

        BluetoothHeadsetClientCall c = getCall(BluetoothHeadsetClientCall.CALL_STATE_INCOMING);
        if (c != null) {
            action = HeadsetClientHalConstants.CALL_ACTION_BTRH_0;
        } else {
            c = getCall(BluetoothHeadsetClientCall.CALL_STATE_ACTIVE);
            if (c == null) {
                return;
            }

            action = HeadsetClientHalConstants.CALL_ACTION_CHLD_2;
        }

        // Set HFP enable to false in case the call is being held to accept a cellular call. This
        // allows the cellular call's audio to be correctly routed.
        Log.d(TAG,"hfp_enable=false");
        mAudioManager.setParameters("hfp_enable=false");

        if (handleCallActionNative(action, 0)) {
            addQueuedAction(HOLD_CALL, action);
        } else {
            Log.e(TAG, "ERROR: Couldn't hold a call, action:" + action);
        }
    }

    private void terminateCall(int idx) {
        Log.d(TAG, "terminateCall: " + idx);

        if (idx == 0) {
            int action = HeadsetClientHalConstants.CALL_ACTION_CHUP;

            BluetoothHeadsetClientCall c = getCall(
                    BluetoothHeadsetClientCall.CALL_STATE_DIALING,
                    BluetoothHeadsetClientCall.CALL_STATE_ALERTING);
            if (c != null) {
                if (handleCallActionNative(action, 0)) {
                    addQueuedAction(TERMINATE_CALL, action);
                } else {
                    Log.e(TAG, "ERROR: Couldn't terminate outgoing call");
                }
            }

            if (callsInState(BluetoothHeadsetClientCall.CALL_STATE_ACTIVE) > 0) {
                if (handleCallActionNative(action, 0)) {
                    addQueuedAction(TERMINATE_CALL, action);
                } else {
                    Log.e(TAG, "ERROR: Couldn't terminate active calls");
                }
            }
        } else {
            int action;
            BluetoothHeadsetClientCall c = mCalls.get(idx);

            if (c == null) {
                return;
            }

            switch (c.getState()) {
                case BluetoothHeadsetClientCall.CALL_STATE_ACTIVE:
                    action = HeadsetClientHalConstants.CALL_ACTION_CHLD_1x;
                    break;
                case BluetoothHeadsetClientCall.CALL_STATE_DIALING:
                case BluetoothHeadsetClientCall.CALL_STATE_ALERTING:
                    action = HeadsetClientHalConstants.CALL_ACTION_CHUP;
                    break;
                default:
                    return;
            }

            if (handleCallActionNative(action, idx)) {
                if (action == HeadsetClientHalConstants.CALL_ACTION_CHLD_1x) {
                    addQueuedAction(TERMINATE_SPECIFIC_CALL, c);
                } else {
                    addQueuedAction(TERMINATE_CALL, action);
                }
            } else {
                Log.e(TAG, "ERROR: Couldn't terminate a call, action:" + action + " id:" + idx);
            }
        }
    }

    private void enterPrivateMode(int idx) {
        Log.d(TAG, "enterPrivateMode: " + idx);

        BluetoothHeadsetClientCall c = mCalls.get(idx);

        if (c == null) {
            return;
        }

        if (c.getState() != BluetoothHeadsetClientCall.CALL_STATE_ACTIVE) {
            return;
        }

        if (!c.isMultiParty()) {
            return;
        }

        if (handleCallActionNative(HeadsetClientHalConstants.CALL_ACTION_CHLD_2x, idx)) {
            addQueuedAction(ENTER_PRIVATE_MODE, c);
        } else {
            Log.e(TAG, "ERROR: Couldn't enter private " + " id:" + idx);
        }
    }

    private void explicitCallTransfer() {
        Log.d(TAG, "explicitCallTransfer");

        // can't transfer call if there is not enough call parties
        if (mCalls.size() < 2) {
            return;
        }

        if (handleCallActionNative(HeadsetClientHalConstants.CALL_ACTION_CHLD_4, -1)) {
            addQueuedAction(EXPLICIT_CALL_TRANSFER);
        } else {
            Log.e(TAG, "ERROR: Couldn't transfer call");
        }
    }

    public Bundle getCurrentAgFeatures()
    {
        Bundle b = new Bundle();
        if ((mPeerFeatures & HeadsetClientHalConstants.PEER_FEAT_3WAY) ==
                HeadsetClientHalConstants.PEER_FEAT_3WAY) {
            b.putBoolean(BluetoothHeadsetClient.EXTRA_AG_FEATURE_3WAY_CALLING, true);
        }
        if ((mPeerFeatures & HeadsetClientHalConstants.PEER_FEAT_VREC) ==
                HeadsetClientHalConstants.PEER_FEAT_VREC) {
            b.putBoolean(BluetoothHeadsetClient.EXTRA_AG_FEATURE_VOICE_RECOGNITION, true);
        }
        if ((mPeerFeatures & HeadsetClientHalConstants.PEER_FEAT_VTAG) ==
                HeadsetClientHalConstants.PEER_FEAT_VTAG) {
            b.putBoolean(BluetoothHeadsetClient.EXTRA_AG_FEATURE_ATTACH_NUMBER_TO_VT, true);
        }
        if ((mPeerFeatures & HeadsetClientHalConstants.PEER_FEAT_REJECT) ==
                HeadsetClientHalConstants.PEER_FEAT_REJECT) {
            b.putBoolean(BluetoothHeadsetClient.EXTRA_AG_FEATURE_REJECT_CALL, true);
        }
        if ((mPeerFeatures & HeadsetClientHalConstants.PEER_FEAT_ECC) ==
                HeadsetClientHalConstants.PEER_FEAT_ECC) {
            b.putBoolean(BluetoothHeadsetClient.EXTRA_AG_FEATURE_ECC, true);
        }

        // add individual CHLD support extras
        if ((mChldFeatures & HeadsetClientHalConstants.CHLD_FEAT_HOLD_ACC) ==
                HeadsetClientHalConstants.CHLD_FEAT_HOLD_ACC) {
            b.putBoolean(BluetoothHeadsetClient.EXTRA_AG_FEATURE_ACCEPT_HELD_OR_WAITING_CALL, true);
        }
        if ((mChldFeatures & HeadsetClientHalConstants.CHLD_FEAT_REL) ==
                HeadsetClientHalConstants.CHLD_FEAT_REL) {
            b.putBoolean(BluetoothHeadsetClient.EXTRA_AG_FEATURE_RELEASE_HELD_OR_WAITING_CALL, true);
        }
        if ((mChldFeatures & HeadsetClientHalConstants.CHLD_FEAT_REL_ACC) ==
                HeadsetClientHalConstants.CHLD_FEAT_REL_ACC) {
            b.putBoolean(BluetoothHeadsetClient.EXTRA_AG_FEATURE_RELEASE_AND_ACCEPT, true);
        }
        if ((mChldFeatures & HeadsetClientHalConstants.CHLD_FEAT_MERGE) ==
                HeadsetClientHalConstants.CHLD_FEAT_MERGE) {
            b.putBoolean(BluetoothHeadsetClient.EXTRA_AG_FEATURE_MERGE, true);
        }
        if ((mChldFeatures & HeadsetClientHalConstants.CHLD_FEAT_MERGE_DETACH) ==
                HeadsetClientHalConstants.CHLD_FEAT_MERGE_DETACH) {
            b.putBoolean(BluetoothHeadsetClient.EXTRA_AG_FEATURE_MERGE_AND_DETACH, true);
        }

        return b;
    }

    private HeadsetClientStateMachine(HeadsetClientService context) {
        super(TAG);
        mService = context;

        mAdapter = BluetoothAdapter.getDefaultAdapter();
        mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        mAudioState = BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED;
        mAudioWbs = false;

        mAudioRouteAllowed = context.getResources().getBoolean(
                R.bool.headset_client_initial_audio_route_allowed);

        mTelecomManager = (TelecomManager) context.getSystemService(context.TELECOM_SERVICE);

        mIndicatorNetworkState = HeadsetClientHalConstants.NETWORK_STATE_NOT_AVAILABLE;
        mIndicatorNetworkType = HeadsetClientHalConstants.SERVICE_TYPE_HOME;
        mIndicatorNetworkSignal = 0;
        mIndicatorBatteryLevel = 0;

        // all will be set on connected
        mIndicatorCall = -1;
        mIndicatorCallSetup = -1;
        mIndicatorCallHeld = -1;

        mMaxAmVcVol = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL);
        mMinAmVcVol = mAudioManager.getStreamMinVolume(AudioManager.STREAM_VOICE_CALL);

        mOperatorName = null;
        mSubscriberInfo = null;

        mVoiceRecognitionActive = HeadsetClientHalConstants.VR_STATE_STOPPED;
        mInBandRingtone = HeadsetClientHalConstants.IN_BAND_RING_NOT_PROVIDED;

        mQueuedActions = new LinkedList<Pair<Integer, Object>>();
        clearPendingAction();

        mCalls = new Hashtable<Integer, BluetoothHeadsetClientCall>();
        mCallsUpdate = null;
        mQueryCallsSupported = true;

        initializeNative();
        mNativeAvailable = true;

        mDisconnected = new Disconnected();
        mConnecting = new Connecting();
        mConnected = new Connected();
        mAudioOn = new AudioOn();

        addState(mDisconnected);
        addState(mConnecting);
        addState(mConnected);
        addState(mAudioOn, mConnected);

        setInitialState(mDisconnected);
    }

    static HeadsetClientStateMachine make(HeadsetClientService context) {
        Log.d(TAG, "make");
        HeadsetClientStateMachine hfcsm = new HeadsetClientStateMachine(context);
        hfcsm.start();
        return hfcsm;
    }

    public void doQuit() {
        quitNow();
    }

    public void cleanup() {
        if (mNativeAvailable) {
            cleanupNative();
            mNativeAvailable = false;
        }
    }

    private int hfToAmVol(int hfVol) {
        int amRange = mMaxAmVcVol - mMinAmVcVol;
        int hfRange = MAX_HFP_SCO_VOICE_CALL_VOLUME - MIN_HFP_SCO_VOICE_CALL_VOLUME;
        int amOffset =
            (amRange * (hfVol - MIN_HFP_SCO_VOICE_CALL_VOLUME)) / hfRange;
        int amVol = mMinAmVcVol + amOffset;
        Log.d(TAG, "HF -> AM " + hfVol + " " + amVol);
        return amVol;
    }

    private int amToHfVol(int amVol) {
        int amRange = mMaxAmVcVol - mMinAmVcVol;
        int hfRange = MAX_HFP_SCO_VOICE_CALL_VOLUME - MIN_HFP_SCO_VOICE_CALL_VOLUME;
        int hfOffset = (hfRange * (amVol - mMinAmVcVol)) / amRange;
        int hfVol = MIN_HFP_SCO_VOICE_CALL_VOLUME + hfOffset;
        Log.d(TAG, "AM -> HF " + amVol + " " + hfVol);
        return hfVol;
    }

    private class Disconnected extends State {
        @Override
        public void enter() {
            Log.d(TAG, "Enter Disconnected: " + getCurrentMessage().what);

            // cleanup
            mIndicatorNetworkState = HeadsetClientHalConstants.NETWORK_STATE_NOT_AVAILABLE;
            mIndicatorNetworkType = HeadsetClientHalConstants.SERVICE_TYPE_HOME;
            mIndicatorNetworkSignal = 0;
            mIndicatorBatteryLevel = 0;

            mAudioWbs = false;

            // will be set on connect
            mIndicatorCall = -1;
            mIndicatorCallSetup = -1;
            mIndicatorCallHeld = -1;

            mOperatorName = null;
            mSubscriberInfo = null;

            mQueuedActions = new LinkedList<Pair<Integer, Object>>();
            clearPendingAction();

            mVoiceRecognitionActive = HeadsetClientHalConstants.VR_STATE_STOPPED;
            mInBandRingtone = HeadsetClientHalConstants.IN_BAND_RING_NOT_PROVIDED;

            mCalls = new Hashtable<Integer, BluetoothHeadsetClientCall>();
            mCallsUpdate = null;
            mQueryCallsSupported = true;

            mPeerFeatures = 0;
            mChldFeatures = 0;

            removeMessages(QUERY_CURRENT_CALLS);
        }

        @Override
        public synchronized boolean processMessage(Message message) {
            Log.d(TAG, "Disconnected process message: " + message.what);

            if (mCurrentDevice != null) {
                Log.e(TAG, "ERROR: current device not null in Disconnected");
                return NOT_HANDLED;
            }

            switch (message.what) {
                case CONNECT:
                    BluetoothDevice device = (BluetoothDevice) message.obj;

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

                    if (!connectNative(getByteAddress(device))) {
                        broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED,
                                BluetoothProfile.STATE_CONNECTING);
                        break;
                    }

                    mCurrentDevice = device;
                    transitionTo(mConnecting);
                    break;
                case DISCONNECT:
                    // ignore
                    break;
                case STACK_EVENT:
                    StackEvent event = (StackEvent) message.obj;
                    if (DBG) {
                        Log.d(TAG, "Stack event type: " + event.type);
                    }
                    switch (event.type) {
                        case EVENT_TYPE_CONNECTION_STATE_CHANGED:
                            Log.d(TAG, "Disconnected: Connection " + event.device
                                    + " state changed:" + event.valueInt);
                            processConnectionEvent(event.valueInt, event.device);
                            break;
                        default:
                            Log.e(TAG, "Disconnected: Unexpected stack event: " + event.type);
                            break;
                    }
                    break;
                default:
                    return NOT_HANDLED;
            }
            return HANDLED;
        }

        // in Disconnected state
        private void processConnectionEvent(int state, BluetoothDevice device)
        {
            switch (state) {
                case HeadsetClientHalConstants.CONNECTION_STATE_CONNECTED:
                    Log.w(TAG, "HFPClient Connecting from Disconnected state");
                    if (okToConnect(device)) {
                        Log.i(TAG, "Incoming AG accepted");
                        broadcastConnectionState(device, BluetoothProfile.STATE_CONNECTING,
                                BluetoothProfile.STATE_DISCONNECTED);
                        mCurrentDevice = device;
                        transitionTo(mConnecting);
                    } else {
                        Log.i(TAG, "Incoming AG rejected. priority=" + mService.getPriority(device)
                                +
                                " bondState=" + device.getBondState());
                        // reject the connection and stay in Disconnected state
                        // itself
                        disconnectNative(getByteAddress(device));
                        // the other profile connection should be initiated
                        AdapterService adapterService = AdapterService.getAdapterService();
                        if (adapterService != null) {
                            adapterService.connectOtherProfile(device,
                                    AdapterService.PROFILE_CONN_REJECTED);
                        }
                    }
                    break;
                case HeadsetClientHalConstants.CONNECTION_STATE_CONNECTING:
                case HeadsetClientHalConstants.CONNECTION_STATE_DISCONNECTED:
                case HeadsetClientHalConstants.CONNECTION_STATE_DISCONNECTING:
                default:
                    Log.i(TAG, "ignoring state: " + state);
                    break;
            }
        }

        @Override
        public void exit() {
            Log.d(TAG, "Exit Disconnected: " + getCurrentMessage().what);
        }
    }

    private class Connecting extends State {
        @Override
        public void enter() {
            Log.d(TAG, "Enter Connecting: " + getCurrentMessage().what);
        }

        @Override
        public synchronized boolean processMessage(Message message) {
            Log.d(TAG, "Connecting process message: " + message.what);

            boolean retValue = HANDLED;
            switch (message.what) {
                case CONNECT:
                case CONNECT_AUDIO:
                case DISCONNECT:
                    deferMessage(message);
                    break;
                case STACK_EVENT:
                    StackEvent event = (StackEvent) message.obj;
                    if (DBG) {
                        Log.d(TAG, "Connecting: event type: " + event.type);
                    }
                    switch (event.type) {
                        case EVENT_TYPE_CONNECTION_STATE_CHANGED:
                            Log.d(TAG, "Connecting: Connection " + event.device + " state changed:"
                                    + event.valueInt);
                            processConnectionEvent(event.valueInt, event.valueInt2,
                                    event.valueInt3, event.device);
                            break;
                        case EVENT_TYPE_AUDIO_STATE_CHANGED:
                        case EVENT_TYPE_VR_STATE_CHANGED:
                        case EVENT_TYPE_NETWORK_STATE:
                        case EVENT_TYPE_ROAMING_STATE:
                        case EVENT_TYPE_NETWORK_SIGNAL:
                        case EVENT_TYPE_BATTERY_LEVEL:
                        case EVENT_TYPE_CALL:
                        case EVENT_TYPE_CALLSETUP:
                        case EVENT_TYPE_CALLHELD:
                        case EVENT_TYPE_RESP_AND_HOLD:
                        case EVENT_TYPE_CLIP:
                        case EVENT_TYPE_CALL_WAITING:
                        case EVENT_TYPE_VOLUME_CHANGED:
                        case EVENT_TYPE_IN_BAND_RING:
                            deferMessage(message);
                            break;
                        case EVENT_TYPE_CMD_RESULT:
                        case EVENT_TYPE_SUBSCRIBER_INFO:
                        case EVENT_TYPE_CURRENT_CALLS:
                        case EVENT_TYPE_OPERATOR_NAME:
                        default:
                            Log.e(TAG, "Connecting: ignoring stack event: " + event.type);
                            break;
                    }
                    break;
                default:
                    return NOT_HANDLED;
            }
            return retValue;
        }

        // in Connecting state
        private void processConnectionEvent(int state, int peer_feat, int chld_feat, BluetoothDevice device) {
            switch (state) {
                case HeadsetClientHalConstants.CONNECTION_STATE_DISCONNECTED:
                    broadcastConnectionState(mCurrentDevice, BluetoothProfile.STATE_DISCONNECTED,
                            BluetoothProfile.STATE_CONNECTING);
                    mCurrentDevice = null;
                    transitionTo(mDisconnected);
                    break;
                case HeadsetClientHalConstants.CONNECTION_STATE_SLC_CONNECTED:
                    Log.w(TAG, "HFPClient Connected from Connecting state");

                    mPeerFeatures = peer_feat;
                    mChldFeatures = chld_feat;

                    broadcastConnectionState(mCurrentDevice, BluetoothProfile.STATE_CONNECTED,
                            BluetoothProfile.STATE_CONNECTING);
                    // Send AT+NREC to remote if supported by audio
                    if (HeadsetClientHalConstants.HANDSFREECLIENT_NREC_SUPPORTED &&
                            ((mPeerFeatures & HeadsetClientHalConstants.PEER_FEAT_ECNR) ==
                                    HeadsetClientHalConstants.PEER_FEAT_ECNR)) {
                        if (sendATCmdNative(HeadsetClientHalConstants.HANDSFREECLIENT_AT_CMD_NREC,
                            1 , 0, null)) {
                            addQueuedAction(DISABLE_NREC);
                        } else {
                            Log.e(TAG, "Failed to send NREC");
                        }
                    }
                    transitionTo(mConnected);

                    int amVol = mAudioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL);
                    sendMessage(
                            obtainMessage(HeadsetClientStateMachine.SET_SPEAKER_VOLUME, amVol, 0));
                    // Mic is either in ON state (full volume) or OFF state. There is no way in
                    // Android to change the MIC volume.
                    sendMessage(obtainMessage(HeadsetClientStateMachine.SET_MIC_VOLUME,
                            mAudioManager.isMicrophoneMute() ? 0 : 15, 0));

                    // query subscriber info
                    sendMessage(HeadsetClientStateMachine.SUBSCRIBER_INFO);
                    break;
                case HeadsetClientHalConstants.CONNECTION_STATE_CONNECTED:
                    if (!mCurrentDevice.equals(device)) {
                        Log.w(TAG, "incoming connection event, device: " + device);

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

                        mCurrentDevice = device;
                    }
                    break;
                case HeadsetClientHalConstants.CONNECTION_STATE_CONNECTING:
                    /* outgoing connecting started */
                    Log.d(TAG, "outgoing connection started, ignore");
                    break;
                case HeadsetClientHalConstants.CONNECTION_STATE_DISCONNECTING:
                default:
                    Log.e(TAG, "Incorrect state: " + state);
                    break;
            }
        }

        @Override
        public void exit() {
            Log.d(TAG, "Exit Connecting: " + getCurrentMessage().what);
        }
    }

    private class Connected extends State {
        @Override
        public void enter() {
            Log.d(TAG, "Enter Connected: " + getCurrentMessage().what);

            mAudioWbs = false;
        }

        @Override
        public synchronized boolean processMessage(Message message) {
            Log.d(TAG, "Connected process message: " + message.what);
            if (DBG) {
                if (mCurrentDevice == null) {
                    Log.d(TAG, "ERROR: mCurrentDevice is null in Connected");
                    return NOT_HANDLED;
                }
            }

            switch (message.what) {
                case CONNECT:
                    BluetoothDevice device = (BluetoothDevice) message.obj;
                    if (mCurrentDevice.equals(device)) {
                        // already connected to this device, do nothing
                        break;
                    }

                    if (!disconnectNative(getByteAddress(mCurrentDevice))) {
                        // if succeed this will be handled from disconnected
                        // state
                        broadcastConnectionState(device, BluetoothProfile.STATE_CONNECTING,
                                BluetoothProfile.STATE_DISCONNECTED);
                        broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED,
                                BluetoothProfile.STATE_CONNECTING);
                        break;
                    }

                    // will be handled when entered disconnected
                    deferMessage(message);
                    break;
                case DISCONNECT:
                    BluetoothDevice dev = (BluetoothDevice) message.obj;
                    if (!mCurrentDevice.equals(dev)) {
                        break;
                    }
                    broadcastConnectionState(dev, BluetoothProfile.STATE_DISCONNECTING,
                            BluetoothProfile.STATE_CONNECTED);
                    if (!disconnectNative(getByteAddress(dev))) {
                        // disconnecting failed
                        broadcastConnectionState(dev, BluetoothProfile.STATE_CONNECTED,
                                BluetoothProfile.STATE_DISCONNECTED);
                        break;
                    }
                    break;
                case CONNECT_AUDIO:
                    // TODO: handle audio connection failure
                    if (!connectAudioNative(getByteAddress(mCurrentDevice))) {
                        Log.e(TAG, "ERROR: Couldn't connect Audio.");
                    }
                    break;
                case DISCONNECT_AUDIO:
                    // TODO: handle audio disconnection failure
                    if (!disconnectAudioNative(getByteAddress(mCurrentDevice))) {
                        Log.e(TAG, "ERROR: Couldn't connect Audio.");
                    }
                    break;
                case VOICE_RECOGNITION_START:
                    if (mVoiceRecognitionActive == HeadsetClientHalConstants.VR_STATE_STOPPED) {
                        if (startVoiceRecognitionNative()) {
                            addQueuedAction(VOICE_RECOGNITION_START);
                        } else {
                            Log.e(TAG, "ERROR: Couldn't start voice recognition");
                        }
                    }
                    break;
                case VOICE_RECOGNITION_STOP:
                    if (mVoiceRecognitionActive == HeadsetClientHalConstants.VR_STATE_STARTED) {
                        if (stopVoiceRecognitionNative()) {
                            addQueuedAction(VOICE_RECOGNITION_STOP);
                        } else {
                            Log.e(TAG, "ERROR: Couldn't stop voice recognition");
                        }
                    }
                    break;
                // Called only for Mute/Un-mute - Mic volume change is not allowed.
                case SET_MIC_VOLUME:
                    if (mVgmFromStack) {
                        mVgmFromStack = false;
                        break;
                    }
                    if (setVolumeNative(HeadsetClientHalConstants.VOLUME_TYPE_MIC, message.arg1)) {
                        addQueuedAction(SET_MIC_VOLUME);
                    }
                    break;
                case SET_SPEAKER_VOLUME:
                    // This message should always contain the volume in AudioManager max normalized.
                    int amVol = message.arg1;
                    int hfVol = amToHfVol(amVol);
                    Log.d(TAG,"HF volume is set to " + hfVol);
                    mAudioManager.setParameters("hfp_volume=" + hfVol);
                    if (mVgsFromStack) {
                        mVgsFromStack = false;
                        break;
                    }
                    if (setVolumeNative(HeadsetClientHalConstants.VOLUME_TYPE_SPK, hfVol)) {
                        addQueuedAction(SET_SPEAKER_VOLUME);
                    }
                    break;
                case REDIAL:
                    if (dialNative(null)) {
                        addQueuedAction(REDIAL);
                    } else {
                        Log.e(TAG, "ERROR: Cannot redial");
                    }
                    break;
                case DIAL_NUMBER:
                    if (dialNative((String) message.obj)) {
                        addQueuedAction(DIAL_NUMBER, message.obj);
                    } else {
                        Log.e(TAG, "ERROR: Cannot dial with a given number:" + (String) message.obj);
                    }
                    break;
                case DIAL_MEMORY:
                    if (dialMemoryNative(message.arg1)) {
                        addQueuedAction(DIAL_MEMORY);
                    } else {
                        Log.e(TAG, "ERROR: Cannot dial with a given location:" + message.arg1);
                    }
                    break;
                case ACCEPT_CALL:
                    acceptCall(message.arg1, false);
                    break;
                case REJECT_CALL:
                    rejectCall();
                    break;
                case HOLD_CALL:
                    holdCall();
                    break;
                case TERMINATE_CALL:
                    terminateCall(message.arg1);
                    break;
                case ENTER_PRIVATE_MODE:
                    enterPrivateMode(message.arg1);
                    break;
                case EXPLICIT_CALL_TRANSFER:
                    explicitCallTransfer();
                    break;
                case SEND_DTMF:
                    if (sendDtmfNative((byte) message.arg1)) {
                        addQueuedAction(SEND_DTMF);
                    } else {
                        Log.e(TAG, "ERROR: Couldn't send DTMF");
                    }
                    break;
                case SUBSCRIBER_INFO:
                    if (retrieveSubscriberInfoNative()) {
                        addQueuedAction(SUBSCRIBER_INFO);
                    } else {
                        Log.e(TAG, "ERROR: Couldn't retrieve subscriber info");
                    }
                    break;
                case LAST_VTAG_NUMBER:
                    if (requestLastVoiceTagNumberNative()) {
                        addQueuedAction(LAST_VTAG_NUMBER);
                    } else {
                        Log.e(TAG, "ERROR: Couldn't get last VTAG number");
                    }
                    break;
                case QUERY_CURRENT_CALLS:
                    queryCallsStart();
                    break;
                case STACK_EVENT:
                    Intent intent = null;
                    StackEvent event = (StackEvent) message.obj;
                    if (DBG) {
                        Log.d(TAG, "Connected: event type: " + event.type);
                    }

                    switch (event.type) {
                        case EVENT_TYPE_CONNECTION_STATE_CHANGED:
                            Log.d(TAG, "Connected: Connection state changed: " + event.device
                                    + ": " + event.valueInt);
                            processConnectionEvent(event.valueInt, event.device);
                            break;
                        case EVENT_TYPE_AUDIO_STATE_CHANGED:
                            Log.d(TAG, "Connected: Audio state changed: " + event.device + ": "
                                    + event.valueInt);
                            processAudioEvent(event.valueInt, event.device);
                            break;
                        case EVENT_TYPE_NETWORK_STATE:
                            Log.d(TAG, "Connected: Network state: " + event.valueInt);

                            mIndicatorNetworkState = event.valueInt;

                            intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT);
                            intent.putExtra(BluetoothHeadsetClient.EXTRA_NETWORK_STATUS,
                                    event.valueInt);

                            if (mIndicatorNetworkState ==
                                    HeadsetClientHalConstants.NETWORK_STATE_NOT_AVAILABLE) {
                                mOperatorName = null;
                                intent.putExtra(BluetoothHeadsetClient.EXTRA_OPERATOR_NAME,
                                        mOperatorName);
                            }

                            intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device);
                            mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);

                            if (mIndicatorNetworkState ==
                                    HeadsetClientHalConstants.NETWORK_STATE_AVAILABLE) {
                                if (queryCurrentOperatorNameNative()) {
                                    addQueuedAction(QUERY_OPERATOR_NAME);
                                } else {
                                    Log.e(TAG, "ERROR: Couldn't querry operator name");
                                }
                            }
                            break;
                        case EVENT_TYPE_ROAMING_STATE:
                            Log.d(TAG, "Connected: Roaming state: " + event.valueInt);

                            mIndicatorNetworkType = event.valueInt;

                            intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT);
                            intent.putExtra(BluetoothHeadsetClient.EXTRA_NETWORK_ROAMING,
                                    event.valueInt);
                            intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device);
                            mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
                            break;
                        case EVENT_TYPE_NETWORK_SIGNAL:
                            Log.d(TAG, "Connected: Signal level: " + event.valueInt);

                            mIndicatorNetworkSignal = event.valueInt;

                            intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT);
                            intent.putExtra(BluetoothHeadsetClient.EXTRA_NETWORK_SIGNAL_STRENGTH,
                                    event.valueInt);
                            intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device);
                            mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
                            break;
                        case EVENT_TYPE_BATTERY_LEVEL:
                            Log.d(TAG, "Connected: Battery level: " + event.valueInt);

                            mIndicatorBatteryLevel = event.valueInt;

                            intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT);
                            intent.putExtra(BluetoothHeadsetClient.EXTRA_BATTERY_LEVEL,
                                    event.valueInt);
                            intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device);
                            mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
                            break;
                        case EVENT_TYPE_OPERATOR_NAME:
                            Log.d(TAG, "Connected: Operator name: " + event.valueString);

                            mOperatorName = event.valueString;

                            intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT);
                            intent.putExtra(BluetoothHeadsetClient.EXTRA_OPERATOR_NAME,
                                    event.valueString);
                            intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device);
                            mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
                            break;
                        case EVENT_TYPE_VR_STATE_CHANGED:
                            Log.d(TAG, "Connected: Voice recognition state: " + event.valueInt);

                            if (mVoiceRecognitionActive != event.valueInt) {
                                mVoiceRecognitionActive = event.valueInt;

                                intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT);
                                intent.putExtra(BluetoothHeadsetClient.EXTRA_VOICE_RECOGNITION,
                                        mVoiceRecognitionActive);
                                intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device);
                                mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
                            }
                            break;
                        case EVENT_TYPE_CALL:
                            updateCallIndicator(event.valueInt);
                            break;
                        case EVENT_TYPE_CALLSETUP:
                            updateCallSetupIndicator(event.valueInt);
                            break;
                        case EVENT_TYPE_CALLHELD:
                            updateCallHeldIndicator(event.valueInt);
                            break;
                        case EVENT_TYPE_RESP_AND_HOLD:
                            updateRespAndHold(event.valueInt);
                            break;
                        case EVENT_TYPE_CLIP:
                            updateClip(event.valueString);
                            break;
                        case EVENT_TYPE_CALL_WAITING:
                            addCallWaiting(event.valueString);
                            break;
                        case EVENT_TYPE_IN_BAND_RING:
                            if (mInBandRingtone != event.valueInt) {
                                mInBandRingtone = event.valueInt;
                                intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT);
                                intent.putExtra(BluetoothHeadsetClient.EXTRA_IN_BAND_RING,
                                        mInBandRingtone);
                                intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device);
                                mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
                            }
                            break;
                        case EVENT_TYPE_CURRENT_CALLS:
                            queryCallsUpdate(
                                    event.valueInt,
                                    event.valueInt3,
                                    event.valueString,
                                    event.valueInt4 ==
                                            HeadsetClientHalConstants.CALL_MPTY_TYPE_MULTI,
                                    event.valueInt2 ==
                                            HeadsetClientHalConstants.CALL_DIRECTION_OUTGOING);
                            break;
                        case EVENT_TYPE_VOLUME_CHANGED:
                            if (event.valueInt == HeadsetClientHalConstants.VOLUME_TYPE_SPK) {
                                Log.d(TAG, "AM volume set to " +
                                      hfToAmVol(event.valueInt2));
                                mAudioManager.setStreamVolume(
                                    AudioManager.STREAM_VOICE_CALL,
                                    hfToAmVol(event.valueInt2),
                                    AudioManager.FLAG_SHOW_UI);
                                mVgsFromStack = true;
                            } else if (event.valueInt ==
                                HeadsetClientHalConstants.VOLUME_TYPE_MIC) {
                                mAudioManager.setMicrophoneMute(event.valueInt2 == 0);

                                mVgmFromStack = true;
                            }
                            break;
                        case EVENT_TYPE_CMD_RESULT:
                            Pair<Integer, Object> queuedAction = mQueuedActions.poll();

                            // should not happen but...
                            if (queuedAction == null || queuedAction.first == NO_ACTION) {
                                clearPendingAction();
                                break;
                            }

                            Log.d(TAG, "Connected: command result: " + event.valueInt
                                    + " queuedAction: " + queuedAction.first);

                            switch (queuedAction.first) {
                                case VOICE_RECOGNITION_STOP:
                                case VOICE_RECOGNITION_START:
                                    if (event.valueInt == HeadsetClientHalConstants.CMD_COMPLETE_OK) {
                                        if (queuedAction.first == VOICE_RECOGNITION_STOP) {
                                            mVoiceRecognitionActive =
                                                    HeadsetClientHalConstants.VR_STATE_STOPPED;
                                        } else {
                                            mVoiceRecognitionActive =
                                                    HeadsetClientHalConstants.VR_STATE_STARTED;
                                        }
                                    }
                                    intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT);
                                    intent.putExtra(
                                            BluetoothHeadsetClient.EXTRA_VOICE_RECOGNITION,
                                            mVoiceRecognitionActive);
                                    intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device);
                                    mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
                                    break;
                                case QUERY_CURRENT_CALLS:
                                    queryCallsDone();
                                    break;
                                case ACCEPT_CALL:
                                    if (event.valueInt == BluetoothHeadsetClient.ACTION_RESULT_OK) {
                                        mPendingAction = queuedAction;
                                    } else {
                                        if (callsInState(BluetoothHeadsetClientCall.CALL_STATE_ACTIVE) == 0) {
                                            if(getCall(BluetoothHeadsetClientCall.CALL_STATE_INCOMING) != null &&
                                                (Integer) mPendingAction.second == HeadsetClientHalConstants.CALL_ACTION_ATA) {
                                                acceptCall(BluetoothHeadsetClient.CALL_ACCEPT_NONE, true);
                                                break;
                                            } else if(getCall(BluetoothHeadsetClientCall.CALL_STATE_WAITING) != null &&
                                                     (Integer) mPendingAction.second == HeadsetClientHalConstants.CALL_ACTION_CHLD_2) {
                                                acceptCall(BluetoothHeadsetClient.CALL_ACCEPT_NONE, true);
                                                break;
                                            }
                                        }
                                        sendActionResultIntent(event);
                                    }
                                    break;
                                case REJECT_CALL:
                                case HOLD_CALL:
                                case TERMINATE_CALL:
                                case ENTER_PRIVATE_MODE:
                                case DIAL_NUMBER:
                                case DIAL_MEMORY:
                                case REDIAL:
                                    if (event.valueInt == BluetoothHeadsetClient.ACTION_RESULT_OK) {
                                        mPendingAction = queuedAction;
                                    } else {
                                        sendActionResultIntent(event);
                                    }
                                    break;
                                case TERMINATE_SPECIFIC_CALL:
                                    // if terminating specific succeed no other
                                    // event is send
                                    if (event.valueInt == BluetoothHeadsetClient.ACTION_RESULT_OK) {
                                        BluetoothHeadsetClientCall c =
                                                (BluetoothHeadsetClientCall) queuedAction.second;
                                        setCallState(c,
                                                BluetoothHeadsetClientCall.CALL_STATE_TERMINATED);
                                        mCalls.remove(c.getId());
                                    } else {
                                        sendActionResultIntent(event);
                                    }
                                    break;
                                case LAST_VTAG_NUMBER:
                                    if (event.valueInt != BluetoothHeadsetClient.ACTION_RESULT_OK) {
                                        sendActionResultIntent(event);
                                    }
                                    break;
                                case DISABLE_NREC:
                                    if (event.valueInt != HeadsetClientHalConstants.CMD_COMPLETE_OK) {
                                        Log.w(TAG, "Failed to disable AG's EC and NR");
                                    }
                                    break;
                                case SET_MIC_VOLUME:
                                case SET_SPEAKER_VOLUME:
                                case SUBSCRIBER_INFO:
                                case QUERY_OPERATOR_NAME:
                                    break;
                                default:
                                    sendActionResultIntent(event);
                                    break;
                            }

                            break;
                        case EVENT_TYPE_SUBSCRIBER_INFO:
                            /* TODO should we handle type as well? */
                            mSubscriberInfo = event.valueString;
                            intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT);
                            intent.putExtra(BluetoothHeadsetClient.EXTRA_SUBSCRIBER_INFO,
                                    mSubscriberInfo);
                            intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device);
                            mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
                            break;
                        case EVENT_TYPE_LAST_VOICE_TAG_NUMBER:
                            intent = new Intent(BluetoothHeadsetClient.ACTION_LAST_VTAG);
                            intent.putExtra(BluetoothHeadsetClient.EXTRA_NUMBER,
                                    event.valueString);
                            intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device);
                            mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
                            break;
                        case EVENT_TYPE_RING_INDICATION:
                            // Ringing is not handled at this indication and rather should be
                            // implemented (by the client of this service). Use the
                            // CALL_STATE_INCOMING (and similar) handle ringing.
                            break;
                        default:
                            Log.e(TAG, "Unknown stack event: " + event.type);
                            break;
                    }

                    break;
                default:
                    return NOT_HANDLED;
            }
            return HANDLED;
        }

        private void sendActionResultIntent(StackEvent event) {
            Intent intent = new Intent(BluetoothHeadsetClient.ACTION_RESULT);
            intent.putExtra(BluetoothHeadsetClient.EXTRA_RESULT_CODE, event.valueInt);
            if (event.valueInt == BluetoothHeadsetClient.ACTION_RESULT_ERROR_CME) {
                intent.putExtra(BluetoothHeadsetClient.EXTRA_CME_CODE, event.valueInt2);
            }
            intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device);
            mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
        }

        // in Connected state
        private void processConnectionEvent(int state, BluetoothDevice device) {
            switch (state) {
                case HeadsetClientHalConstants.CONNECTION_STATE_DISCONNECTED:
                    Log.d(TAG, "Connected disconnects.");
                    // AG disconnects
                    if (mCurrentDevice.equals(device)) {
                        broadcastConnectionState(mCurrentDevice,
                                BluetoothProfile.STATE_DISCONNECTED,
                                BluetoothProfile.STATE_CONNECTED);
                        mCurrentDevice = null;
                        transitionTo(mDisconnected);
                    } else {
                        Log.e(TAG, "Disconnected from unknown device: " + device);
                    }
                    break;
                default:
                    Log.e(TAG, "Connection State Device: " + device + " bad state: " + state);
                    break;
            }
        }

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

            switch (state) {
                case HeadsetClientHalConstants.AUDIO_STATE_CONNECTED_MSBC:
                    mAudioWbs = true;
                    // fall through
                case HeadsetClientHalConstants.AUDIO_STATE_CONNECTED:
                    if (!mAudioRouteAllowed) {
                        sendMessage(HeadsetClientStateMachine.DISCONNECT_AUDIO);
                        break;
                    }

                    // Audio state is split in two parts, the audio focus is maintained by the
                    // entity exercising this service (typically the Telecom stack) and audio
                    // routing is handled by the bluetooth stack itself. The only reason to do so is
                    // because Bluetooth SCO connection from the HF role is not entirely supported
                    // for routing and volume purposes.
                    // NOTE: All calls here are routed via the setParameters which changes the
                    // routing at the Audio HAL level.
                    mAudioState = BluetoothHeadsetClient.STATE_AUDIO_CONNECTED;

                    // We need to set the volume after switching into HFP mode as some Audio HALs
                    // reset the volume to a known-default on mode switch.
                    final int amVol =
                            mAudioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL);
                    final int hfVol = amToHfVol(amVol);

                    Log.d(TAG,"hfp_enable=true");
                    Log.d(TAG,"mAudioWbs is " + mAudioWbs);
                    if (mAudioWbs) {
                        Log.d(TAG,"Setting sampling rate as 16000");
                        mAudioManager.setParameters("hfp_set_sampling_rate=16000");
                    }
                    else {
                        Log.d(TAG,"Setting sampling rate as 8000");
                        mAudioManager.setParameters("hfp_set_sampling_rate=8000");
                    }
                    Log.d(TAG, "hf_volume " + hfVol);
                    mAudioManager.setParameters("hfp_enable=true");
                    mAudioManager.setParameters("hfp_volume=" + hfVol);
                    transitionTo(mAudioOn);
                    break;
                case HeadsetClientHalConstants.AUDIO_STATE_CONNECTING:
                    mAudioState = BluetoothHeadsetClient.STATE_AUDIO_CONNECTING;
                    broadcastAudioState(device, BluetoothHeadsetClient.STATE_AUDIO_CONNECTING,
                            BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED);
                    break;
                case HeadsetClientHalConstants.AUDIO_STATE_DISCONNECTED:
                    if (mAudioState == BluetoothHeadsetClient.STATE_AUDIO_CONNECTING) {
                        mAudioState = BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED;
                        broadcastAudioState(device,
                                BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED,
                                BluetoothHeadsetClient.STATE_AUDIO_CONNECTING);
                    }
                    break;
                default:
                    Log.e(TAG, "Audio State Device: " + device + " bad state: " + state);
                    break;
            }
        }

        @Override
        public void exit() {
            Log.d(TAG, "Exit Connected: " + getCurrentMessage().what);
        }
    }

    private class AudioOn extends State {
        @Override
        public void enter() {
            Log.d(TAG, "Enter AudioOn: " + getCurrentMessage().what);
            broadcastAudioState(mCurrentDevice, BluetoothHeadsetClient.STATE_AUDIO_CONNECTED,
                BluetoothHeadsetClient.STATE_AUDIO_CONNECTING);
        }

        @Override
        public synchronized boolean processMessage(Message message) {
            Log.d(TAG, "AudioOn process message: " + message.what);
            if (DBG) {
                if (mCurrentDevice == null) {
                    Log.d(TAG, "ERROR: mCurrentDevice is null in Connected");
                    return NOT_HANDLED;
                }
            }

            switch (message.what) {
                case DISCONNECT:
                    BluetoothDevice device = (BluetoothDevice) message.obj;
                    if (!mCurrentDevice.equals(device)) {
                        break;
                    }
                    deferMessage(message);
                    /*
                     * fall through - disconnect audio first then expect
                     * deferred DISCONNECT message in Connected state
                     */
                case DISCONNECT_AUDIO:
                    /*
                     * just disconnect audio and wait for
                     * EVENT_TYPE_AUDIO_STATE_CHANGED, that triggers State
                     * Machines state changing
                     */
                    if (disconnectAudioNative(getByteAddress(mCurrentDevice))) {
                        mAudioState = BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED;
                        Log.d(TAG,"hfp_enable=false");
                        mAudioManager.setParameters("hfp_enable=false");
                        broadcastAudioState(mCurrentDevice,
                                BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED,
                                BluetoothHeadsetClient.STATE_AUDIO_CONNECTED);
                    }
                    break;
                case STACK_EVENT:
                    StackEvent event = (StackEvent) message.obj;
                    if (DBG) {
                        Log.d(TAG, "AudioOn: event type: " + event.type);
                    }
                    switch (event.type) {
                        case EVENT_TYPE_CONNECTION_STATE_CHANGED:
                            Log.d(TAG, "AudioOn connection state changed" + event.device + ": "
                                    + event.valueInt);
                            processConnectionEvent(event.valueInt, event.device);
                            break;
                        case EVENT_TYPE_AUDIO_STATE_CHANGED:
                            Log.d(TAG, "AudioOn audio state changed" + event.device + ": "
                                    + event.valueInt);
                            processAudioEvent(event.valueInt, event.device);
                            break;
                        default:
                            return NOT_HANDLED;
                    }
                    break;
                default:
                    return NOT_HANDLED;
            }
            return HANDLED;
        }

        // in AudioOn state. Can AG disconnect RFCOMM prior to SCO? Handle this
        private void processConnectionEvent(int state, BluetoothDevice device) {
            switch (state) {
                case HeadsetClientHalConstants.CONNECTION_STATE_DISCONNECTED:
                    if (mCurrentDevice.equals(device)) {
                        processAudioEvent(HeadsetClientHalConstants.AUDIO_STATE_DISCONNECTED,
                                device);
                        broadcastConnectionState(mCurrentDevice,
                                BluetoothProfile.STATE_DISCONNECTED,
                                BluetoothProfile.STATE_CONNECTED);
                        mCurrentDevice = null;
                        transitionTo(mDisconnected);
                    } else {
                        Log.e(TAG, "Disconnected from unknown device: " + device);
                    }
                    break;
                default:
                    Log.e(TAG, "Connection State Device: " + device + " bad state: " + state);
                    break;
            }
        }

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

            switch (state) {
                case HeadsetClientHalConstants.AUDIO_STATE_DISCONNECTED:
                    if (mAudioState != BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED) {
                        mAudioState = BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED;
                        // Audio focus may still be held by the entity controlling the actual call
                        // (such as Telecom) and hence this will still keep the call around, there
                        // is not much we can do here since dropping the call without user consent
                        // even if the audio connection snapped may not be a good idea.
                        Log.d(TAG,"hfp_enable=false");
                        mAudioManager.setParameters("hfp_enable=false");
                        broadcastAudioState(device,
                                BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED,
                                BluetoothHeadsetClient.STATE_AUDIO_CONNECTED);
                    }

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

        @Override
        public void exit() {
            Log.d(TAG, "Exit AudioOn: " + getCurrentMessage().what);
        }
    }

    /**
     * @hide
     */
    public synchronized int getConnectionState(BluetoothDevice device) {
        if (mCurrentDevice == null) {
            return BluetoothProfile.STATE_DISCONNECTED;
        }

        if (!mCurrentDevice.equals(device)) {
            return BluetoothProfile.STATE_DISCONNECTED;
        }

        IState currentState = getCurrentState();
        if (currentState == mConnecting) {
            return BluetoothProfile.STATE_CONNECTING;
        }

        if (currentState == mConnected || currentState == mAudioOn) {
            return BluetoothProfile.STATE_CONNECTED;
        }

        Log.e(TAG, "Bad currentState: " + currentState);
        return BluetoothProfile.STATE_DISCONNECTED;
    }

    private void broadcastAudioState(BluetoothDevice device, int newState, int prevState) {
        Intent intent = new Intent(BluetoothHeadsetClient.ACTION_AUDIO_STATE_CHANGED);
        intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState);
        intent.putExtra(BluetoothProfile.EXTRA_STATE, newState);

        if (newState == BluetoothHeadsetClient.STATE_AUDIO_CONNECTED) {
            intent.putExtra(BluetoothHeadsetClient.EXTRA_AUDIO_WBS, mAudioWbs);
        }

        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
        mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
        Log.d(TAG, "Audio state " + device + ": " + prevState + "->" + newState);
    }

    // This method does not check for error condition (newState == prevState)
    private void broadcastConnectionState(BluetoothDevice device, int newState, int prevState) {
        Log.d(TAG, "Connection state " + device + ": " + prevState + "->" + newState);
        /*
         * Notifying the connection state change of the profile before sending
         * the intent for connection state change, as it was causing a race
         * condition, with the UI not being updated with the correct connection
         * state.
         */
        mService.notifyProfileConnectionStateChanged(device, BluetoothProfile.HEADSET_CLIENT,
                newState, prevState);
        Intent intent = new Intent(BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED);
        intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState);
        intent.putExtra(BluetoothProfile.EXTRA_STATE, newState);
        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);

        // add feature extras when connected
        if (newState == BluetoothProfile.STATE_CONNECTED) {
            if ((mPeerFeatures & HeadsetClientHalConstants.PEER_FEAT_3WAY) ==
                    HeadsetClientHalConstants.PEER_FEAT_3WAY) {
                intent.putExtra(BluetoothHeadsetClient.EXTRA_AG_FEATURE_3WAY_CALLING, true);
            }
            if ((mPeerFeatures & HeadsetClientHalConstants.PEER_FEAT_VREC) ==
                    HeadsetClientHalConstants.PEER_FEAT_VREC) {
                intent.putExtra(BluetoothHeadsetClient.EXTRA_AG_FEATURE_VOICE_RECOGNITION, true);
            }
            if ((mPeerFeatures & HeadsetClientHalConstants.PEER_FEAT_VTAG) ==
                    HeadsetClientHalConstants.PEER_FEAT_VTAG) {
                intent.putExtra(BluetoothHeadsetClient.EXTRA_AG_FEATURE_ATTACH_NUMBER_TO_VT, true);
            }
            if ((mPeerFeatures & HeadsetClientHalConstants.PEER_FEAT_REJECT) ==
                    HeadsetClientHalConstants.PEER_FEAT_REJECT) {
                intent.putExtra(BluetoothHeadsetClient.EXTRA_AG_FEATURE_REJECT_CALL, true);
            }
            if ((mPeerFeatures & HeadsetClientHalConstants.PEER_FEAT_ECC) ==
                    HeadsetClientHalConstants.PEER_FEAT_ECC) {
                intent.putExtra(BluetoothHeadsetClient.EXTRA_AG_FEATURE_ECC, true);
            }

            // add individual CHLD support extras
            if ((mChldFeatures & HeadsetClientHalConstants.CHLD_FEAT_HOLD_ACC) ==
                    HeadsetClientHalConstants.CHLD_FEAT_HOLD_ACC) {
                intent.putExtra(BluetoothHeadsetClient.EXTRA_AG_FEATURE_ACCEPT_HELD_OR_WAITING_CALL, true);
            }
            if ((mChldFeatures & HeadsetClientHalConstants.CHLD_FEAT_REL) ==
                    HeadsetClientHalConstants.CHLD_FEAT_REL) {
                intent.putExtra(BluetoothHeadsetClient.EXTRA_AG_FEATURE_RELEASE_HELD_OR_WAITING_CALL, true);
            }
            if ((mChldFeatures & HeadsetClientHalConstants.CHLD_FEAT_REL_ACC) ==
                    HeadsetClientHalConstants.CHLD_FEAT_REL_ACC) {
                intent.putExtra(BluetoothHeadsetClient.EXTRA_AG_FEATURE_RELEASE_AND_ACCEPT, true);
            }
            if ((mChldFeatures & HeadsetClientHalConstants.CHLD_FEAT_MERGE) ==
                    HeadsetClientHalConstants.CHLD_FEAT_MERGE) {
                intent.putExtra(BluetoothHeadsetClient.EXTRA_AG_FEATURE_MERGE, true);
            }
            if ((mChldFeatures & HeadsetClientHalConstants.CHLD_FEAT_MERGE_DETACH) ==
                    HeadsetClientHalConstants.CHLD_FEAT_MERGE_DETACH) {
                intent.putExtra(BluetoothHeadsetClient.EXTRA_AG_FEATURE_MERGE_AND_DETACH, true);
            }
        }
        mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
    }

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

    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.isUuidPresent(featureUuids, BluetoothUuid.Handsfree_AG)) {
                    continue;
                }
                connectionState = getConnectionState(device);
                for (int state : states) {
                    if (connectionState == state) {
                        deviceList.add(device);
                    }
                }
            }
        }
        return deviceList;
    }

    boolean okToConnect(BluetoothDevice device) {
        int priority = mService.getPriority(device);
        boolean 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
        if ((BluetoothProfile.PRIORITY_OFF < priority) ||
                ((BluetoothProfile.PRIORITY_UNDEFINED == priority) &&
                (device.getBondState() != BluetoothDevice.BOND_NONE))) {
            ret = true;
        }
        return ret;
    }

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

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

    public boolean getAudioRouteAllowed() {
        return mAudioRouteAllowed;
    }

    synchronized int getAudioState(BluetoothDevice device) {
        if (mCurrentDevice == null || !mCurrentDevice.equals(device)) {
            return BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED;
        }
        return mAudioState;
    }

    /**
     * @hide
     */
    List<BluetoothDevice> getConnectedDevices() {
        List<BluetoothDevice> devices = new ArrayList<BluetoothDevice>();
        synchronized (this) {
            if (isConnected()) {
                devices.add(mCurrentDevice);
            }
        }
        return devices;
    }

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

    private void onConnectionStateChanged(int state, int peer_feat, int chld_feat, byte[] address) {
        StackEvent event = new StackEvent(EVENT_TYPE_CONNECTION_STATE_CHANGED);
        event.valueInt = state;
        event.valueInt2 = peer_feat;
        event.valueInt3 = chld_feat;
        event.device = getDevice(address);
        Log.d(TAG, "incoming" + event);
        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);
        Log.d(TAG, "incoming" + event);
        sendMessage(STACK_EVENT, event);
    }

    private void onVrStateChanged(int state) {
        StackEvent event = new StackEvent(EVENT_TYPE_VR_STATE_CHANGED);
        event.valueInt = state;
        Log.d(TAG, "incoming" + event);
        sendMessage(STACK_EVENT, event);
    }

    private void onNetworkState(int state) {
        StackEvent event = new StackEvent(EVENT_TYPE_NETWORK_STATE);
        event.valueInt = state;
        Log.d(TAG, "incoming" + event);
        sendMessage(STACK_EVENT, event);
    }

    private void onNetworkRoaming(int state) {
        StackEvent event = new StackEvent(EVENT_TYPE_ROAMING_STATE);
        event.valueInt = state;
        Log.d(TAG, "incoming" + event);
        sendMessage(STACK_EVENT, event);
    }

    private void onNetworkSignal(int signal) {
        StackEvent event = new StackEvent(EVENT_TYPE_NETWORK_SIGNAL);
        event.valueInt = signal;
        Log.d(TAG, "incoming" + event);
        sendMessage(STACK_EVENT, event);
    }

    private void onBatteryLevel(int level) {
        StackEvent event = new StackEvent(EVENT_TYPE_BATTERY_LEVEL);
        event.valueInt = level;
        Log.d(TAG, "incoming" + event);
        sendMessage(STACK_EVENT, event);
    }

    private void onCurrentOperator(String name) {
        StackEvent event = new StackEvent(EVENT_TYPE_OPERATOR_NAME);
        event.valueString = name;
        Log.d(TAG, "incoming" + event);
        sendMessage(STACK_EVENT, event);
    }

    private void onCall(int call) {
        StackEvent event = new StackEvent(EVENT_TYPE_CALL);
        event.valueInt = call;
        Log.d(TAG, "incoming" + event);
        sendMessage(STACK_EVENT, event);
    }

    private void onCallSetup(int callsetup) {
        StackEvent event = new StackEvent(EVENT_TYPE_CALLSETUP);
        event.valueInt = callsetup;
        Log.d(TAG, "incoming" + event);
        sendMessage(STACK_EVENT, event);
    }

    private void onCallHeld(int callheld) {
        StackEvent event = new StackEvent(EVENT_TYPE_CALLHELD);
        event.valueInt = callheld;
        Log.d(TAG, "incoming" + event);
        sendMessage(STACK_EVENT, event);
    }

    private void onRespAndHold(int resp_and_hold) {
        StackEvent event = new StackEvent(EVENT_TYPE_RESP_AND_HOLD);
        event.valueInt = resp_and_hold;
        Log.d(TAG, "incoming" + event);
        sendMessage(STACK_EVENT, event);
    }

    private void onClip(String number) {
        StackEvent event = new StackEvent(EVENT_TYPE_CLIP);
        event.valueString = number;
        Log.d(TAG, "incoming" + event);
        sendMessage(STACK_EVENT, event);
    }

    private void onCallWaiting(String number) {
        StackEvent event = new StackEvent(EVENT_TYPE_CALL_WAITING);
        event.valueString = number;
        Log.d(TAG, "incoming" + event);
        sendMessage(STACK_EVENT, event);
    }

    private void onCurrentCalls(int index, int dir, int state, int mparty, String number) {
        StackEvent event = new StackEvent(EVENT_TYPE_CURRENT_CALLS);
        event.valueInt = index;
        event.valueInt2 = dir;
        event.valueInt3 = state;
        event.valueInt4 = mparty;
        event.valueString = number;
        Log.d(TAG, "incoming " + event);
        sendMessage(STACK_EVENT, event);
    }

    private void onVolumeChange(int type, int volume) {
        StackEvent event = new StackEvent(EVENT_TYPE_VOLUME_CHANGED);
        event.valueInt = type;
        event.valueInt2 = volume;
        Log.d(TAG, "incoming" + event);
        sendMessage(STACK_EVENT, event);
    }

    private void onCmdResult(int type, int cme) {
        StackEvent event = new StackEvent(EVENT_TYPE_CMD_RESULT);
        event.valueInt = type;
        event.valueInt2 = cme;
        Log.d(TAG, "incoming" + event);
        sendMessage(STACK_EVENT, event);
    }

    private void onSubscriberInfo(String number, int type) {
        StackEvent event = new StackEvent(EVENT_TYPE_SUBSCRIBER_INFO);
        event.valueInt = type;
        event.valueString = number;
        Log.d(TAG, "incoming" + event);
        sendMessage(STACK_EVENT, event);
    }

    private void onInBandRing(int in_band) {
        StackEvent event = new StackEvent(EVENT_TYPE_IN_BAND_RING);
        event.valueInt = in_band;
        Log.d(TAG, "incoming" + event);
        sendMessage(STACK_EVENT, event);
    }

    private void onLastVoiceTagNumber(String number) {
        StackEvent event = new StackEvent(EVENT_TYPE_LAST_VOICE_TAG_NUMBER);
        event.valueString = number;
        Log.d(TAG, "incoming" + event);
        sendMessage(STACK_EVENT, event);
    }
    private void onRingIndication() {
        StackEvent event = new StackEvent(EVENT_TYPE_RING_INDICATION);
        Log.d(TAG, "incoming" + event);
        sendMessage(STACK_EVENT, event);
    }

    private String getCurrentDeviceName() {
        String defaultName = "<unknown>";
        if (mCurrentDevice == null) {
            return defaultName;
        }
        String deviceName = mCurrentDevice.getName();
        if (deviceName == null) {
            return defaultName;
        }
        return deviceName;
    }

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

    // 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_NETWORK_STATE = 4;
    final private static int EVENT_TYPE_ROAMING_STATE = 5;
    final private static int EVENT_TYPE_NETWORK_SIGNAL = 6;
    final private static int EVENT_TYPE_BATTERY_LEVEL = 7;
    final private static int EVENT_TYPE_OPERATOR_NAME = 8;
    final private static int EVENT_TYPE_CALL = 9;
    final private static int EVENT_TYPE_CALLSETUP = 10;
    final private static int EVENT_TYPE_CALLHELD = 11;
    final private static int EVENT_TYPE_CLIP = 12;
    final private static int EVENT_TYPE_CALL_WAITING = 13;
    final private static int EVENT_TYPE_CURRENT_CALLS = 14;
    final private static int EVENT_TYPE_VOLUME_CHANGED = 15;
    final private static int EVENT_TYPE_CMD_RESULT = 16;
    final private static int EVENT_TYPE_SUBSCRIBER_INFO = 17;
    final private static int EVENT_TYPE_RESP_AND_HOLD = 18;
    final private static int EVENT_TYPE_IN_BAND_RING = 19;
    final private static int EVENT_TYPE_LAST_VOICE_TAG_NUMBER = 20;
    final private static int EVENT_TYPE_RING_INDICATION= 21;

    // for debugging only
    private final String EVENT_TYPE_NAMES[] =
    {
            "EVENT_TYPE_NONE",
            "EVENT_TYPE_CONNECTION_STATE_CHANGED",
            "EVENT_TYPE_AUDIO_STATE_CHANGED",
            "EVENT_TYPE_VR_STATE_CHANGED",
            "EVENT_TYPE_NETWORK_STATE",
            "EVENT_TYPE_ROAMING_STATE",
            "EVENT_TYPE_NETWORK_SIGNAL",
            "EVENT_TYPE_BATTERY_LEVEL",
            "EVENT_TYPE_OPERATOR_NAME",
            "EVENT_TYPE_CALL",
            "EVENT_TYPE_CALLSETUP",
            "EVENT_TYPE_CALLHELD",
            "EVENT_TYPE_CLIP",
            "EVENT_TYPE_CALL_WAITING",
            "EVENT_TYPE_CURRENT_CALLS",
            "EVENT_TYPE_VOLUME_CHANGED",
            "EVENT_TYPE_CMD_RESULT",
            "EVENT_TYPE_SUBSCRIBER_INFO",
            "EVENT_TYPE_RESP_AND_HOLD",
            "EVENT_TYPE_IN_BAND_RING",
            "EVENT_TYPE_LAST_VOICE_TAG_NUMBER",
            "EVENT_TYPE_RING_INDICATION",
    };

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

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

        @Override
        public String toString() {
            // event dump
            StringBuilder result = new StringBuilder();
            result.append("StackEvent {type:" + EVENT_TYPE_NAMES[type]);
            result.append(", value1:" + valueInt);
            result.append(", value2:" + valueInt2);
            result.append(", value3:" + valueInt3);
            result.append(", value4:" + valueInt4);
            result.append(", string: \"" + valueString + "\"");
            result.append(", device:" + device + "}");
            return result.toString();
        }
    }

    private native static void classInitNative();

    private native void initializeNative();

    private native void cleanupNative();

    private native boolean connectNative(byte[] address);

    private native boolean disconnectNative(byte[] address);

    private native boolean connectAudioNative(byte[] address);

    private native boolean disconnectAudioNative(byte[] address);

    private native boolean startVoiceRecognitionNative();

    private native boolean stopVoiceRecognitionNative();

    private native boolean setVolumeNative(int volumeType, int volume);

    private native boolean dialNative(String number);

    private native boolean dialMemoryNative(int location);

    private native boolean handleCallActionNative(int action, int index);

    private native boolean queryCurrentCallsNative();

    private native boolean queryCurrentOperatorNameNative();

    private native boolean retrieveSubscriberInfoNative();

    private native boolean sendDtmfNative(byte code);

    private native boolean requestLastVoiceTagNumberNative();

    private native boolean sendATCmdNative(int ATCmd, int val1,
            int val2, String arg);

    public List<BluetoothHeadsetClientCall> getCurrentCalls() {
        return new ArrayList<BluetoothHeadsetClientCall>(mCalls.values());
    }

    public Bundle getCurrentAgEvents() {
        Bundle b = new Bundle();
        b.putInt(BluetoothHeadsetClient.EXTRA_NETWORK_STATUS, mIndicatorNetworkState);
        b.putInt(BluetoothHeadsetClient.EXTRA_NETWORK_SIGNAL_STRENGTH, mIndicatorNetworkSignal);
        b.putInt(BluetoothHeadsetClient.EXTRA_NETWORK_ROAMING, mIndicatorNetworkType);
        b.putInt(BluetoothHeadsetClient.EXTRA_BATTERY_LEVEL, mIndicatorBatteryLevel);
        b.putString(BluetoothHeadsetClient.EXTRA_OPERATOR_NAME, mOperatorName);
        b.putInt(BluetoothHeadsetClient.EXTRA_VOICE_RECOGNITION, mVoiceRecognitionActive);
        b.putInt(BluetoothHeadsetClient.EXTRA_IN_BAND_RING, mInBandRingtone);
        b.putString(BluetoothHeadsetClient.EXTRA_SUBSCRIBER_INFO, mSubscriberInfo);
        return b;
    }
}
