1aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta/* 2aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * Copyright (c) 2014 The Android Open Source Project 3aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * Copyright (C) 2012 The Android Open Source Project 4aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * 5aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * Licensed under the Apache License, Version 2.0 (the "License"); 6aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * you may not use this file except in compliance with the License. 7aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * You may obtain a copy of the License at 8aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * 9aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * http://www.apache.org/licenses/LICENSE-2.0 10aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * 11aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * Unless required by applicable law or agreed to in writing, software 12aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * distributed under the License is distributed on an "AS IS" BASIS, 13aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * See the License for the specific language governing permissions and 15aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * limitations under the License. 16aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta */ 17aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 18aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta/** 198d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood * Bluetooth Headset Client StateMachine 20aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * (Disconnected) 21aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * | ^ ^ 22aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * CONNECT | | | DISCONNECTED 23aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * V | | 24aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * (Connecting) | 25aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * | | 26aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * CONNECTED | | DISCONNECT 27aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * V | 28aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * (Connected) 29aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * | ^ 30aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * CONNECT_AUDIO | | DISCONNECT_AUDIO 31aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * V | 32aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * (AudioOn) 33aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta */ 34aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 35aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptapackage com.android.bluetooth.hfpclient; 36aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 37aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport android.bluetooth.BluetoothAdapter; 38aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport android.bluetooth.BluetoothDevice; 398d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwoodimport android.bluetooth.BluetoothHeadsetClient; 408d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwoodimport android.bluetooth.BluetoothHeadsetClientCall; 41aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport android.bluetooth.BluetoothProfile; 42aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport android.bluetooth.BluetoothUuid; 43aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport android.os.Bundle; 44aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport android.os.Message; 45aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport android.os.ParcelUuid; 46aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport android.util.Log; 47aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport android.util.Pair; 48aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport android.content.Context; 49aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport android.content.Intent; 50aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport android.media.AudioManager; 51aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport android.media.Ringtone; 52aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport android.media.RingtoneManager; 53aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport android.net.Uri; 54a9ad98ec1222093baecd70b32611c3a74ba7f2d8Sanket Agarwalimport android.telecom.TelecomManager; 55aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 56aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport com.android.bluetooth.Utils; 57aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport com.android.bluetooth.btservice.AdapterService; 58aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport com.android.bluetooth.btservice.ProfileService; 59a9ad98ec1222093baecd70b32611c3a74ba7f2d8Sanket Agarwalimport com.android.bluetooth.hfpclient.connserv.HfpClientConnectionService; 60a9ad98ec1222093baecd70b32611c3a74ba7f2d8Sanket Agarwalimport com.android.internal.util.IState; 61a9ad98ec1222093baecd70b32611c3a74ba7f2d8Sanket Agarwalimport com.android.internal.util.State; 62a9ad98ec1222093baecd70b32611c3a74ba7f2d8Sanket Agarwalimport com.android.internal.util.StateMachine; 63aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 64aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport java.util.ArrayList; 65aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport java.util.Arrays; 66aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport java.util.Hashtable; 67aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport java.util.Iterator; 68aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport java.util.LinkedList; 69aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport java.util.List; 70aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport java.util.Queue; 71aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Guptaimport java.util.Set; 72aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 7322bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Leeimport com.android.bluetooth.R; 7422bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee 758d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwoodfinal class HeadsetClientStateMachine extends StateMachine { 768d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood private static final String TAG = "HeadsetClientStateMachine"; 77aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private static final boolean DBG = false; 78aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 79aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta static final int NO_ACTION = 0; 80aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 81aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // external actions 82aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta static final int CONNECT = 1; 83aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta static final int DISCONNECT = 2; 84aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta static final int CONNECT_AUDIO = 3; 85aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta static final int DISCONNECT_AUDIO = 4; 86aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta static final int VOICE_RECOGNITION_START = 5; 87aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta static final int VOICE_RECOGNITION_STOP = 6; 88aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta static final int SET_MIC_VOLUME = 7; 89aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta static final int SET_SPEAKER_VOLUME = 8; 90aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta static final int REDIAL = 9; 91aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta static final int DIAL_NUMBER = 10; 92aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta static final int DIAL_MEMORY = 11; 93aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta static final int ACCEPT_CALL = 12; 94aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta static final int REJECT_CALL = 13; 95aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta static final int HOLD_CALL = 14; 96aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta static final int TERMINATE_CALL = 15; 97aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta static final int ENTER_PRIVATE_MODE = 16; 98aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta static final int SEND_DTMF = 17; 99aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta static final int EXPLICIT_CALL_TRANSFER = 18; 100aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta static final int LAST_VTAG_NUMBER = 19; 101d1fadc3b23a03cbf028bfbdca9fd64640d7a05bdDavid Stevens static final int DISABLE_NREC = 20; 102aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 103aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // internal actions 104aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta static final int QUERY_CURRENT_CALLS = 50; 105aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta static final int QUERY_OPERATOR_NAME = 51; 106aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta static final int SUBSCRIBER_INFO = 52; 107aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // special action to handle terminating specific call from multiparty call 108aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta static final int TERMINATE_SPECIFIC_CALL = 53; 109aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 110d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal static final int MAX_HFP_SCO_VOICE_CALL_VOLUME = 15; // HFP 1.5 spec. 111d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal static final int MIN_HFP_SCO_VOICE_CALL_VOLUME = 1; // HFP 1.5 spec. 112d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal 113aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private static final int STACK_EVENT = 100; 114aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 115aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private final Disconnected mDisconnected; 116aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private final Connecting mConnecting; 117aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private final Connected mConnected; 118aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private final AudioOn mAudioOn; 119aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1208d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood private final HeadsetClientService mService; 121aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1228d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood private Hashtable<Integer, BluetoothHeadsetClientCall> mCalls; 1238d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood private Hashtable<Integer, BluetoothHeadsetClientCall> mCallsUpdate; 124aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private boolean mQueryCallsSupported; 125aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 126aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private int mIndicatorNetworkState; 127aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private int mIndicatorNetworkType; 128aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private int mIndicatorNetworkSignal; 129aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private int mIndicatorBatteryLevel; 130aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 131aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private int mIndicatorCall; 132aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private int mIndicatorCallSetup; 133aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private int mIndicatorCallHeld; 134aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private boolean mVgsFromStack = false; 135aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private boolean mVgmFromStack = false; 136aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 137aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private String mOperatorName; 138aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private String mSubscriberInfo; 139aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 140aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private int mVoiceRecognitionActive; 141aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private int mInBandRingtone; 142aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 143d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal private int mMaxAmVcVol; 144d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal private int mMinAmVcVol; 145d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal 146aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // queue of send actions (pair action, action_data) 147aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private Queue<Pair<Integer, Object>> mQueuedActions; 148aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 149aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // last executed command, before action is complete e.g. waiting for some 150aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // indicator 151aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private Pair<Integer, Object> mPendingAction; 152aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 153aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private final AudioManager mAudioManager; 154aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private int mAudioState; 15522bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee // Indicates whether audio can be routed to the device. 15622bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee private boolean mAudioRouteAllowed; 157aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private boolean mAudioWbs; 158aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private final BluetoothAdapter mAdapter; 159aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private boolean mNativeAvailable; 160a9ad98ec1222093baecd70b32611c3a74ba7f2d8Sanket Agarwal private TelecomManager mTelecomManager; 161aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 162aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // currently connected device 163aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private BluetoothDevice mCurrentDevice = null; 164aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 165aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // general peer features and call handling features 166aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private int mPeerFeatures; 167aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private int mChldFeatures; 168aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 169aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta static { 170aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta classInitNative(); 171aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 172aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 173838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood public void dump(StringBuilder sb) { 174838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood ProfileService.println(sb, "mCurrentDevice: " + mCurrentDevice); 175838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood ProfileService.println(sb, "mAudioOn: " + mAudioOn); 176838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood ProfileService.println(sb, "mAudioState: " + mAudioState); 177838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood ProfileService.println(sb, "mAudioWbs: " + mAudioWbs); 178838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood ProfileService.println(sb, "mIndicatorNetworkState: " + mIndicatorNetworkState); 179838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood ProfileService.println(sb, "mIndicatorNetworkType: " + mIndicatorNetworkType); 180838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood ProfileService.println(sb, "mIndicatorNetworkSignal: " + mIndicatorNetworkSignal); 181838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood ProfileService.println(sb, "mIndicatorBatteryLevel: " + mIndicatorBatteryLevel); 182838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood ProfileService.println(sb, "mIndicatorCall: " + mIndicatorCall); 183838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood ProfileService.println(sb, "mIndicatorCallSetup: " + mIndicatorCallSetup); 184838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood ProfileService.println(sb, "mIndicatorCallHeld: " + mIndicatorCallHeld); 185838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood ProfileService.println(sb, "mVgsFromStack: " + mVgsFromStack); 186838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood ProfileService.println(sb, "mVgmFromStack: " + mVgmFromStack); 187838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood ProfileService.println(sb, "mOperatorName: " + mOperatorName); 188838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood ProfileService.println(sb, "mSubscriberInfo: " + mSubscriberInfo); 189838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood ProfileService.println(sb, "mVoiceRecognitionActive: " + mVoiceRecognitionActive); 190838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood ProfileService.println(sb, "mInBandRingtone: " + mInBandRingtone); 1917618faa5df18324c581ade91f75454e2e3d8ad49Sharvil Nanavati 192838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood ProfileService.println(sb, "mCalls:"); 1937618faa5df18324c581ade91f75454e2e3d8ad49Sharvil Nanavati if (mCalls != null) { 1947618faa5df18324c581ade91f75454e2e3d8ad49Sharvil Nanavati for (BluetoothHeadsetClientCall call : mCalls.values()) { 1957618faa5df18324c581ade91f75454e2e3d8ad49Sharvil Nanavati ProfileService.println(sb, " " + call); 1967618faa5df18324c581ade91f75454e2e3d8ad49Sharvil Nanavati } 197838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood } 1987618faa5df18324c581ade91f75454e2e3d8ad49Sharvil Nanavati 199838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood ProfileService.println(sb, "mCallsUpdate:"); 2007618faa5df18324c581ade91f75454e2e3d8ad49Sharvil Nanavati if (mCallsUpdate != null) { 2017618faa5df18324c581ade91f75454e2e3d8ad49Sharvil Nanavati for (BluetoothHeadsetClientCall call : mCallsUpdate.values()) { 2027618faa5df18324c581ade91f75454e2e3d8ad49Sharvil Nanavati ProfileService.println(sb, " " + call); 2037618faa5df18324c581ade91f75454e2e3d8ad49Sharvil Nanavati } 204838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood } 205838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood } 206838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood 207aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void clearPendingAction() { 208aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mPendingAction = new Pair<Integer, Object>(NO_ACTION, 0); 209aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 210aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 211aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void addQueuedAction(int action) { 212aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta addQueuedAction(action, 0); 213aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 214aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 215aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void addQueuedAction(int action, Object data) { 216aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mQueuedActions.add(new Pair<Integer, Object>(action, data)); 217aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 218aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 219aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void addQueuedAction(int action, int data) { 220aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mQueuedActions.add(new Pair<Integer, Object>(action, data)); 221aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 222aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 223aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void addCall(int state, String number) { 224aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "addToCalls state:" + state + " number:" + number); 225aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2268d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood boolean outgoing = state == BluetoothHeadsetClientCall.CALL_STATE_DIALING || 2278d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood state == BluetoothHeadsetClientCall.CALL_STATE_ALERTING; 228aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 229aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // new call always takes lowest possible id, starting with 1 230aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Integer id = 1; 231aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta while (mCalls.containsKey(id)) { 232aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta id++; 233aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 234aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2350301badedb14c68fe1c0e46efc14eb24411e333cMike Lockwood BluetoothHeadsetClientCall c = new BluetoothHeadsetClientCall(mCurrentDevice, id, state, 2360301badedb14c68fe1c0e46efc14eb24411e333cMike Lockwood number, false, outgoing); 237aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mCalls.put(id, c); 238aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 239aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendCallChangedIntent(c); 240aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 241aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 242aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void removeCalls(int... states) { 243aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "removeFromCalls states:" + Arrays.toString(states)); 244aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2458d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood Iterator<Hashtable.Entry<Integer, BluetoothHeadsetClientCall>> it; 246aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 247aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta it = mCalls.entrySet().iterator(); 248aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta while (it.hasNext()) { 2498d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall c = it.next().getValue(); 250aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 251aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta for (int s : states) { 252aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (c.getState() == s) { 253aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta it.remove(); 2548d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood setCallState(c, BluetoothHeadsetClientCall.CALL_STATE_TERMINATED); 255aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 256aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 257aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 258aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 259aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 260aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 261aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void changeCallsState(int old_state, int new_state) { 262aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "changeStateFromCalls old:" + old_state + " new: " + new_state); 263aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2648d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood for (BluetoothHeadsetClientCall c : mCalls.values()) { 265aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (c.getState() == old_state) { 266aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta setCallState(c, new_state); 267aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 268aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 269aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 270aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2718d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood private BluetoothHeadsetClientCall getCall(int... states) { 272aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "getFromCallsWithStates states:" + Arrays.toString(states)); 2738d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood for (BluetoothHeadsetClientCall c : mCalls.values()) { 274aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta for (int s : states) { 275aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (c.getState() == s) { 276aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return c; 277aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 278aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 279aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 280aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 281aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return null; 282aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 283aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 284aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private int callsInState(int state) { 285aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int i = 0; 2868d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood for (BluetoothHeadsetClientCall c : mCalls.values()) { 287aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (c.getState() == state) { 288aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta i++; 289aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 290aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 291aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 292aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return i; 293aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 294aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 295aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void updateCallsMultiParty() { 2968d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood boolean multi = callsInState(BluetoothHeadsetClientCall.CALL_STATE_ACTIVE) > 1; 297aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2988d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood for (BluetoothHeadsetClientCall c : mCalls.values()) { 2998d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (c.getState() == BluetoothHeadsetClientCall.CALL_STATE_ACTIVE) { 300aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (c.isMultiParty() == multi) { 301aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta continue; 302aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 303aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 304aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta c.setMultiParty(multi); 305aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendCallChangedIntent(c); 306aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 307aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (c.isMultiParty()) { 308aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta c.setMultiParty(false); 309aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendCallChangedIntent(c); 310aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 311aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 312aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 313aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 314aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 3158d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood private void setCallState(BluetoothHeadsetClientCall c, int state) { 316aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (state == c.getState()) { 317aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return; 318aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 319aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta c.setState(state); 320aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendCallChangedIntent(c); 321aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 322aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 3238d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood private void sendCallChangedIntent(BluetoothHeadsetClientCall c) { 324a9ad98ec1222093baecd70b32611c3a74ba7f2d8Sanket Agarwal Log.d(TAG, "sendCallChangedIntent " + c); 3258d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood Intent intent = new Intent(BluetoothHeadsetClient.ACTION_CALL_CHANGED); 32606c566ebd3462ec18624f1db9f49f81c2eec0cefLianchao Song intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 3278d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent.putExtra(BluetoothHeadsetClient.EXTRA_CALL, c); 328aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM); 329aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 330aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 331aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private boolean waitForIndicators(int call, int callsetup, int callheld) { 332aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // all indicators initial values received 333aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mIndicatorCall != -1 && mIndicatorCallSetup != -1 && 334aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mIndicatorCallHeld != -1) { 335aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 336aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 337aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 338aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (call != -1) { 339aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mIndicatorCall = call; 340aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else if (callsetup != -1) { 341aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mIndicatorCallSetup = callsetup; 342aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else if (callheld != -1) { 343aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mIndicatorCallHeld = callheld; 344aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 345aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 346aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // still waiting for some indicators 347aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mIndicatorCall == -1 || mIndicatorCallSetup == -1 || 348aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mIndicatorCallHeld == -1) { 349aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return true; 350aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 351aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 352aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // for start always query calls to define if it is supported 353aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mQueryCallsSupported = queryCallsStart(); 354aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 355aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mQueryCallsSupported) { 356aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return true; 357aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 358aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 359aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // no support for querying calls 360aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 361aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch (mIndicatorCallSetup) { 3628d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CALLSETUP_INCOMING: 3638d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood addCall(BluetoothHeadsetClientCall.CALL_STATE_INCOMING, ""); 364aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 3658d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CALLSETUP_OUTGOING: 3668d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood addCall(BluetoothHeadsetClientCall.CALL_STATE_DIALING, ""); 367aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 3688d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CALLSETUP_ALERTING: 3698d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood addCall(BluetoothHeadsetClientCall.CALL_STATE_ALERTING, ""); 370aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 3718d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CALLSETUP_NONE: 372aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 373aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 374aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 375aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 376aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch (mIndicatorCall) { 3778d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CALL_CALLS_IN_PROGRESS: 3788d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood addCall(BluetoothHeadsetClientCall.CALL_STATE_ACTIVE, ""); 379aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 3808d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CALL_NO_CALLS_IN_PROGRESS: 381aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 382aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 383aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 384aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 385aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch (mIndicatorCallHeld) { 3868d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CALLHELD_HOLD_AND_ACTIVE: 3878d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CALLHELD_HOLD: 3888d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood addCall(BluetoothHeadsetClientCall.CALL_STATE_HELD, ""); 389aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 3908d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CALLHELD_NONE: 391aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 392aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 393aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 394aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 395aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return true; 396aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 397aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 398aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void updateCallIndicator(int call) { 399aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "updateCallIndicator " + call); 400aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 401aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (waitForIndicators(call, -1, -1)) { 402aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return; 403aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 404aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 405aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mQueryCallsSupported) { 406aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendMessage(QUERY_CURRENT_CALLS); 407aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return; 408aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 409aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 4108d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall c = null; 411aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 412aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch (call) { 4138d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CALL_NO_CALLS_IN_PROGRESS: 4148d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood removeCalls(BluetoothHeadsetClientCall.CALL_STATE_ACTIVE, 4158d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall.CALL_STATE_HELD, 4168d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD); 417aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 418aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 4198d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CALL_CALLS_IN_PROGRESS: 4208d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (mIndicatorCall == HeadsetClientHalConstants.CALL_CALLS_IN_PROGRESS) { 421aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // WP7.8 is sending call=1 before setup=0 when rejecting 422aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // waiting call 4238d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (mIndicatorCallSetup != HeadsetClientHalConstants.CALLSETUP_NONE) { 4248d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood c = getCall(BluetoothHeadsetClientCall.CALL_STATE_WAITING); 425aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (c != null) { 4268d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood setCallState(c, BluetoothHeadsetClientCall.CALL_STATE_TERMINATED); 427aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mCalls.remove(c.getId()); 428aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 429aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 430aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 431aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 432aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 433aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 434aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // if there is only waiting call it is changed to incoming so 435aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // don't 436aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // handle it here 4378d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (mIndicatorCallSetup != HeadsetClientHalConstants.CALLSETUP_NONE) { 4388d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood c = getCall(BluetoothHeadsetClientCall.CALL_STATE_DIALING, 4398d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall.CALL_STATE_ALERTING, 4408d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall.CALL_STATE_INCOMING); 441aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (c != null) { 4428d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood setCallState(c, BluetoothHeadsetClientCall.CALL_STATE_ACTIVE); 443aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 444aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 445aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 446aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta updateCallsMultiParty(); 447aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 448aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 449aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 450aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 451aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 452aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mIndicatorCall = call; 453aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 454aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 455aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void updateCallSetupIndicator(int callsetup) { 456aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "updateCallSetupIndicator " + callsetup + " " + mPendingAction.first); 457aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 458aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (waitForIndicators(-1, callsetup, -1)) { 459aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return; 460aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 461aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 462aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mQueryCallsSupported) { 463aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendMessage(QUERY_CURRENT_CALLS); 464aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return; 465aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 466aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 467aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch (callsetup) { 4688d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CALLSETUP_NONE: 469aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch (mPendingAction.first) { 470aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case ACCEPT_CALL: 471aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch ((Integer) mPendingAction.second) { 4728d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CALL_ACTION_ATA: 4738d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood removeCalls(BluetoothHeadsetClientCall.CALL_STATE_DIALING, 4748d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall.CALL_STATE_ALERTING); 475aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta clearPendingAction(); 476aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 4778d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CALL_ACTION_CHLD_1: 4788d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood removeCalls(BluetoothHeadsetClientCall.CALL_STATE_ACTIVE); 4798d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood changeCallsState(BluetoothHeadsetClientCall.CALL_STATE_WAITING, 4808d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall.CALL_STATE_ACTIVE); 481aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta clearPendingAction(); 482aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 4838d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CALL_ACTION_CHLD_2: 484aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // no specific order for callsetup=0 and 485aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // callheld=1 486aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mIndicatorCallHeld == 4878d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientHalConstants.CALLHELD_HOLD_AND_ACTIVE) { 488aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta clearPendingAction(); 489aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 490aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 4918d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CALL_ACTION_CHLD_3: 492aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mIndicatorCallHeld == 4938d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientHalConstants.CALLHELD_NONE) { 494aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta clearPendingAction(); 495aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 496aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 497aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 498aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "Unexpected callsetup=0 while in action ACCEPT_CALL"); 499aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 500aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 501aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 502aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case REJECT_CALL: 503aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch ((Integer) mPendingAction.second) { 5048d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CALL_ACTION_CHUP: 5058d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood removeCalls(BluetoothHeadsetClientCall.CALL_STATE_INCOMING); 506aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta clearPendingAction(); 507aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 5088d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CALL_ACTION_CHLD_0: 5098d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood removeCalls(BluetoothHeadsetClientCall.CALL_STATE_WAITING); 510aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta clearPendingAction(); 511aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 512aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 513aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "Unexpected callsetup=0 while in action REJECT_CALL"); 514aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 515aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 516aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 517aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case DIAL_NUMBER: 518aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case DIAL_MEMORY: 519aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case REDIAL: 520aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case NO_ACTION: 521aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case TERMINATE_CALL: 5228d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood removeCalls(BluetoothHeadsetClientCall.CALL_STATE_INCOMING, 5238d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall.CALL_STATE_DIALING, 5248d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall.CALL_STATE_WAITING, 5258d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall.CALL_STATE_ALERTING); 526aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta clearPendingAction(); 527aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 528aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 529aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "Unexpected callsetup=0 while in action " + 530aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mPendingAction.first); 531aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 532aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 533aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 5348d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CALLSETUP_ALERTING: 5358d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall c = 5368d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood getCall(BluetoothHeadsetClientCall.CALL_STATE_DIALING); 537aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (c == null) { 538aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mPendingAction.first == DIAL_NUMBER) { 5398d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood addCall(BluetoothHeadsetClientCall.CALL_STATE_ALERTING, 540aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta (String) mPendingAction.second); 541aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 5428d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood addCall(BluetoothHeadsetClientCall.CALL_STATE_ALERTING, ""); 543aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 544aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 5458d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood setCallState(c, BluetoothHeadsetClientCall.CALL_STATE_ALERTING); 546aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 547aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 548aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch (mPendingAction.first) { 549aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case DIAL_NUMBER: 550aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case DIAL_MEMORY: 551aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case REDIAL: 552aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta clearPendingAction(); 553aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 554aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 555aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 556aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 557aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 5588d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CALLSETUP_OUTGOING: 559aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mPendingAction.first == DIAL_NUMBER) { 5608d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood addCall(BluetoothHeadsetClientCall.CALL_STATE_DIALING, 561aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta (String) mPendingAction.second); 562aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 5638d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood addCall(BluetoothHeadsetClientCall.CALL_STATE_DIALING, ""); 564aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 565aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 5668d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CALLSETUP_INCOMING: 5678d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (getCall(BluetoothHeadsetClientCall.CALL_STATE_WAITING) == null) 568aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta { 569aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // will get number in clip if known 5708d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood addCall(BluetoothHeadsetClientCall.CALL_STATE_INCOMING, ""); 571aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 572aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 573aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 574aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 575aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 576aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 577aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta updateCallsMultiParty(); 578aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 579aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mIndicatorCallSetup = callsetup; 580aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 581aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 582aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void updateCallHeldIndicator(int callheld) { 583aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "updateCallHeld " + callheld); 584aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 585aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (waitForIndicators(-1, -1, callheld)) { 586aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return; 587aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 588aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 589aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mQueryCallsSupported) { 590aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendMessage(QUERY_CURRENT_CALLS); 591aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return; 592aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 593aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 594aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch (callheld) { 5958d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CALLHELD_NONE: 596aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch (mPendingAction.first) { 597aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case REJECT_CALL: 5988d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood removeCalls(BluetoothHeadsetClientCall.CALL_STATE_HELD); 599aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta clearPendingAction(); 600aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 601aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case ACCEPT_CALL: 602aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch ((Integer) mPendingAction.second) { 6038d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CALL_ACTION_CHLD_1: 6048d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood removeCalls(BluetoothHeadsetClientCall.CALL_STATE_ACTIVE); 6058d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood changeCallsState(BluetoothHeadsetClientCall.CALL_STATE_HELD, 6068d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall.CALL_STATE_ACTIVE); 607aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta clearPendingAction(); 608aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 6098d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CALL_ACTION_CHLD_3: 6108d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood changeCallsState(BluetoothHeadsetClientCall.CALL_STATE_HELD, 6118d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall.CALL_STATE_ACTIVE); 612aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta clearPendingAction(); 613aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 614aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 615aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 616aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 617aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 618aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case NO_ACTION: 6198d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (mIndicatorCall == HeadsetClientHalConstants.CALL_CALLS_IN_PROGRESS && 6208d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood mIndicatorCallHeld == HeadsetClientHalConstants.CALLHELD_HOLD) { 6218d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood changeCallsState(BluetoothHeadsetClientCall.CALL_STATE_HELD, 6228d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall.CALL_STATE_ACTIVE); 623aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 624aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 625aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 6268d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood removeCalls(BluetoothHeadsetClientCall.CALL_STATE_HELD); 627aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 628aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 629aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "Unexpected callheld=0 while in action " + mPendingAction.first); 630aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 631aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 632aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 6338d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CALLHELD_HOLD_AND_ACTIVE: 634aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch (mPendingAction.first) { 635aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case ACCEPT_CALL: 636aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if ((Integer) mPendingAction.second == 6378d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientHalConstants.CALL_ACTION_CHLD_2) { 6388d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall c = 6398d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood getCall(BluetoothHeadsetClientCall.CALL_STATE_WAITING); 640aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (c != null) { // accept 6418d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood changeCallsState(BluetoothHeadsetClientCall.CALL_STATE_ACTIVE, 6428d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall.CALL_STATE_HELD); 6438d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood setCallState(c, BluetoothHeadsetClientCall.CALL_STATE_ACTIVE); 644aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { // swap 6458d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood for (BluetoothHeadsetClientCall cc : mCalls.values()) { 646aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (cc.getState() == 6478d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall.CALL_STATE_ACTIVE) { 648aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta setCallState(cc, 6498d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall.CALL_STATE_HELD); 650aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else if (cc.getState() == 6518d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall.CALL_STATE_HELD) { 652aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta setCallState(cc, 6538d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall.CALL_STATE_ACTIVE); 654aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 655aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 656aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 657aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta clearPendingAction(); 658aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 659aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 660aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case NO_ACTION: 6618d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall c = 6628d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood getCall(BluetoothHeadsetClientCall.CALL_STATE_WAITING); 663aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (c != null) { // accept 6648d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood changeCallsState(BluetoothHeadsetClientCall.CALL_STATE_ACTIVE, 6658d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall.CALL_STATE_HELD); 6668d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood setCallState(c, BluetoothHeadsetClientCall.CALL_STATE_ACTIVE); 667aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 668aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 669aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 670aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // swap 6718d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood for (BluetoothHeadsetClientCall cc : mCalls.values()) { 6728d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (cc.getState() == BluetoothHeadsetClientCall.CALL_STATE_ACTIVE) { 6738d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood setCallState(cc, BluetoothHeadsetClientCall.CALL_STATE_HELD); 6748d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood } else if (cc.getState() == BluetoothHeadsetClientCall.CALL_STATE_HELD) { 6758d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood setCallState(cc, BluetoothHeadsetClientCall.CALL_STATE_ACTIVE); 676aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 677aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 678aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 679aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case ENTER_PRIVATE_MODE: 6808d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood for (BluetoothHeadsetClientCall cc : mCalls.values()) { 6818d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (cc != (BluetoothHeadsetClientCall) mPendingAction.second) { 6828d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood setCallState(cc, BluetoothHeadsetClientCall.CALL_STATE_HELD); 683aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 684aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 685aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta clearPendingAction(); 686aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 687aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 688aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "Unexpected callheld=0 while in action " + mPendingAction.first); 689aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 690aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 691aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 6928d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CALLHELD_HOLD: 693aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch (mPendingAction.first) { 694aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case DIAL_NUMBER: 695aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case DIAL_MEMORY: 696aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case REDIAL: 6978d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood changeCallsState(BluetoothHeadsetClientCall.CALL_STATE_ACTIVE, 6988d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall.CALL_STATE_HELD); 699aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 700aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case REJECT_CALL: 701aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch ((Integer) mPendingAction.second) { 7028d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CALL_ACTION_CHLD_1: 7038d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood removeCalls(BluetoothHeadsetClientCall.CALL_STATE_ACTIVE); 7048d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood changeCallsState(BluetoothHeadsetClientCall.CALL_STATE_HELD, 7058d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall.CALL_STATE_ACTIVE); 706aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta clearPendingAction(); 707aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 7088d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CALL_ACTION_CHLD_3: 7098d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood changeCallsState(BluetoothHeadsetClientCall.CALL_STATE_HELD, 7108d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall.CALL_STATE_ACTIVE); 711aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta clearPendingAction(); 712aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 713aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 714aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 715aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 716aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 717aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case TERMINATE_CALL: 718aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case NO_ACTION: 7198d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood removeCalls(BluetoothHeadsetClientCall.CALL_STATE_ACTIVE); 720aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 721aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 722aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "Unexpected callheld=0 while in action " + mPendingAction.first); 723aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 724aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 725aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 726aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 727aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 728aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 729aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 730aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta updateCallsMultiParty(); 731aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 732aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mIndicatorCallHeld = callheld; 733aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 734aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 735aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void updateRespAndHold(int resp_and_hold) { 736aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "updatRespAndHold " + resp_and_hold); 737aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 738aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mQueryCallsSupported) { 739aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendMessage(QUERY_CURRENT_CALLS); 740aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return; 741aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 742aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 7438d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall c = null; 744aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 745aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch (resp_and_hold) { 7468d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.RESP_AND_HOLD_HELD: 747aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // might be active if it was resp-and-hold before SLC created 7488d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood c = getCall(BluetoothHeadsetClientCall.CALL_STATE_INCOMING, 7498d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall.CALL_STATE_ACTIVE); 750aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (c != null) { 751aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta setCallState(c, 7528d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD); 753aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 7548d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood addCall(BluetoothHeadsetClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD, ""); 755aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 756aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 7578d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.RESP_AND_HOLD_ACCEPT: 7588d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood c = getCall(BluetoothHeadsetClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD); 759aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (c != null) { 7608d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood setCallState(c, BluetoothHeadsetClientCall.CALL_STATE_ACTIVE); 761aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 762aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mPendingAction.first == ACCEPT_CALL && 763aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta (Integer) mPendingAction.second == 7648d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientHalConstants.CALL_ACTION_BTRH_1) { 765aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta clearPendingAction(); 766aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 767aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 7688d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.RESP_AND_HOLD_REJECT: 7698d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood removeCalls(BluetoothHeadsetClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD); 770aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 771aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 772aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 773aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 774aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 775aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 776aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void updateClip(String number) { 7778d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall c = getCall(BluetoothHeadsetClientCall.CALL_STATE_INCOMING); 778aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 779aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (c == null) { 780aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // MeeGo sends CLCC indicating waiting call followed by CLIP when call state changes 781aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // from waiting to incoming in 3WC scenarios. Handle this call state transfer here. 7828d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall cw = getCall(BluetoothHeadsetClientCall.CALL_STATE_WAITING); 783aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if(cw != null) { 7848d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood setCallState(cw, BluetoothHeadsetClientCall.CALL_STATE_INCOMING); 785aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 786aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta else { 7878d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood addCall(BluetoothHeadsetClientCall.CALL_STATE_INCOMING, number); 788aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 789aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 790aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta c.setNumber(number); 791aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendCallChangedIntent(c); 792aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 793aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 794aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 795aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void addCallWaiting(String number) { 7968d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (getCall(BluetoothHeadsetClientCall.CALL_STATE_WAITING) == null) { 7978d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood addCall(BluetoothHeadsetClientCall.CALL_STATE_WAITING, number); 798aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 799aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 800aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 801aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // use ECS 802aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private boolean queryCallsStart() { 803aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "queryCallsStart"); 804aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 805aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // not supported 806aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mQueryCallsSupported == false) { 807aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 808aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 809aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 810aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta clearPendingAction(); 811aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 812aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // already started 813aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mCallsUpdate != null) { 814aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return true; 815aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 816aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 817aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (queryCurrentCallsNative()) { 8188d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood mCallsUpdate = new Hashtable<Integer, BluetoothHeadsetClientCall>(); 819aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta addQueuedAction(QUERY_CURRENT_CALLS, 0); 820aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return true; 821aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 822aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 823aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.i(TAG, "updateCallsStart queryCurrentCallsNative failed"); 824aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mQueryCallsSupported = false; 825aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mCallsUpdate = null; 826aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 827aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 828aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 829aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void queryCallsDone() { 830aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "queryCallsDone"); 8318d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood Iterator<Hashtable.Entry<Integer, BluetoothHeadsetClientCall>> it; 832aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 833aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // check if any call was removed 834aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta it = mCalls.entrySet().iterator(); 835aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta while (it.hasNext()) { 8368d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood Hashtable.Entry<Integer, BluetoothHeadsetClientCall> entry = it.next(); 837aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 838aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mCallsUpdate.containsKey(entry.getKey())) { 839aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta continue; 840aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 841aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 842aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "updateCallsDone call removed id:" + entry.getValue().getId()); 8438d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall c = entry.getValue(); 844aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 8458d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood setCallState(c, BluetoothHeadsetClientCall.CALL_STATE_TERMINATED); 846aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 847aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 848aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta /* check if any calls changed or new call is present */ 849aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta it = mCallsUpdate.entrySet().iterator(); 850aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta while (it.hasNext()) { 8518d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood Hashtable.Entry<Integer, BluetoothHeadsetClientCall> entry = it.next(); 852aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 853aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mCalls.containsKey(entry.getKey())) { 854aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // avoid losing number if was not present in clcc 855aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (entry.getValue().getNumber().equals("")) { 856aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta entry.getValue().setNumber(mCalls.get(entry.getKey()).getNumber()); 857aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 858aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 859aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mCalls.get(entry.getKey()).equals(entry.getValue())) { 860aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta continue; 861aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 862aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 863aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "updateCallsDone call changed id:" + entry.getValue().getId()); 864aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendCallChangedIntent(entry.getValue()); 865aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 866aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "updateCallsDone new call id:" + entry.getValue().getId()); 867aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendCallChangedIntent(entry.getValue()); 868aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 869aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 870aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 871aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mCalls = mCallsUpdate; 872aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mCallsUpdate = null; 873aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 874aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (loopQueryCalls()) { 875aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "queryCallsDone ambigious calls, starting call query loop"); 876aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendMessageDelayed(QUERY_CURRENT_CALLS, 1523); 877aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 878aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 879aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 880aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void queryCallsUpdate(int id, int state, String number, boolean multiParty, 881aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta boolean outgoing) { 882aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "queryCallsUpdate: " + id); 883aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 884aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // should not happen 885aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mCallsUpdate == null) { 886aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return; 887aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 888aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 8890301badedb14c68fe1c0e46efc14eb24411e333cMike Lockwood mCallsUpdate.put(id, new BluetoothHeadsetClientCall(mCurrentDevice, id, state, number, 8900301badedb14c68fe1c0e46efc14eb24411e333cMike Lockwood multiParty, outgoing)); 891aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 892aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 893aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // helper function for determining if query calls should be looped 894aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private boolean loopQueryCalls() { 8958d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (callsInState(BluetoothHeadsetClientCall.CALL_STATE_ACTIVE) > 1) { 896aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return true; 897aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 898aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 899aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // Workaround for Windows Phone 7.8 not sending callsetup=0 after 900aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // rejecting incoming call in 3WC use case (when no active calls present). 901aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // Fixes both, AG and HF rejecting the call. 9028d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall c = getCall(BluetoothHeadsetClientCall.CALL_STATE_INCOMING); 9038d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (c != null && mIndicatorCallSetup == HeadsetClientHalConstants.CALLSETUP_NONE) 904aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return true; 905aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 906aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return false; 907aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 908aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 909aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void acceptCall(int flag, boolean retry) { 910aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int action; 911aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 912aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "acceptCall: (" + flag + ")"); 913aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 9148d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall c = getCall(BluetoothHeadsetClientCall.CALL_STATE_INCOMING, 9158d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall.CALL_STATE_WAITING); 916aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (c == null) { 9178d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood c = getCall(BluetoothHeadsetClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD, 9188d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall.CALL_STATE_HELD); 919aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 920aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (c == null) { 921aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return; 922aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 923aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 924aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 925aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch (c.getState()) { 9268d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case BluetoothHeadsetClientCall.CALL_STATE_INCOMING: 9278d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (flag != BluetoothHeadsetClient.CALL_ACCEPT_NONE) { 928aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return; 929aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 930aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 931aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // Some NOKIA phones with Windows Phone 7.8 and MeeGo requires CHLD=1 932aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // for accepting incoming call if it is the only call present after 933aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // second active remote has disconnected (3WC scenario - call state 934aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // changes from waiting to incoming). On the other hand some Android 935aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // phones and iPhone requires ATA. Try to handle those gently by 936aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // first issuing ATA. Failing means that AG is probably one of those 937aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // phones that requires CHLD=1. Handle this case when we are retrying. 938aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // Accepting incoming calls when there is held one and 939aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // no active should also be handled by ATA. 9408d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood action = HeadsetClientHalConstants.CALL_ACTION_ATA; 941aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 942aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mCalls.size() == 1 && retry) { 9438d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood action = HeadsetClientHalConstants.CALL_ACTION_CHLD_1; 944aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 945aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 9468d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case BluetoothHeadsetClientCall.CALL_STATE_WAITING: 9478d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (callsInState(BluetoothHeadsetClientCall.CALL_STATE_ACTIVE) == 0) { 948aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // if no active calls present only plain accept is allowed 9498d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (flag != BluetoothHeadsetClient.CALL_ACCEPT_NONE) { 950aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return; 951aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 952aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 953aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // Some phones (WP7) require ATA instead of CHLD=2 954aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // to accept waiting call if no active calls are present. 955aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (retry) { 9568d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood action = HeadsetClientHalConstants.CALL_ACTION_ATA; 957aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 9588d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood action = HeadsetClientHalConstants.CALL_ACTION_CHLD_2; 959aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 960aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 961aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 962aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 963aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // if active calls are present action must be selected 9648d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (flag == BluetoothHeadsetClient.CALL_ACCEPT_HOLD) { 9658d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood action = HeadsetClientHalConstants.CALL_ACTION_CHLD_2; 9668d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood } else if (flag == BluetoothHeadsetClient.CALL_ACCEPT_TERMINATE) { 9678d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood action = HeadsetClientHalConstants.CALL_ACTION_CHLD_1; 968aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 969aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return; 970aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 971aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 9728d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case BluetoothHeadsetClientCall.CALL_STATE_HELD: 9738d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (flag == BluetoothHeadsetClient.CALL_ACCEPT_HOLD) { 9748d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood action = HeadsetClientHalConstants.CALL_ACTION_CHLD_2; 9758d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood } else if (flag == BluetoothHeadsetClient.CALL_ACCEPT_TERMINATE) { 9768d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood action = HeadsetClientHalConstants.CALL_ACTION_CHLD_1; 9778d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood } else if (getCall(BluetoothHeadsetClientCall.CALL_STATE_ACTIVE) != null) { 9788d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood action = HeadsetClientHalConstants.CALL_ACTION_CHLD_3; 979aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 9808d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood action = HeadsetClientHalConstants.CALL_ACTION_CHLD_2; 981aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 982aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 9838d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case BluetoothHeadsetClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD: 9848d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (flag != BluetoothHeadsetClient.CALL_ACCEPT_NONE) { 985aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return; 986aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 9878d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood action = HeadsetClientHalConstants.CALL_ACTION_BTRH_1; 988aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 9898d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case BluetoothHeadsetClientCall.CALL_STATE_ALERTING: 9908d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case BluetoothHeadsetClientCall.CALL_STATE_ACTIVE: 9918d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case BluetoothHeadsetClientCall.CALL_STATE_DIALING: 992aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 993aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return; 994aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 995aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 9963ee63fdfb7fa5896bff7e172be60c763919c9f63Christine Hallstrom if (flag == BluetoothHeadsetClient.CALL_ACCEPT_HOLD) { 9973ee63fdfb7fa5896bff7e172be60c763919c9f63Christine Hallstrom // HFP is disabled when a call is put on hold to ensure correct audio routing for 9983ee63fdfb7fa5896bff7e172be60c763919c9f63Christine Hallstrom // cellular calls accepted while an HFP call is in progress. Reenable HFP when the HFP 9993ee63fdfb7fa5896bff7e172be60c763919c9f63Christine Hallstrom // call is put off hold. 10003ee63fdfb7fa5896bff7e172be60c763919c9f63Christine Hallstrom Log.d(TAG,"hfp_enable=true"); 10013ee63fdfb7fa5896bff7e172be60c763919c9f63Christine Hallstrom mAudioManager.setParameters("hfp_enable=true"); 10023ee63fdfb7fa5896bff7e172be60c763919c9f63Christine Hallstrom } 10033ee63fdfb7fa5896bff7e172be60c763919c9f63Christine Hallstrom 1004aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (handleCallActionNative(action, 0)) { 1005aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta addQueuedAction(ACCEPT_CALL, action); 1006aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 1007aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "ERROR: Couldn't accept a call, action:" + action); 1008aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1009aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1010aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1011aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void rejectCall() { 1012aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int action; 1013aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1014aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "rejectCall"); 1015aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 10168d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall c = 10178d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood getCall(BluetoothHeadsetClientCall.CALL_STATE_INCOMING, 10188d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall.CALL_STATE_WAITING, 10198d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD, 10208d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall.CALL_STATE_HELD); 1021aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (c == null) { 1022aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return; 1023aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1024aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1025aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch (c.getState()) { 10268d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case BluetoothHeadsetClientCall.CALL_STATE_INCOMING: 10278d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood action = HeadsetClientHalConstants.CALL_ACTION_CHUP; 1028aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 10298d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case BluetoothHeadsetClientCall.CALL_STATE_WAITING: 10308d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case BluetoothHeadsetClientCall.CALL_STATE_HELD: 10318d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood action = HeadsetClientHalConstants.CALL_ACTION_CHLD_0; 1032aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 10338d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case BluetoothHeadsetClientCall.CALL_STATE_HELD_BY_RESPONSE_AND_HOLD: 10348d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood action = HeadsetClientHalConstants.CALL_ACTION_BTRH_2; 1035aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 10368d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case BluetoothHeadsetClientCall.CALL_STATE_ACTIVE: 10378d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case BluetoothHeadsetClientCall.CALL_STATE_DIALING: 10388d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case BluetoothHeadsetClientCall.CALL_STATE_ALERTING: 1039aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 1040aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return; 1041aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1042aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1043aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (handleCallActionNative(action, 0)) { 1044aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta addQueuedAction(REJECT_CALL, action); 1045aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 1046aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "ERROR: Couldn't reject a call, action:" + action); 1047aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1048aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1049aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1050aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void holdCall() { 1051aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int action; 1052aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1053aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "holdCall"); 1054aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 10558d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall c = getCall(BluetoothHeadsetClientCall.CALL_STATE_INCOMING); 1056aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (c != null) { 10578d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood action = HeadsetClientHalConstants.CALL_ACTION_BTRH_0; 1058aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 10598d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood c = getCall(BluetoothHeadsetClientCall.CALL_STATE_ACTIVE); 1060aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (c == null) { 1061aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return; 1062aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1063aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 10648d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood action = HeadsetClientHalConstants.CALL_ACTION_CHLD_2; 1065aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1066aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 10673ee63fdfb7fa5896bff7e172be60c763919c9f63Christine Hallstrom // Set HFP enable to false in case the call is being held to accept a cellular call. This 10683ee63fdfb7fa5896bff7e172be60c763919c9f63Christine Hallstrom // allows the cellular call's audio to be correctly routed. 10693ee63fdfb7fa5896bff7e172be60c763919c9f63Christine Hallstrom Log.d(TAG,"hfp_enable=false"); 10703ee63fdfb7fa5896bff7e172be60c763919c9f63Christine Hallstrom mAudioManager.setParameters("hfp_enable=false"); 10713ee63fdfb7fa5896bff7e172be60c763919c9f63Christine Hallstrom 1072aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (handleCallActionNative(action, 0)) { 1073aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta addQueuedAction(HOLD_CALL, action); 1074aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 1075aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "ERROR: Couldn't hold a call, action:" + action); 1076aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1077aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1078aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1079aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void terminateCall(int idx) { 1080aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "terminateCall: " + idx); 1081aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1082aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (idx == 0) { 10838d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood int action = HeadsetClientHalConstants.CALL_ACTION_CHUP; 1084aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 10858d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall c = getCall( 10868d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall.CALL_STATE_DIALING, 10878d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall.CALL_STATE_ALERTING); 1088aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (c != null) { 1089aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (handleCallActionNative(action, 0)) { 1090aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta addQueuedAction(TERMINATE_CALL, action); 1091aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 1092aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "ERROR: Couldn't terminate outgoing call"); 1093aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1094aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1095aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 10968d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (callsInState(BluetoothHeadsetClientCall.CALL_STATE_ACTIVE) > 0) { 1097aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (handleCallActionNative(action, 0)) { 1098aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta addQueuedAction(TERMINATE_CALL, action); 1099aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 1100aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "ERROR: Couldn't terminate active calls"); 1101aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1102aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1103aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 1104aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int action; 11058d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall c = mCalls.get(idx); 1106aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1107aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (c == null) { 1108aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return; 1109aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1110aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1111aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch (c.getState()) { 11128d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case BluetoothHeadsetClientCall.CALL_STATE_ACTIVE: 11138d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood action = HeadsetClientHalConstants.CALL_ACTION_CHLD_1x; 1114aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 11158d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case BluetoothHeadsetClientCall.CALL_STATE_DIALING: 11168d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case BluetoothHeadsetClientCall.CALL_STATE_ALERTING: 11178d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood action = HeadsetClientHalConstants.CALL_ACTION_CHUP; 1118aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1119aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 1120aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return; 1121aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1122aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1123aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (handleCallActionNative(action, idx)) { 11248d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (action == HeadsetClientHalConstants.CALL_ACTION_CHLD_1x) { 1125aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta addQueuedAction(TERMINATE_SPECIFIC_CALL, c); 1126aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 1127aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta addQueuedAction(TERMINATE_CALL, action); 1128aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1129aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 1130aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "ERROR: Couldn't terminate a call, action:" + action + " id:" + idx); 1131aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1132aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1133aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1134aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1135aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void enterPrivateMode(int idx) { 1136aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "enterPrivateMode: " + idx); 1137aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 11388d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall c = mCalls.get(idx); 1139aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1140aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (c == null) { 1141aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return; 1142aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1143aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 11448d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (c.getState() != BluetoothHeadsetClientCall.CALL_STATE_ACTIVE) { 1145aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return; 1146aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1147aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1148aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (!c.isMultiParty()) { 1149aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return; 1150aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1151aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 11528d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (handleCallActionNative(HeadsetClientHalConstants.CALL_ACTION_CHLD_2x, idx)) { 1153aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta addQueuedAction(ENTER_PRIVATE_MODE, c); 1154aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 1155aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "ERROR: Couldn't enter private " + " id:" + idx); 1156aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1157aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1158aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1159aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void explicitCallTransfer() { 1160aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "explicitCallTransfer"); 1161aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1162aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // can't transfer call if there is not enough call parties 1163aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mCalls.size() < 2) { 1164aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return; 1165aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1166aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 11678d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (handleCallActionNative(HeadsetClientHalConstants.CALL_ACTION_CHLD_4, -1)) { 1168aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta addQueuedAction(EXPLICIT_CALL_TRANSFER); 1169aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 1170aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "ERROR: Couldn't transfer call"); 1171aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1172aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1173aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1174aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public Bundle getCurrentAgFeatures() 1175aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta { 1176aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Bundle b = new Bundle(); 11778d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if ((mPeerFeatures & HeadsetClientHalConstants.PEER_FEAT_3WAY) == 11788d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientHalConstants.PEER_FEAT_3WAY) { 11798d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood b.putBoolean(BluetoothHeadsetClient.EXTRA_AG_FEATURE_3WAY_CALLING, true); 1180aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 11818d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if ((mPeerFeatures & HeadsetClientHalConstants.PEER_FEAT_VREC) == 11828d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientHalConstants.PEER_FEAT_VREC) { 11838d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood b.putBoolean(BluetoothHeadsetClient.EXTRA_AG_FEATURE_VOICE_RECOGNITION, true); 1184aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 11858d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if ((mPeerFeatures & HeadsetClientHalConstants.PEER_FEAT_VTAG) == 11868d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientHalConstants.PEER_FEAT_VTAG) { 11878d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood b.putBoolean(BluetoothHeadsetClient.EXTRA_AG_FEATURE_ATTACH_NUMBER_TO_VT, true); 1188aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 11898d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if ((mPeerFeatures & HeadsetClientHalConstants.PEER_FEAT_REJECT) == 11908d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientHalConstants.PEER_FEAT_REJECT) { 11918d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood b.putBoolean(BluetoothHeadsetClient.EXTRA_AG_FEATURE_REJECT_CALL, true); 1192aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 11938d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if ((mPeerFeatures & HeadsetClientHalConstants.PEER_FEAT_ECC) == 11948d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientHalConstants.PEER_FEAT_ECC) { 11958d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood b.putBoolean(BluetoothHeadsetClient.EXTRA_AG_FEATURE_ECC, true); 1196aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1197aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1198aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // add individual CHLD support extras 11998d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if ((mChldFeatures & HeadsetClientHalConstants.CHLD_FEAT_HOLD_ACC) == 12008d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientHalConstants.CHLD_FEAT_HOLD_ACC) { 12018d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood b.putBoolean(BluetoothHeadsetClient.EXTRA_AG_FEATURE_ACCEPT_HELD_OR_WAITING_CALL, true); 1202aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 12038d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if ((mChldFeatures & HeadsetClientHalConstants.CHLD_FEAT_REL) == 12048d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientHalConstants.CHLD_FEAT_REL) { 12058d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood b.putBoolean(BluetoothHeadsetClient.EXTRA_AG_FEATURE_RELEASE_HELD_OR_WAITING_CALL, true); 1206aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 12078d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if ((mChldFeatures & HeadsetClientHalConstants.CHLD_FEAT_REL_ACC) == 12088d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientHalConstants.CHLD_FEAT_REL_ACC) { 12098d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood b.putBoolean(BluetoothHeadsetClient.EXTRA_AG_FEATURE_RELEASE_AND_ACCEPT, true); 1210aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 12118d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if ((mChldFeatures & HeadsetClientHalConstants.CHLD_FEAT_MERGE) == 12128d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientHalConstants.CHLD_FEAT_MERGE) { 12138d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood b.putBoolean(BluetoothHeadsetClient.EXTRA_AG_FEATURE_MERGE, true); 1214aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 12158d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if ((mChldFeatures & HeadsetClientHalConstants.CHLD_FEAT_MERGE_DETACH) == 12168d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientHalConstants.CHLD_FEAT_MERGE_DETACH) { 12178d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood b.putBoolean(BluetoothHeadsetClient.EXTRA_AG_FEATURE_MERGE_AND_DETACH, true); 1218aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1219aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1220aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return b; 1221aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1222aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 12238d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood private HeadsetClientStateMachine(HeadsetClientService context) { 1224aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta super(TAG); 1225aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mService = context; 1226aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1227aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mAdapter = BluetoothAdapter.getDefaultAdapter(); 1228aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); 12298d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood mAudioState = BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED; 1230aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mAudioWbs = false; 1231aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 123222bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee mAudioRouteAllowed = context.getResources().getBoolean( 123322bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee R.bool.headset_client_initial_audio_route_allowed); 123422bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee 1235a9ad98ec1222093baecd70b32611c3a74ba7f2d8Sanket Agarwal mTelecomManager = (TelecomManager) context.getSystemService(context.TELECOM_SERVICE); 1236a9ad98ec1222093baecd70b32611c3a74ba7f2d8Sanket Agarwal 12378d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood mIndicatorNetworkState = HeadsetClientHalConstants.NETWORK_STATE_NOT_AVAILABLE; 12388d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood mIndicatorNetworkType = HeadsetClientHalConstants.SERVICE_TYPE_HOME; 1239aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mIndicatorNetworkSignal = 0; 1240aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mIndicatorBatteryLevel = 0; 1241aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1242aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // all will be set on connected 1243aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mIndicatorCall = -1; 1244aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mIndicatorCallSetup = -1; 1245aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mIndicatorCallHeld = -1; 1246aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1247d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal mMaxAmVcVol = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL); 1248d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal mMinAmVcVol = mAudioManager.getStreamMinVolume(AudioManager.STREAM_VOICE_CALL); 1249d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal 1250aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mOperatorName = null; 1251aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mSubscriberInfo = null; 1252aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 12538d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood mVoiceRecognitionActive = HeadsetClientHalConstants.VR_STATE_STOPPED; 12548d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood mInBandRingtone = HeadsetClientHalConstants.IN_BAND_RING_NOT_PROVIDED; 1255aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1256aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mQueuedActions = new LinkedList<Pair<Integer, Object>>(); 1257aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta clearPendingAction(); 1258aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 12598d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood mCalls = new Hashtable<Integer, BluetoothHeadsetClientCall>(); 1260aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mCallsUpdate = null; 1261aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mQueryCallsSupported = true; 1262aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1263aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta initializeNative(); 1264aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mNativeAvailable = true; 1265aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1266aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mDisconnected = new Disconnected(); 1267aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mConnecting = new Connecting(); 1268aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mConnected = new Connected(); 1269aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mAudioOn = new AudioOn(); 1270aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1271aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta addState(mDisconnected); 1272aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta addState(mConnecting); 1273aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta addState(mConnected); 1274aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta addState(mAudioOn, mConnected); 1275aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1276aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta setInitialState(mDisconnected); 1277aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1278aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 12798d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood static HeadsetClientStateMachine make(HeadsetClientService context) { 1280aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "make"); 12818d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientStateMachine hfcsm = new HeadsetClientStateMachine(context); 1282aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta hfcsm.start(); 1283aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return hfcsm; 1284aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1285aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1286aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public void doQuit() { 1287aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta quitNow(); 1288aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1289aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1290aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public void cleanup() { 1291aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mNativeAvailable) { 1292aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta cleanupNative(); 1293aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mNativeAvailable = false; 1294aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1295aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1296aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1297d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal private int hfToAmVol(int hfVol) { 1298d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal int amRange = mMaxAmVcVol - mMinAmVcVol; 1299d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal int hfRange = MAX_HFP_SCO_VOICE_CALL_VOLUME - MIN_HFP_SCO_VOICE_CALL_VOLUME; 1300d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal int amOffset = 1301d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal (amRange * (hfVol - MIN_HFP_SCO_VOICE_CALL_VOLUME)) / hfRange; 1302d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal int amVol = mMinAmVcVol + amOffset; 1303d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal Log.d(TAG, "HF -> AM " + hfVol + " " + amVol); 1304d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal return amVol; 1305d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal } 1306d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal 1307d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal private int amToHfVol(int amVol) { 1308d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal int amRange = mMaxAmVcVol - mMinAmVcVol; 1309d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal int hfRange = MAX_HFP_SCO_VOICE_CALL_VOLUME - MIN_HFP_SCO_VOICE_CALL_VOLUME; 1310d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal int hfOffset = (hfRange * (amVol - mMinAmVcVol)) / amRange; 1311d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal int hfVol = MIN_HFP_SCO_VOICE_CALL_VOLUME + hfOffset; 1312d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal Log.d(TAG, "AM -> HF " + amVol + " " + hfVol); 1313d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal return hfVol; 1314d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal } 1315d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal 1316aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private class Disconnected extends State { 1317aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 1318aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public void enter() { 1319aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "Enter Disconnected: " + getCurrentMessage().what); 1320aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1321aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // cleanup 13228d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood mIndicatorNetworkState = HeadsetClientHalConstants.NETWORK_STATE_NOT_AVAILABLE; 13238d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood mIndicatorNetworkType = HeadsetClientHalConstants.SERVICE_TYPE_HOME; 1324aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mIndicatorNetworkSignal = 0; 1325aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mIndicatorBatteryLevel = 0; 1326aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1327aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mAudioWbs = false; 1328aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1329aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // will be set on connect 1330aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mIndicatorCall = -1; 1331aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mIndicatorCallSetup = -1; 1332aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mIndicatorCallHeld = -1; 1333aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1334aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mOperatorName = null; 1335aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mSubscriberInfo = null; 1336aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1337aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mQueuedActions = new LinkedList<Pair<Integer, Object>>(); 1338aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta clearPendingAction(); 1339aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 13408d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood mVoiceRecognitionActive = HeadsetClientHalConstants.VR_STATE_STOPPED; 13418d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood mInBandRingtone = HeadsetClientHalConstants.IN_BAND_RING_NOT_PROVIDED; 1342aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 13438d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood mCalls = new Hashtable<Integer, BluetoothHeadsetClientCall>(); 1344aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mCallsUpdate = null; 1345aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mQueryCallsSupported = true; 1346aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1347aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mPeerFeatures = 0; 1348aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mChldFeatures = 0; 1349aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1350aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta removeMessages(QUERY_CURRENT_CALLS); 1351aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1352aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1353aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 1354aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public synchronized boolean processMessage(Message message) { 1355aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "Disconnected process message: " + message.what); 1356aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1357aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mCurrentDevice != null) { 1358aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "ERROR: current device not null in Disconnected"); 1359aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return NOT_HANDLED; 1360aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1361aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1362aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch (message.what) { 1363aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case CONNECT: 1364aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta BluetoothDevice device = (BluetoothDevice) message.obj; 1365aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1366aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta broadcastConnectionState(device, BluetoothProfile.STATE_CONNECTING, 1367aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta BluetoothProfile.STATE_DISCONNECTED); 1368aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1369aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (!connectNative(getByteAddress(device))) { 1370aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED, 1371aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta BluetoothProfile.STATE_CONNECTING); 1372aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1373aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1374aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1375aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mCurrentDevice = device; 1376aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta transitionTo(mConnecting); 1377aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1378aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case DISCONNECT: 1379aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // ignore 1380aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1381aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case STACK_EVENT: 1382aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta StackEvent event = (StackEvent) message.obj; 1383aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (DBG) { 1384aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "Stack event type: " + event.type); 1385aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1386aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch (event.type) { 1387aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_CONNECTION_STATE_CHANGED: 1388aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "Disconnected: Connection " + event.device 1389aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta + " state changed:" + event.valueInt); 1390aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta processConnectionEvent(event.valueInt, event.device); 1391aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1392aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 1393aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "Disconnected: Unexpected stack event: " + event.type); 1394aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1395aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1396aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1397aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 1398aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return NOT_HANDLED; 1399aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1400aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return HANDLED; 1401aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1402aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1403aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // in Disconnected state 1404aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void processConnectionEvent(int state, BluetoothDevice device) 1405aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta { 1406aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch (state) { 14078d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CONNECTION_STATE_CONNECTED: 1408aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.w(TAG, "HFPClient Connecting from Disconnected state"); 1409aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (okToConnect(device)) { 1410aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.i(TAG, "Incoming AG accepted"); 1411aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta broadcastConnectionState(device, BluetoothProfile.STATE_CONNECTING, 1412aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta BluetoothProfile.STATE_DISCONNECTED); 1413aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mCurrentDevice = device; 1414aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta transitionTo(mConnecting); 1415aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 1416aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.i(TAG, "Incoming AG rejected. priority=" + mService.getPriority(device) 1417aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta + 1418aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta " bondState=" + device.getBondState()); 1419aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // reject the connection and stay in Disconnected state 1420aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // itself 1421aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta disconnectNative(getByteAddress(device)); 1422aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // the other profile connection should be initiated 1423aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta AdapterService adapterService = AdapterService.getAdapterService(); 1424aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (adapterService != null) { 1425aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta adapterService.connectOtherProfile(device, 1426aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta AdapterService.PROFILE_CONN_REJECTED); 1427aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1428aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1429aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 14308d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CONNECTION_STATE_CONNECTING: 14318d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CONNECTION_STATE_DISCONNECTED: 14328d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CONNECTION_STATE_DISCONNECTING: 1433aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 1434aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.i(TAG, "ignoring state: " + state); 1435aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1436aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1437aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1438aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1439aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 1440aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public void exit() { 1441aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "Exit Disconnected: " + getCurrentMessage().what); 1442aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1443aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1444aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1445aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private class Connecting extends State { 1446aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 1447aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public void enter() { 1448aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "Enter Connecting: " + getCurrentMessage().what); 1449aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1450aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1451aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 1452aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public synchronized boolean processMessage(Message message) { 1453aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "Connecting process message: " + message.what); 1454aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1455aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta boolean retValue = HANDLED; 1456aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch (message.what) { 1457aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case CONNECT: 1458aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case CONNECT_AUDIO: 1459aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case DISCONNECT: 1460aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta deferMessage(message); 1461aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1462aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case STACK_EVENT: 1463aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta StackEvent event = (StackEvent) message.obj; 1464aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (DBG) { 1465aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "Connecting: event type: " + event.type); 1466aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1467aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch (event.type) { 1468aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_CONNECTION_STATE_CHANGED: 1469aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "Connecting: Connection " + event.device + " state changed:" 1470aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta + event.valueInt); 1471aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta processConnectionEvent(event.valueInt, event.valueInt2, 1472aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueInt3, event.device); 1473aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1474aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_AUDIO_STATE_CHANGED: 1475aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_VR_STATE_CHANGED: 1476aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_NETWORK_STATE: 1477aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_ROAMING_STATE: 1478aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_NETWORK_SIGNAL: 1479aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_BATTERY_LEVEL: 1480aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_CALL: 1481aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_CALLSETUP: 1482aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_CALLHELD: 1483aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_RESP_AND_HOLD: 1484aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_CLIP: 1485aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_CALL_WAITING: 1486aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_VOLUME_CHANGED: 1487aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_IN_BAND_RING: 1488aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta deferMessage(message); 1489aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1490aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_CMD_RESULT: 1491aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_SUBSCRIBER_INFO: 1492aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_CURRENT_CALLS: 1493aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_OPERATOR_NAME: 1494aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 1495aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "Connecting: ignoring stack event: " + event.type); 1496aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1497aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1498aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1499aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 1500aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return NOT_HANDLED; 1501aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1502aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return retValue; 1503aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1504aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1505aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // in Connecting state 1506aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void processConnectionEvent(int state, int peer_feat, int chld_feat, BluetoothDevice device) { 1507aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch (state) { 15088d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CONNECTION_STATE_DISCONNECTED: 1509aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta broadcastConnectionState(mCurrentDevice, BluetoothProfile.STATE_DISCONNECTED, 1510aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta BluetoothProfile.STATE_CONNECTING); 1511aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mCurrentDevice = null; 1512aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta transitionTo(mDisconnected); 1513aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 15148d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CONNECTION_STATE_SLC_CONNECTED: 1515aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.w(TAG, "HFPClient Connected from Connecting state"); 1516aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1517aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mPeerFeatures = peer_feat; 1518aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mChldFeatures = chld_feat; 1519aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1520aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta broadcastConnectionState(mCurrentDevice, BluetoothProfile.STATE_CONNECTED, 1521aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta BluetoothProfile.STATE_CONNECTING); 1522aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // Send AT+NREC to remote if supported by audio 1523d1fadc3b23a03cbf028bfbdca9fd64640d7a05bdDavid Stevens if (HeadsetClientHalConstants.HANDSFREECLIENT_NREC_SUPPORTED && 1524d1fadc3b23a03cbf028bfbdca9fd64640d7a05bdDavid Stevens ((mPeerFeatures & HeadsetClientHalConstants.PEER_FEAT_ECNR) == 1525d1fadc3b23a03cbf028bfbdca9fd64640d7a05bdDavid Stevens HeadsetClientHalConstants.PEER_FEAT_ECNR)) { 1526d1fadc3b23a03cbf028bfbdca9fd64640d7a05bdDavid Stevens if (sendATCmdNative(HeadsetClientHalConstants.HANDSFREECLIENT_AT_CMD_NREC, 1527d1fadc3b23a03cbf028bfbdca9fd64640d7a05bdDavid Stevens 1 , 0, null)) { 1528d1fadc3b23a03cbf028bfbdca9fd64640d7a05bdDavid Stevens addQueuedAction(DISABLE_NREC); 1529d1fadc3b23a03cbf028bfbdca9fd64640d7a05bdDavid Stevens } else { 1530d1fadc3b23a03cbf028bfbdca9fd64640d7a05bdDavid Stevens Log.e(TAG, "Failed to send NREC"); 1531d1fadc3b23a03cbf028bfbdca9fd64640d7a05bdDavid Stevens } 1532aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1533aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta transitionTo(mConnected); 1534aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1535d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal int amVol = mAudioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL); 1536d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal sendMessage( 1537d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal obtainMessage(HeadsetClientStateMachine.SET_SPEAKER_VOLUME, amVol, 0)); 15383076d2acccf5c3db0db19b622f062e259be39f3aSanket Agarwal // Mic is either in ON state (full volume) or OFF state. There is no way in 15393076d2acccf5c3db0db19b622f062e259be39f3aSanket Agarwal // Android to change the MIC volume. 15408d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood sendMessage(obtainMessage(HeadsetClientStateMachine.SET_MIC_VOLUME, 1541aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mAudioManager.isMicrophoneMute() ? 0 : 15, 0)); 1542aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1543aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // query subscriber info 15448d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood sendMessage(HeadsetClientStateMachine.SUBSCRIBER_INFO); 1545aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 15468d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CONNECTION_STATE_CONNECTED: 1547aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (!mCurrentDevice.equals(device)) { 1548aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.w(TAG, "incoming connection event, device: " + device); 1549aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1550aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta broadcastConnectionState(mCurrentDevice, 1551aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta BluetoothProfile.STATE_DISCONNECTED, 1552aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta BluetoothProfile.STATE_CONNECTING); 1553aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta broadcastConnectionState(device, BluetoothProfile.STATE_CONNECTING, 1554aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta BluetoothProfile.STATE_DISCONNECTED); 1555aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1556aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mCurrentDevice = device; 1557aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1558aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 15598d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CONNECTION_STATE_CONNECTING: 1560aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta /* outgoing connecting started */ 1561aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "outgoing connection started, ignore"); 1562aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 15638d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CONNECTION_STATE_DISCONNECTING: 1564aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 1565aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "Incorrect state: " + state); 1566aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1567aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1568aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1569aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1570aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 1571aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public void exit() { 1572aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "Exit Connecting: " + getCurrentMessage().what); 1573aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1574aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1575aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1576aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private class Connected extends State { 1577aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 1578aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public void enter() { 1579aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "Enter Connected: " + getCurrentMessage().what); 1580aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1581aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mAudioWbs = false; 1582aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1583aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1584aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 1585aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public synchronized boolean processMessage(Message message) { 1586aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "Connected process message: " + message.what); 1587aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (DBG) { 1588aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mCurrentDevice == null) { 1589aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "ERROR: mCurrentDevice is null in Connected"); 1590aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return NOT_HANDLED; 1591aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1592aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1593aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1594aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch (message.what) { 1595aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case CONNECT: 1596aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta BluetoothDevice device = (BluetoothDevice) message.obj; 1597aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mCurrentDevice.equals(device)) { 1598aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // already connected to this device, do nothing 1599aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1600aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1601aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1602aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (!disconnectNative(getByteAddress(mCurrentDevice))) { 1603aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // if succeed this will be handled from disconnected 1604aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // state 1605aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta broadcastConnectionState(device, BluetoothProfile.STATE_CONNECTING, 1606aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta BluetoothProfile.STATE_DISCONNECTED); 1607aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED, 1608aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta BluetoothProfile.STATE_CONNECTING); 1609aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1610aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1611aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1612aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // will be handled when entered disconnected 1613aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta deferMessage(message); 1614aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1615aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case DISCONNECT: 1616aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta BluetoothDevice dev = (BluetoothDevice) message.obj; 1617aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (!mCurrentDevice.equals(dev)) { 1618aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1619aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1620aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta broadcastConnectionState(dev, BluetoothProfile.STATE_DISCONNECTING, 1621aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta BluetoothProfile.STATE_CONNECTED); 1622aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (!disconnectNative(getByteAddress(dev))) { 1623aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // disconnecting failed 1624aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta broadcastConnectionState(dev, BluetoothProfile.STATE_CONNECTED, 1625aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta BluetoothProfile.STATE_DISCONNECTED); 1626aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1627aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1628aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1629aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case CONNECT_AUDIO: 1630aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // TODO: handle audio connection failure 1631aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (!connectAudioNative(getByteAddress(mCurrentDevice))) { 1632aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "ERROR: Couldn't connect Audio."); 1633aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1634aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1635aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case DISCONNECT_AUDIO: 1636aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // TODO: handle audio disconnection failure 1637aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (!disconnectAudioNative(getByteAddress(mCurrentDevice))) { 1638aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "ERROR: Couldn't connect Audio."); 1639aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1640aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1641aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case VOICE_RECOGNITION_START: 16428d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (mVoiceRecognitionActive == HeadsetClientHalConstants.VR_STATE_STOPPED) { 1643aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (startVoiceRecognitionNative()) { 1644aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta addQueuedAction(VOICE_RECOGNITION_START); 1645aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 1646aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "ERROR: Couldn't start voice recognition"); 1647aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1648aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1649aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1650aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case VOICE_RECOGNITION_STOP: 16518d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (mVoiceRecognitionActive == HeadsetClientHalConstants.VR_STATE_STARTED) { 1652aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (stopVoiceRecognitionNative()) { 1653aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta addQueuedAction(VOICE_RECOGNITION_STOP); 1654aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 1655aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "ERROR: Couldn't stop voice recognition"); 1656aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1657aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1658aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 16593076d2acccf5c3db0db19b622f062e259be39f3aSanket Agarwal // Called only for Mute/Un-mute - Mic volume change is not allowed. 1660aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case SET_MIC_VOLUME: 1661aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mVgmFromStack) { 1662aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mVgmFromStack = false; 1663aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1664aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 16658d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (setVolumeNative(HeadsetClientHalConstants.VOLUME_TYPE_MIC, message.arg1)) { 1666aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta addQueuedAction(SET_MIC_VOLUME); 1667aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1668aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1669aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case SET_SPEAKER_VOLUME: 1670d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal // This message should always contain the volume in AudioManager max normalized. 1671d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal int amVol = message.arg1; 1672d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal int hfVol = amToHfVol(amVol); 1673d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal Log.d(TAG,"HF volume is set to " + hfVol); 1674d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal mAudioManager.setParameters("hfp_volume=" + hfVol); 1675aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mVgsFromStack) { 1676aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mVgsFromStack = false; 1677aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1678aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1679d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal if (setVolumeNative(HeadsetClientHalConstants.VOLUME_TYPE_SPK, hfVol)) { 1680aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta addQueuedAction(SET_SPEAKER_VOLUME); 1681aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1682aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1683aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case REDIAL: 1684aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (dialNative(null)) { 1685aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta addQueuedAction(REDIAL); 1686aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 1687aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "ERROR: Cannot redial"); 1688aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1689aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1690aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case DIAL_NUMBER: 1691aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (dialNative((String) message.obj)) { 1692aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta addQueuedAction(DIAL_NUMBER, message.obj); 1693aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 1694aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "ERROR: Cannot dial with a given number:" + (String) message.obj); 1695aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1696aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1697aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case DIAL_MEMORY: 1698aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (dialMemoryNative(message.arg1)) { 1699aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta addQueuedAction(DIAL_MEMORY); 1700aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 1701aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "ERROR: Cannot dial with a given location:" + message.arg1); 1702aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1703aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1704aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case ACCEPT_CALL: 1705aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta acceptCall(message.arg1, false); 1706aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1707aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case REJECT_CALL: 1708aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta rejectCall(); 1709aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1710aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case HOLD_CALL: 1711aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta holdCall(); 1712aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1713aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case TERMINATE_CALL: 1714aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta terminateCall(message.arg1); 1715aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1716aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case ENTER_PRIVATE_MODE: 1717aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta enterPrivateMode(message.arg1); 1718aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1719aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EXPLICIT_CALL_TRANSFER: 1720aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta explicitCallTransfer(); 1721aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1722aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case SEND_DTMF: 1723aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (sendDtmfNative((byte) message.arg1)) { 1724aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta addQueuedAction(SEND_DTMF); 1725aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 1726aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "ERROR: Couldn't send DTMF"); 1727aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1728aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1729aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case SUBSCRIBER_INFO: 1730aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (retrieveSubscriberInfoNative()) { 1731aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta addQueuedAction(SUBSCRIBER_INFO); 1732aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 1733aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "ERROR: Couldn't retrieve subscriber info"); 1734aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1735aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1736aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case LAST_VTAG_NUMBER: 1737aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (requestLastVoiceTagNumberNative()) { 1738aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta addQueuedAction(LAST_VTAG_NUMBER); 1739aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 1740aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "ERROR: Couldn't get last VTAG number"); 1741aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1742aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1743aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case QUERY_CURRENT_CALLS: 1744aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta queryCallsStart(); 1745aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1746aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case STACK_EVENT: 1747aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Intent intent = null; 1748aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta StackEvent event = (StackEvent) message.obj; 1749aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (DBG) { 1750aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "Connected: event type: " + event.type); 1751aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1752aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1753aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch (event.type) { 1754aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_CONNECTION_STATE_CHANGED: 1755aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "Connected: Connection state changed: " + event.device 1756aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta + ": " + event.valueInt); 1757aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta processConnectionEvent(event.valueInt, event.device); 1758aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1759aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_AUDIO_STATE_CHANGED: 1760aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "Connected: Audio state changed: " + event.device + ": " 1761aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta + event.valueInt); 1762aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta processAudioEvent(event.valueInt, event.device); 1763aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1764aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_NETWORK_STATE: 1765aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "Connected: Network state: " + event.valueInt); 1766aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1767aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mIndicatorNetworkState = event.valueInt; 1768aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 17698d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT); 17708d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent.putExtra(BluetoothHeadsetClient.EXTRA_NETWORK_STATUS, 1771aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueInt); 1772aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1773aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mIndicatorNetworkState == 17748d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientHalConstants.NETWORK_STATE_NOT_AVAILABLE) { 1775aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mOperatorName = null; 17768d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent.putExtra(BluetoothHeadsetClient.EXTRA_OPERATOR_NAME, 1777aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mOperatorName); 1778aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1779aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1780aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device); 1781aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM); 1782aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1783aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mIndicatorNetworkState == 17848d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientHalConstants.NETWORK_STATE_AVAILABLE) { 1785aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (queryCurrentOperatorNameNative()) { 1786aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta addQueuedAction(QUERY_OPERATOR_NAME); 1787aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 1788aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "ERROR: Couldn't querry operator name"); 1789aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1790aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1791aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1792aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_ROAMING_STATE: 1793aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "Connected: Roaming state: " + event.valueInt); 1794aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1795aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mIndicatorNetworkType = event.valueInt; 1796aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 17978d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT); 17988d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent.putExtra(BluetoothHeadsetClient.EXTRA_NETWORK_ROAMING, 1799aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueInt); 1800aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device); 1801aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM); 1802aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1803aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_NETWORK_SIGNAL: 1804aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "Connected: Signal level: " + event.valueInt); 1805aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1806aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mIndicatorNetworkSignal = event.valueInt; 1807aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 18088d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT); 18098d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent.putExtra(BluetoothHeadsetClient.EXTRA_NETWORK_SIGNAL_STRENGTH, 1810aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueInt); 1811aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device); 1812aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM); 1813aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1814aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_BATTERY_LEVEL: 1815aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "Connected: Battery level: " + event.valueInt); 1816aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1817aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mIndicatorBatteryLevel = event.valueInt; 1818aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 18198d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT); 18208d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent.putExtra(BluetoothHeadsetClient.EXTRA_BATTERY_LEVEL, 1821aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueInt); 1822aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device); 1823aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM); 1824aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1825aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_OPERATOR_NAME: 1826aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "Connected: Operator name: " + event.valueString); 1827aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1828aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mOperatorName = event.valueString; 1829aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 18308d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT); 18318d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent.putExtra(BluetoothHeadsetClient.EXTRA_OPERATOR_NAME, 1832aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueString); 1833aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device); 1834aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM); 1835aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1836aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_VR_STATE_CHANGED: 1837aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "Connected: Voice recognition state: " + event.valueInt); 1838aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1839aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mVoiceRecognitionActive != event.valueInt) { 1840aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mVoiceRecognitionActive = event.valueInt; 1841aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 18428d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT); 18438d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent.putExtra(BluetoothHeadsetClient.EXTRA_VOICE_RECOGNITION, 1844aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mVoiceRecognitionActive); 1845aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device); 1846aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM); 1847aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1848aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1849aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_CALL: 1850aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta updateCallIndicator(event.valueInt); 1851aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1852aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_CALLSETUP: 1853aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta updateCallSetupIndicator(event.valueInt); 1854aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1855aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_CALLHELD: 1856aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta updateCallHeldIndicator(event.valueInt); 1857aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1858aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_RESP_AND_HOLD: 1859aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta updateRespAndHold(event.valueInt); 1860aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1861aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_CLIP: 1862aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta updateClip(event.valueString); 1863aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1864aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_CALL_WAITING: 1865aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta addCallWaiting(event.valueString); 1866aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1867aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_IN_BAND_RING: 1868aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mInBandRingtone != event.valueInt) { 1869aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mInBandRingtone = event.valueInt; 18708d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT); 18718d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent.putExtra(BluetoothHeadsetClient.EXTRA_IN_BAND_RING, 1872aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mInBandRingtone); 1873aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device); 1874aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM); 1875aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1876aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1877aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_CURRENT_CALLS: 1878aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta queryCallsUpdate( 1879aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueInt, 1880aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueInt3, 1881aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueString, 1882aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueInt4 == 18838d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientHalConstants.CALL_MPTY_TYPE_MULTI, 1884aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueInt2 == 18858d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientHalConstants.CALL_DIRECTION_OUTGOING); 1886aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1887aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_VOLUME_CHANGED: 18888d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (event.valueInt == HeadsetClientHalConstants.VOLUME_TYPE_SPK) { 1889d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal Log.d(TAG, "AM volume set to " + 1890d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal hfToAmVol(event.valueInt2)); 18913076d2acccf5c3db0db19b622f062e259be39f3aSanket Agarwal mAudioManager.setStreamVolume( 18923076d2acccf5c3db0db19b622f062e259be39f3aSanket Agarwal AudioManager.STREAM_VOICE_CALL, 1893d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal hfToAmVol(event.valueInt2), 18943076d2acccf5c3db0db19b622f062e259be39f3aSanket Agarwal AudioManager.FLAG_SHOW_UI); 1895aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mVgsFromStack = true; 18963076d2acccf5c3db0db19b622f062e259be39f3aSanket Agarwal } else if (event.valueInt == 18973076d2acccf5c3db0db19b622f062e259be39f3aSanket Agarwal HeadsetClientHalConstants.VOLUME_TYPE_MIC) { 1898aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mAudioManager.setMicrophoneMute(event.valueInt2 == 0); 18993076d2acccf5c3db0db19b622f062e259be39f3aSanket Agarwal 1900aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mVgmFromStack = true; 1901aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1902aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1903aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_CMD_RESULT: 1904aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Pair<Integer, Object> queuedAction = mQueuedActions.poll(); 1905aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1906aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // should not happen but... 1907aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (queuedAction == null || queuedAction.first == NO_ACTION) { 1908aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta clearPendingAction(); 1909aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1910aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1911aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1912aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "Connected: command result: " + event.valueInt 1913aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta + " queuedAction: " + queuedAction.first); 1914aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 1915aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch (queuedAction.first) { 1916aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case VOICE_RECOGNITION_STOP: 1917aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case VOICE_RECOGNITION_START: 19188d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (event.valueInt == HeadsetClientHalConstants.CMD_COMPLETE_OK) { 1919aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (queuedAction.first == VOICE_RECOGNITION_STOP) { 1920aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mVoiceRecognitionActive = 19218d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientHalConstants.VR_STATE_STOPPED; 1922aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 1923aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mVoiceRecognitionActive = 19248d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientHalConstants.VR_STATE_STARTED; 1925aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1926aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 19278d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT); 1928aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta intent.putExtra( 19298d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClient.EXTRA_VOICE_RECOGNITION, 1930aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mVoiceRecognitionActive); 1931aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device); 1932aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM); 1933aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1934aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case QUERY_CURRENT_CALLS: 1935aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta queryCallsDone(); 1936aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1937aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case ACCEPT_CALL: 19388d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (event.valueInt == BluetoothHeadsetClient.ACTION_RESULT_OK) { 1939aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mPendingAction = queuedAction; 1940aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 19418d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (callsInState(BluetoothHeadsetClientCall.CALL_STATE_ACTIVE) == 0) { 19428d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if(getCall(BluetoothHeadsetClientCall.CALL_STATE_INCOMING) != null && 19438d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood (Integer) mPendingAction.second == HeadsetClientHalConstants.CALL_ACTION_ATA) { 19448d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood acceptCall(BluetoothHeadsetClient.CALL_ACCEPT_NONE, true); 1945aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 19468d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood } else if(getCall(BluetoothHeadsetClientCall.CALL_STATE_WAITING) != null && 19478d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood (Integer) mPendingAction.second == HeadsetClientHalConstants.CALL_ACTION_CHLD_2) { 19488d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood acceptCall(BluetoothHeadsetClient.CALL_ACCEPT_NONE, true); 1949aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1950aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1951aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1952aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendActionResultIntent(event); 1953aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1954aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1955aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case REJECT_CALL: 1956aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case HOLD_CALL: 1957aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case TERMINATE_CALL: 1958aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case ENTER_PRIVATE_MODE: 1959aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case DIAL_NUMBER: 1960aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case DIAL_MEMORY: 1961aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case REDIAL: 19628d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (event.valueInt == BluetoothHeadsetClient.ACTION_RESULT_OK) { 1963aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mPendingAction = queuedAction; 1964aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 1965aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendActionResultIntent(event); 1966aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1967aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1968aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case TERMINATE_SPECIFIC_CALL: 1969aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // if terminating specific succeed no other 1970aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // event is send 19718d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (event.valueInt == BluetoothHeadsetClient.ACTION_RESULT_OK) { 19728d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall c = 19738d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood (BluetoothHeadsetClientCall) queuedAction.second; 1974aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta setCallState(c, 19758d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClientCall.CALL_STATE_TERMINATED); 1976aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mCalls.remove(c.getId()); 1977aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 1978aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendActionResultIntent(event); 1979aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1980aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1981aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case LAST_VTAG_NUMBER: 19828d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (event.valueInt != BluetoothHeadsetClient.ACTION_RESULT_OK) { 1983aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendActionResultIntent(event); 1984aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 1985d1fadc3b23a03cbf028bfbdca9fd64640d7a05bdDavid Stevens break; 1986d1fadc3b23a03cbf028bfbdca9fd64640d7a05bdDavid Stevens case DISABLE_NREC: 1987d1fadc3b23a03cbf028bfbdca9fd64640d7a05bdDavid Stevens if (event.valueInt != HeadsetClientHalConstants.CMD_COMPLETE_OK) { 1988d1fadc3b23a03cbf028bfbdca9fd64640d7a05bdDavid Stevens Log.w(TAG, "Failed to disable AG's EC and NR"); 1989d1fadc3b23a03cbf028bfbdca9fd64640d7a05bdDavid Stevens } 1990aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1991aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case SET_MIC_VOLUME: 1992aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case SET_SPEAKER_VOLUME: 1993aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case SUBSCRIBER_INFO: 1994aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case QUERY_OPERATOR_NAME: 1995aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1996aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 1997aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendActionResultIntent(event); 1998aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 1999aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2000aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2001aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 2002aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_SUBSCRIBER_INFO: 2003aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta /* TODO should we handle type as well? */ 2004aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mSubscriberInfo = event.valueString; 20058d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent = new Intent(BluetoothHeadsetClient.ACTION_AG_EVENT); 20068d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent.putExtra(BluetoothHeadsetClient.EXTRA_SUBSCRIBER_INFO, 2007aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mSubscriberInfo); 2008aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device); 2009aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM); 2010aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 2011aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_LAST_VOICE_TAG_NUMBER: 20128d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent = new Intent(BluetoothHeadsetClient.ACTION_LAST_VTAG); 20138d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent.putExtra(BluetoothHeadsetClient.EXTRA_NUMBER, 2014aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueString); 2015aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device); 2016aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM); 2017aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 2018aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_RING_INDICATION: 20193076d2acccf5c3db0db19b622f062e259be39f3aSanket Agarwal // Ringing is not handled at this indication and rather should be 20203076d2acccf5c3db0db19b622f062e259be39f3aSanket Agarwal // implemented (by the client of this service). Use the 20213076d2acccf5c3db0db19b622f062e259be39f3aSanket Agarwal // CALL_STATE_INCOMING (and similar) handle ringing. 2022aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 2023aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 2024aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "Unknown stack event: " + event.type); 2025aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 2026aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2027aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2028aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 2029aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 2030aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return NOT_HANDLED; 2031aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2032aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return HANDLED; 2033aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2034aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2035aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void sendActionResultIntent(StackEvent event) { 20368d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood Intent intent = new Intent(BluetoothHeadsetClient.ACTION_RESULT); 20378d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent.putExtra(BluetoothHeadsetClient.EXTRA_RESULT_CODE, event.valueInt); 20388d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (event.valueInt == BluetoothHeadsetClient.ACTION_RESULT_ERROR_CME) { 20398d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent.putExtra(BluetoothHeadsetClient.EXTRA_CME_CODE, event.valueInt2); 2040aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2041aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta intent.putExtra(BluetoothDevice.EXTRA_DEVICE, event.device); 2042aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM); 2043aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2044aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2045aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // in Connected state 2046aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void processConnectionEvent(int state, BluetoothDevice device) { 2047aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch (state) { 20488d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CONNECTION_STATE_DISCONNECTED: 2049aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "Connected disconnects."); 2050aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // AG disconnects 2051aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mCurrentDevice.equals(device)) { 2052aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta broadcastConnectionState(mCurrentDevice, 2053aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta BluetoothProfile.STATE_DISCONNECTED, 2054aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta BluetoothProfile.STATE_CONNECTED); 2055aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mCurrentDevice = null; 2056aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta transitionTo(mDisconnected); 2057aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 2058aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "Disconnected from unknown device: " + device); 2059aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2060aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 2061aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 2062aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "Connection State Device: " + device + " bad state: " + state); 2063aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 2064aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2065aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2066aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2067aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // in Connected state 2068aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void processAudioEvent(int state, BluetoothDevice device) { 2069aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // message from old device 2070aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (!mCurrentDevice.equals(device)) { 2071aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "Audio changed on disconnected device: " + device); 2072aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return; 2073aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2074aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2075aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch (state) { 20768d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.AUDIO_STATE_CONNECTED_MSBC: 2077aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mAudioWbs = true; 2078aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // fall through 20798d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.AUDIO_STATE_CONNECTED: 208022bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee if (!mAudioRouteAllowed) { 208122bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee sendMessage(HeadsetClientStateMachine.DISCONNECT_AUDIO); 208222bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee break; 208322bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee } 208422bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee 20853076d2acccf5c3db0db19b622f062e259be39f3aSanket Agarwal // Audio state is split in two parts, the audio focus is maintained by the 20863076d2acccf5c3db0db19b622f062e259be39f3aSanket Agarwal // entity exercising this service (typically the Telecom stack) and audio 20873076d2acccf5c3db0db19b622f062e259be39f3aSanket Agarwal // routing is handled by the bluetooth stack itself. The only reason to do so is 20883076d2acccf5c3db0db19b622f062e259be39f3aSanket Agarwal // because Bluetooth SCO connection from the HF role is not entirely supported 20893076d2acccf5c3db0db19b622f062e259be39f3aSanket Agarwal // for routing and volume purposes. 20903076d2acccf5c3db0db19b622f062e259be39f3aSanket Agarwal // NOTE: All calls here are routed via the setParameters which changes the 20913076d2acccf5c3db0db19b622f062e259be39f3aSanket Agarwal // routing at the Audio HAL level. 20928d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood mAudioState = BluetoothHeadsetClient.STATE_AUDIO_CONNECTED; 209337604004520846495a5dba50d7c3afef05a9ecf9Sharvil Nanavati 209437604004520846495a5dba50d7c3afef05a9ecf9Sharvil Nanavati // We need to set the volume after switching into HFP mode as some Audio HALs 209537604004520846495a5dba50d7c3afef05a9ecf9Sharvil Nanavati // reset the volume to a known-default on mode switch. 2096d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal final int amVol = 20973076d2acccf5c3db0db19b622f062e259be39f3aSanket Agarwal mAudioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL); 2098d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal final int hfVol = amToHfVol(amVol); 2099d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal 2100aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG,"hfp_enable=true"); 2101aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG,"mAudioWbs is " + mAudioWbs); 2102aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mAudioWbs) { 2103aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG,"Setting sampling rate as 16000"); 2104aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mAudioManager.setParameters("hfp_set_sampling_rate=16000"); 2105aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2106aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta else { 2107aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG,"Setting sampling rate as 8000"); 2108aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mAudioManager.setParameters("hfp_set_sampling_rate=8000"); 2109aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2110d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal Log.d(TAG, "hf_volume " + hfVol); 2111aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mAudioManager.setParameters("hfp_enable=true"); 2112d38ba29ff12eea818f2fd502ee9d5a4f1bfb278eSanket Agarwal mAudioManager.setParameters("hfp_volume=" + hfVol); 2113aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta transitionTo(mAudioOn); 2114aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 21158d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.AUDIO_STATE_CONNECTING: 21168d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood mAudioState = BluetoothHeadsetClient.STATE_AUDIO_CONNECTING; 21178d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood broadcastAudioState(device, BluetoothHeadsetClient.STATE_AUDIO_CONNECTING, 21188d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED); 2119aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 21208d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.AUDIO_STATE_DISCONNECTED: 21218d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (mAudioState == BluetoothHeadsetClient.STATE_AUDIO_CONNECTING) { 21228d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood mAudioState = BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED; 2123aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta broadcastAudioState(device, 21248d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED, 21258d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClient.STATE_AUDIO_CONNECTING); 2126aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2127aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 2128aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 2129aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "Audio State Device: " + device + " bad state: " + state); 2130aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 2131aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2132aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2133aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2134aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 2135aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public void exit() { 2136aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "Exit Connected: " + getCurrentMessage().what); 2137aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2138aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2139aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2140aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private class AudioOn extends State { 2141aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 2142aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public void enter() { 2143aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "Enter AudioOn: " + getCurrentMessage().what); 2144a27628d5cb96981b65daec4db798d06ba9d98ce2Sharvil Nanavati broadcastAudioState(mCurrentDevice, BluetoothHeadsetClient.STATE_AUDIO_CONNECTED, 2145a27628d5cb96981b65daec4db798d06ba9d98ce2Sharvil Nanavati BluetoothHeadsetClient.STATE_AUDIO_CONNECTING); 2146aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2147aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2148aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 2149aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public synchronized boolean processMessage(Message message) { 2150aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "AudioOn process message: " + message.what); 2151aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (DBG) { 2152aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mCurrentDevice == null) { 2153aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "ERROR: mCurrentDevice is null in Connected"); 2154aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return NOT_HANDLED; 2155aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2156aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2157aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2158aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch (message.what) { 2159aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case DISCONNECT: 2160aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta BluetoothDevice device = (BluetoothDevice) message.obj; 2161aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (!mCurrentDevice.equals(device)) { 2162aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 2163aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2164aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta deferMessage(message); 2165aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta /* 2166aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * fall through - disconnect audio first then expect 2167aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * deferred DISCONNECT message in Connected state 2168aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta */ 2169aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case DISCONNECT_AUDIO: 2170aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta /* 2171aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * just disconnect audio and wait for 2172aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * EVENT_TYPE_AUDIO_STATE_CHANGED, that triggers State 2173aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * Machines state changing 2174aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta */ 2175aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (disconnectAudioNative(getByteAddress(mCurrentDevice))) { 21768d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood mAudioState = BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED; 2177aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG,"hfp_enable=false"); 2178aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mAudioManager.setParameters("hfp_enable=false"); 2179aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta broadcastAudioState(mCurrentDevice, 21808d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED, 21818d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClient.STATE_AUDIO_CONNECTED); 2182aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2183aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 2184aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case STACK_EVENT: 2185aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta StackEvent event = (StackEvent) message.obj; 2186aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (DBG) { 2187aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "AudioOn: event type: " + event.type); 2188aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2189aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch (event.type) { 2190aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_CONNECTION_STATE_CHANGED: 2191aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "AudioOn connection state changed" + event.device + ": " 2192aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta + event.valueInt); 2193aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta processConnectionEvent(event.valueInt, event.device); 2194aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 2195aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta case EVENT_TYPE_AUDIO_STATE_CHANGED: 2196aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "AudioOn audio state changed" + event.device + ": " 2197aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta + event.valueInt); 2198aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta processAudioEvent(event.valueInt, event.device); 2199aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 2200aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 2201aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return NOT_HANDLED; 2202aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2203aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 2204aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 2205aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return NOT_HANDLED; 2206aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2207aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return HANDLED; 2208aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2209aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2210aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // in AudioOn state. Can AG disconnect RFCOMM prior to SCO? Handle this 2211aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void processConnectionEvent(int state, BluetoothDevice device) { 2212aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch (state) { 22138d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.CONNECTION_STATE_DISCONNECTED: 2214aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mCurrentDevice.equals(device)) { 22158d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood processAudioEvent(HeadsetClientHalConstants.AUDIO_STATE_DISCONNECTED, 2216aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta device); 2217aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta broadcastConnectionState(mCurrentDevice, 2218aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta BluetoothProfile.STATE_DISCONNECTED, 2219aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta BluetoothProfile.STATE_CONNECTED); 2220aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mCurrentDevice = null; 2221aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta transitionTo(mDisconnected); 2222aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } else { 2223aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "Disconnected from unknown device: " + device); 2224aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2225aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 2226aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 2227aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "Connection State Device: " + device + " bad state: " + state); 2228aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 2229aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2230aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2231aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2232aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // in AudioOn state 2233aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void processAudioEvent(int state, BluetoothDevice device) { 2234aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (!mCurrentDevice.equals(device)) { 2235aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "Audio changed on disconnected device: " + device); 2236aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return; 2237aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2238aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2239aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta switch (state) { 22408d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood case HeadsetClientHalConstants.AUDIO_STATE_DISCONNECTED: 22418d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (mAudioState != BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED) { 22428d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood mAudioState = BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED; 22433076d2acccf5c3db0db19b622f062e259be39f3aSanket Agarwal // Audio focus may still be held by the entity controlling the actual call 22443076d2acccf5c3db0db19b622f062e259be39f3aSanket Agarwal // (such as Telecom) and hence this will still keep the call around, there 22453076d2acccf5c3db0db19b622f062e259be39f3aSanket Agarwal // is not much we can do here since dropping the call without user consent 22463076d2acccf5c3db0db19b622f062e259be39f3aSanket Agarwal // even if the audio connection snapped may not be a good idea. 2247aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG,"hfp_enable=false"); 2248aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mAudioManager.setParameters("hfp_enable=false"); 2249aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta broadcastAudioState(device, 22508d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED, 22518d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood BluetoothHeadsetClient.STATE_AUDIO_CONNECTED); 2252aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2253aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2254aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta transitionTo(mConnected); 2255aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 2256aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta default: 2257aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "Audio State Device: " + device + " bad state: " + state); 2258aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta break; 2259aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2260aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2261aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2262aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 2263aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public void exit() { 2264aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "Exit AudioOn: " + getCurrentMessage().what); 2265aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2266aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2267aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2268aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta /** 2269aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * @hide 2270aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta */ 2271aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public synchronized int getConnectionState(BluetoothDevice device) { 2272aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mCurrentDevice == null) { 2273aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return BluetoothProfile.STATE_DISCONNECTED; 2274aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2275aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2276aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (!mCurrentDevice.equals(device)) { 2277aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return BluetoothProfile.STATE_DISCONNECTED; 2278aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2279aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2280aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta IState currentState = getCurrentState(); 2281aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (currentState == mConnecting) { 2282aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return BluetoothProfile.STATE_CONNECTING; 2283aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2284aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2285aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (currentState == mConnected || currentState == mAudioOn) { 2286aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return BluetoothProfile.STATE_CONNECTED; 2287aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2288aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2289aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.e(TAG, "Bad currentState: " + currentState); 2290aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return BluetoothProfile.STATE_DISCONNECTED; 2291aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2292aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2293aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void broadcastAudioState(BluetoothDevice device, int newState, int prevState) { 22948d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood Intent intent = new Intent(BluetoothHeadsetClient.ACTION_AUDIO_STATE_CHANGED); 2295aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState); 2296aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta intent.putExtra(BluetoothProfile.EXTRA_STATE, newState); 2297aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 22988d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if (newState == BluetoothHeadsetClient.STATE_AUDIO_CONNECTED) { 22998d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent.putExtra(BluetoothHeadsetClient.EXTRA_AUDIO_WBS, mAudioWbs); 2300aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2301aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2302aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); 2303aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM); 2304aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "Audio state " + device + ": " + prevState + "->" + newState); 2305aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2306aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2307aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // This method does not check for error condition (newState == prevState) 2308aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void broadcastConnectionState(BluetoothDevice device, int newState, int prevState) { 2309aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "Connection state " + device + ": " + prevState + "->" + newState); 2310aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta /* 2311aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * Notifying the connection state change of the profile before sending 2312aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * the intent for connection state change, as it was causing a race 2313aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * condition, with the UI not being updated with the correct connection 2314aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * state. 2315aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta */ 23168d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood mService.notifyProfileConnectionStateChanged(device, BluetoothProfile.HEADSET_CLIENT, 2317aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta newState, prevState); 23188d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood Intent intent = new Intent(BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED); 2319aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState); 2320aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta intent.putExtra(BluetoothProfile.EXTRA_STATE, newState); 2321aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); 2322aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2323aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // add feature extras when connected 2324aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (newState == BluetoothProfile.STATE_CONNECTED) { 23258d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if ((mPeerFeatures & HeadsetClientHalConstants.PEER_FEAT_3WAY) == 23268d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientHalConstants.PEER_FEAT_3WAY) { 23278d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent.putExtra(BluetoothHeadsetClient.EXTRA_AG_FEATURE_3WAY_CALLING, true); 2328aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 23298d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if ((mPeerFeatures & HeadsetClientHalConstants.PEER_FEAT_VREC) == 23308d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientHalConstants.PEER_FEAT_VREC) { 23318d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent.putExtra(BluetoothHeadsetClient.EXTRA_AG_FEATURE_VOICE_RECOGNITION, true); 2332aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 23338d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if ((mPeerFeatures & HeadsetClientHalConstants.PEER_FEAT_VTAG) == 23348d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientHalConstants.PEER_FEAT_VTAG) { 23358d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent.putExtra(BluetoothHeadsetClient.EXTRA_AG_FEATURE_ATTACH_NUMBER_TO_VT, true); 2336aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 23378d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if ((mPeerFeatures & HeadsetClientHalConstants.PEER_FEAT_REJECT) == 23388d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientHalConstants.PEER_FEAT_REJECT) { 23398d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent.putExtra(BluetoothHeadsetClient.EXTRA_AG_FEATURE_REJECT_CALL, true); 2340aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 23418d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if ((mPeerFeatures & HeadsetClientHalConstants.PEER_FEAT_ECC) == 23428d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientHalConstants.PEER_FEAT_ECC) { 23438d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent.putExtra(BluetoothHeadsetClient.EXTRA_AG_FEATURE_ECC, true); 2344aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2345aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2346aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // add individual CHLD support extras 23478d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if ((mChldFeatures & HeadsetClientHalConstants.CHLD_FEAT_HOLD_ACC) == 23488d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientHalConstants.CHLD_FEAT_HOLD_ACC) { 23498d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent.putExtra(BluetoothHeadsetClient.EXTRA_AG_FEATURE_ACCEPT_HELD_OR_WAITING_CALL, true); 2350aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 23518d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if ((mChldFeatures & HeadsetClientHalConstants.CHLD_FEAT_REL) == 23528d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientHalConstants.CHLD_FEAT_REL) { 23538d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent.putExtra(BluetoothHeadsetClient.EXTRA_AG_FEATURE_RELEASE_HELD_OR_WAITING_CALL, true); 2354aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 23558d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if ((mChldFeatures & HeadsetClientHalConstants.CHLD_FEAT_REL_ACC) == 23568d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientHalConstants.CHLD_FEAT_REL_ACC) { 23578d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent.putExtra(BluetoothHeadsetClient.EXTRA_AG_FEATURE_RELEASE_AND_ACCEPT, true); 2358aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 23598d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if ((mChldFeatures & HeadsetClientHalConstants.CHLD_FEAT_MERGE) == 23608d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientHalConstants.CHLD_FEAT_MERGE) { 23618d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent.putExtra(BluetoothHeadsetClient.EXTRA_AG_FEATURE_MERGE, true); 2362aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 23638d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood if ((mChldFeatures & HeadsetClientHalConstants.CHLD_FEAT_MERGE_DETACH) == 23648d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood HeadsetClientHalConstants.CHLD_FEAT_MERGE_DETACH) { 23658d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood intent.putExtra(BluetoothHeadsetClient.EXTRA_AG_FEATURE_MERGE_AND_DETACH, true); 2366aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2367aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2368aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM); 2369aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2370aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2371aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta boolean isConnected() { 2372aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta IState currentState = getCurrentState(); 2373aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return (currentState == mConnected || currentState == mAudioOn); 2374aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2375aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2376aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { 2377aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta List<BluetoothDevice> deviceList = new ArrayList<BluetoothDevice>(); 2378aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Set<BluetoothDevice> bondedDevices = mAdapter.getBondedDevices(); 2379aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int connectionState; 2380aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta synchronized (this) { 2381aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta for (BluetoothDevice device : bondedDevices) { 2382aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta ParcelUuid[] featureUuids = device.getUuids(); 2383aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (!BluetoothUuid.isUuidPresent(featureUuids, BluetoothUuid.Handsfree_AG)) { 2384aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta continue; 2385aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2386aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta connectionState = getConnectionState(device); 2387aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta for (int state : states) { 2388aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (connectionState == state) { 2389aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta deviceList.add(device); 2390aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2391aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2392aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2393aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2394aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return deviceList; 2395aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2396aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2397aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta boolean okToConnect(BluetoothDevice device) { 2398aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int priority = mService.getPriority(device); 2399aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta boolean ret = false; 2400aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // check priority and accept or reject the connection. if priority is 2401aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // undefined 2402aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // it is likely that our SDP has not completed and peer is initiating 2403aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // the 2404aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // connection. Allow this connection, provided the device is bonded 2405aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if ((BluetoothProfile.PRIORITY_OFF < priority) || 2406aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta ((BluetoothProfile.PRIORITY_UNDEFINED == priority) && 2407aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta (device.getBondState() != BluetoothDevice.BOND_NONE))) { 2408aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta ret = true; 2409aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2410aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return ret; 2411aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2412aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2413aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta boolean isAudioOn() { 2414aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return (getCurrentState() == mAudioOn); 2415aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2416aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 241722bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee public void setAudioRouteAllowed(boolean allowed) { 241822bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee mAudioRouteAllowed = allowed; 241922bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee } 242022bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee 242122bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee public boolean getAudioRouteAllowed() { 242222bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee return mAudioRouteAllowed; 242322bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee } 242422bb39444356637fbcabd4acf04f2fdb9e3da177Bryce Lee 2425aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta synchronized int getAudioState(BluetoothDevice device) { 2426aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mCurrentDevice == null || !mCurrentDevice.equals(device)) { 24278d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood return BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED; 2428aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2429aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return mAudioState; 2430aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2431aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2432aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta /** 2433aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta * @hide 2434aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta */ 2435aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta List<BluetoothDevice> getConnectedDevices() { 2436aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta List<BluetoothDevice> devices = new ArrayList<BluetoothDevice>(); 2437aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta synchronized (this) { 2438aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (isConnected()) { 2439aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta devices.add(mCurrentDevice); 2440aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2441aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2442aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return devices; 2443aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2444aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2445aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private BluetoothDevice getDevice(byte[] address) { 2446aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return mAdapter.getRemoteDevice(Utils.getAddressStringFromByte(address)); 2447aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2448aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2449aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void onConnectionStateChanged(int state, int peer_feat, int chld_feat, byte[] address) { 2450aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta StackEvent event = new StackEvent(EVENT_TYPE_CONNECTION_STATE_CHANGED); 2451aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueInt = state; 2452aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueInt2 = peer_feat; 2453aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueInt3 = chld_feat; 2454aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.device = getDevice(address); 2455aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "incoming" + event); 2456aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendMessage(STACK_EVENT, event); 2457aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2458aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2459aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void onAudioStateChanged(int state, byte[] address) { 2460aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta StackEvent event = new StackEvent(EVENT_TYPE_AUDIO_STATE_CHANGED); 2461aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueInt = state; 2462aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.device = getDevice(address); 2463aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "incoming" + event); 2464aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendMessage(STACK_EVENT, event); 2465aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2466aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2467aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void onVrStateChanged(int state) { 2468aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta StackEvent event = new StackEvent(EVENT_TYPE_VR_STATE_CHANGED); 2469aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueInt = state; 2470aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "incoming" + event); 2471aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendMessage(STACK_EVENT, event); 2472aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2473aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2474aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void onNetworkState(int state) { 2475aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta StackEvent event = new StackEvent(EVENT_TYPE_NETWORK_STATE); 2476aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueInt = state; 2477aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "incoming" + event); 2478aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendMessage(STACK_EVENT, event); 2479aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2480aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2481aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void onNetworkRoaming(int state) { 2482aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta StackEvent event = new StackEvent(EVENT_TYPE_ROAMING_STATE); 2483aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueInt = state; 2484aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "incoming" + event); 2485aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendMessage(STACK_EVENT, event); 2486aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2487aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2488aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void onNetworkSignal(int signal) { 2489aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta StackEvent event = new StackEvent(EVENT_TYPE_NETWORK_SIGNAL); 2490aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueInt = signal; 2491aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "incoming" + event); 2492aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendMessage(STACK_EVENT, event); 2493aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2494aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2495aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void onBatteryLevel(int level) { 2496aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta StackEvent event = new StackEvent(EVENT_TYPE_BATTERY_LEVEL); 2497aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueInt = level; 2498aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "incoming" + event); 2499aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendMessage(STACK_EVENT, event); 2500aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2501aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2502aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void onCurrentOperator(String name) { 2503aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta StackEvent event = new StackEvent(EVENT_TYPE_OPERATOR_NAME); 2504aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueString = name; 2505aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "incoming" + event); 2506aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendMessage(STACK_EVENT, event); 2507aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2508aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2509aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void onCall(int call) { 2510aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta StackEvent event = new StackEvent(EVENT_TYPE_CALL); 2511aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueInt = call; 2512aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "incoming" + event); 2513aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendMessage(STACK_EVENT, event); 2514aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2515aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2516aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void onCallSetup(int callsetup) { 2517aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta StackEvent event = new StackEvent(EVENT_TYPE_CALLSETUP); 2518aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueInt = callsetup; 2519aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "incoming" + event); 2520aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendMessage(STACK_EVENT, event); 2521aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2522aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2523aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void onCallHeld(int callheld) { 2524aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta StackEvent event = new StackEvent(EVENT_TYPE_CALLHELD); 2525aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueInt = callheld; 2526aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "incoming" + event); 2527aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendMessage(STACK_EVENT, event); 2528aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2529aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2530aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void onRespAndHold(int resp_and_hold) { 2531aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta StackEvent event = new StackEvent(EVENT_TYPE_RESP_AND_HOLD); 2532aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueInt = resp_and_hold; 2533aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "incoming" + event); 2534aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendMessage(STACK_EVENT, event); 2535aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2536aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2537aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void onClip(String number) { 2538aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta StackEvent event = new StackEvent(EVENT_TYPE_CLIP); 2539aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueString = number; 2540aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "incoming" + event); 2541aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendMessage(STACK_EVENT, event); 2542aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2543aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2544aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void onCallWaiting(String number) { 2545aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta StackEvent event = new StackEvent(EVENT_TYPE_CALL_WAITING); 2546aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueString = number; 2547aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "incoming" + event); 2548aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendMessage(STACK_EVENT, event); 2549aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2550aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2551aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void onCurrentCalls(int index, int dir, int state, int mparty, String number) { 2552aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta StackEvent event = new StackEvent(EVENT_TYPE_CURRENT_CALLS); 2553aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueInt = index; 2554aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueInt2 = dir; 2555aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueInt3 = state; 2556aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueInt4 = mparty; 2557aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueString = number; 2558aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "incoming " + event); 2559aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendMessage(STACK_EVENT, event); 2560aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2561aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2562aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void onVolumeChange(int type, int volume) { 2563aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta StackEvent event = new StackEvent(EVENT_TYPE_VOLUME_CHANGED); 2564aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueInt = type; 2565aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueInt2 = volume; 2566aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "incoming" + event); 2567aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendMessage(STACK_EVENT, event); 2568aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2569aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2570aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void onCmdResult(int type, int cme) { 2571aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta StackEvent event = new StackEvent(EVENT_TYPE_CMD_RESULT); 2572aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueInt = type; 2573aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueInt2 = cme; 2574aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "incoming" + event); 2575aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendMessage(STACK_EVENT, event); 2576aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2577aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2578aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void onSubscriberInfo(String number, int type) { 2579aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta StackEvent event = new StackEvent(EVENT_TYPE_SUBSCRIBER_INFO); 2580aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueInt = type; 2581aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueString = number; 2582aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "incoming" + event); 2583aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendMessage(STACK_EVENT, event); 2584aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2585aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2586aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void onInBandRing(int in_band) { 2587aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta StackEvent event = new StackEvent(EVENT_TYPE_IN_BAND_RING); 2588aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueInt = in_band; 2589aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "incoming" + event); 2590aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendMessage(STACK_EVENT, event); 2591aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2592aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2593aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void onLastVoiceTagNumber(String number) { 2594aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta StackEvent event = new StackEvent(EVENT_TYPE_LAST_VOICE_TAG_NUMBER); 2595aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta event.valueString = number; 2596aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "incoming" + event); 2597aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendMessage(STACK_EVENT, event); 2598aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2599aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private void onRingIndication() { 2600aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta StackEvent event = new StackEvent(EVENT_TYPE_RING_INDICATION); 2601aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Log.d(TAG, "incoming" + event); 2602aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta sendMessage(STACK_EVENT, event); 2603aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2604aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2605aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private String getCurrentDeviceName() { 2606aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta String defaultName = "<unknown>"; 2607aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (mCurrentDevice == null) { 2608aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return defaultName; 2609aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2610aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta String deviceName = mCurrentDevice.getName(); 2611aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta if (deviceName == null) { 2612aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return defaultName; 2613aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2614aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return deviceName; 2615aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2616aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2617aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private byte[] getByteAddress(BluetoothDevice device) { 2618aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return Utils.getBytesFromAddress(device.getAddress()); 2619aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2620aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2621aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // Event types for STACK_EVENT message 2622aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta final private static int EVENT_TYPE_NONE = 0; 2623aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta final private static int EVENT_TYPE_CONNECTION_STATE_CHANGED = 1; 2624aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta final private static int EVENT_TYPE_AUDIO_STATE_CHANGED = 2; 2625aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta final private static int EVENT_TYPE_VR_STATE_CHANGED = 3; 2626aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta final private static int EVENT_TYPE_NETWORK_STATE = 4; 2627aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta final private static int EVENT_TYPE_ROAMING_STATE = 5; 2628aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta final private static int EVENT_TYPE_NETWORK_SIGNAL = 6; 2629aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta final private static int EVENT_TYPE_BATTERY_LEVEL = 7; 2630aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta final private static int EVENT_TYPE_OPERATOR_NAME = 8; 2631aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta final private static int EVENT_TYPE_CALL = 9; 2632aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta final private static int EVENT_TYPE_CALLSETUP = 10; 2633aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta final private static int EVENT_TYPE_CALLHELD = 11; 2634aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta final private static int EVENT_TYPE_CLIP = 12; 2635aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta final private static int EVENT_TYPE_CALL_WAITING = 13; 2636aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta final private static int EVENT_TYPE_CURRENT_CALLS = 14; 2637aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta final private static int EVENT_TYPE_VOLUME_CHANGED = 15; 2638aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta final private static int EVENT_TYPE_CMD_RESULT = 16; 2639aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta final private static int EVENT_TYPE_SUBSCRIBER_INFO = 17; 2640aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta final private static int EVENT_TYPE_RESP_AND_HOLD = 18; 2641aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta final private static int EVENT_TYPE_IN_BAND_RING = 19; 2642aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta final private static int EVENT_TYPE_LAST_VOICE_TAG_NUMBER = 20; 2643aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta final private static int EVENT_TYPE_RING_INDICATION= 21; 2644aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2645aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // for debugging only 2646aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private final String EVENT_TYPE_NAMES[] = 2647aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta { 2648aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta "EVENT_TYPE_NONE", 2649aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta "EVENT_TYPE_CONNECTION_STATE_CHANGED", 2650aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta "EVENT_TYPE_AUDIO_STATE_CHANGED", 2651aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta "EVENT_TYPE_VR_STATE_CHANGED", 2652aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta "EVENT_TYPE_NETWORK_STATE", 2653aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta "EVENT_TYPE_ROAMING_STATE", 2654aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta "EVENT_TYPE_NETWORK_SIGNAL", 2655aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta "EVENT_TYPE_BATTERY_LEVEL", 2656aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta "EVENT_TYPE_OPERATOR_NAME", 2657aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta "EVENT_TYPE_CALL", 2658aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta "EVENT_TYPE_CALLSETUP", 2659aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta "EVENT_TYPE_CALLHELD", 2660aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta "EVENT_TYPE_CLIP", 2661aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta "EVENT_TYPE_CALL_WAITING", 2662aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta "EVENT_TYPE_CURRENT_CALLS", 2663aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta "EVENT_TYPE_VOLUME_CHANGED", 2664aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta "EVENT_TYPE_CMD_RESULT", 2665aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta "EVENT_TYPE_SUBSCRIBER_INFO", 2666aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta "EVENT_TYPE_RESP_AND_HOLD", 2667aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta "EVENT_TYPE_IN_BAND_RING", 2668aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta "EVENT_TYPE_LAST_VOICE_TAG_NUMBER", 2669aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta "EVENT_TYPE_RING_INDICATION", 2670aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta }; 2671aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2672aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private class StackEvent { 2673aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int type = EVENT_TYPE_NONE; 2674aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int valueInt = 0; 2675aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int valueInt2 = 0; 2676aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int valueInt3 = 0; 2677aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int valueInt4 = 0; 2678aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta String valueString = null; 2679aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta BluetoothDevice device = null; 2680aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2681aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private StackEvent(int type) { 2682aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta this.type = type; 2683aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2684aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2685aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta @Override 2686aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public String toString() { 2687aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta // event dump 2688aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta StringBuilder result = new StringBuilder(); 2689aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta result.append("StackEvent {type:" + EVENT_TYPE_NAMES[type]); 2690aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta result.append(", value1:" + valueInt); 2691aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta result.append(", value2:" + valueInt2); 2692aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta result.append(", value3:" + valueInt3); 2693aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta result.append(", value4:" + valueInt4); 2694aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta result.append(", string: \"" + valueString + "\""); 2695aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta result.append(", device:" + device + "}"); 2696aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return result.toString(); 2697aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2698aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2699aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2700aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private native static void classInitNative(); 2701aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2702aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private native void initializeNative(); 2703aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2704aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private native void cleanupNative(); 2705aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2706aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private native boolean connectNative(byte[] address); 2707aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2708aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private native boolean disconnectNative(byte[] address); 2709aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2710aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private native boolean connectAudioNative(byte[] address); 2711aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2712aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private native boolean disconnectAudioNative(byte[] address); 2713aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2714aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private native boolean startVoiceRecognitionNative(); 2715aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2716aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private native boolean stopVoiceRecognitionNative(); 2717aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2718aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private native boolean setVolumeNative(int volumeType, int volume); 2719aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2720aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private native boolean dialNative(String number); 2721aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2722aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private native boolean dialMemoryNative(int location); 2723aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2724aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private native boolean handleCallActionNative(int action, int index); 2725aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2726aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private native boolean queryCurrentCallsNative(); 2727aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2728aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private native boolean queryCurrentOperatorNameNative(); 2729aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2730aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private native boolean retrieveSubscriberInfoNative(); 2731aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2732aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private native boolean sendDtmfNative(byte code); 2733aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2734aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private native boolean requestLastVoiceTagNumberNative(); 2735aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2736aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta private native boolean sendATCmdNative(int ATCmd, int val1, 2737aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta int val2, String arg); 2738aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 27398d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood public List<BluetoothHeadsetClientCall> getCurrentCalls() { 27408d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood return new ArrayList<BluetoothHeadsetClientCall>(mCalls.values()); 2741aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2742aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta 2743aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta public Bundle getCurrentAgEvents() { 2744aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta Bundle b = new Bundle(); 27458d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood b.putInt(BluetoothHeadsetClient.EXTRA_NETWORK_STATUS, mIndicatorNetworkState); 27468d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood b.putInt(BluetoothHeadsetClient.EXTRA_NETWORK_SIGNAL_STRENGTH, mIndicatorNetworkSignal); 27478d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood b.putInt(BluetoothHeadsetClient.EXTRA_NETWORK_ROAMING, mIndicatorNetworkType); 27488d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood b.putInt(BluetoothHeadsetClient.EXTRA_BATTERY_LEVEL, mIndicatorBatteryLevel); 27498d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood b.putString(BluetoothHeadsetClient.EXTRA_OPERATOR_NAME, mOperatorName); 27508d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood b.putInt(BluetoothHeadsetClient.EXTRA_VOICE_RECOGNITION, mVoiceRecognitionActive); 27518d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood b.putInt(BluetoothHeadsetClient.EXTRA_IN_BAND_RING, mInBandRingtone); 27528d536f3db19e8ea7426e98e470dc15d10ecbae87Mike Lockwood b.putString(BluetoothHeadsetClient.EXTRA_SUBSCRIBER_INFO, mSubscriberInfo); 2753aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta return b; 2754aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta } 2755aebc726105204f8a7b977eb3556c14b5ba18a5caHemant Gupta} 2756