Loading src/com/android/bluetooth/hfp/HeadsetPhoneState.java +23 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,12 @@ class HeadsetPhoneState { // Number of held (background) calls private int mNumHeld = 0; // Phone Number private String mNumber; // Type of Phone Number private int mType = 0; // HFP 1.6 CIND signal private int mSignal = 0; Loading Loading @@ -116,6 +122,23 @@ class HeadsetPhoneState { mNumHeld = numHeldCall; } void setNumber(String mNumberCall ) { mNumber = mNumberCall; } String getNumber() { return mNumber; } void setType(int mTypeCall) { mType = mTypeCall; } int getType() { return mType; } int getSignal() { return mSignal; } Loading src/com/android/bluetooth/hfp/HeadsetService.java 100755 → 100644 +9 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.bluetooth.hfp; import android.bluetooth.BluetoothA2dp; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHeadset; import android.bluetooth.BluetoothProfile; Loading Loading @@ -63,6 +64,8 @@ public class HeadsetService extends ProfileService { IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); filter.addAction(AudioManager.VOLUME_CHANGED_ACTION); filter.addAction(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY); filter.addAction(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED); filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED); try { registerReceiver(mHeadsetReceiver, filter); } catch (Exception e) { Loading Loading @@ -106,6 +109,12 @@ public class HeadsetService extends ProfileService { else if (action.equals(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY)) { Log.v(TAG, "HeadsetService - Received BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY"); mStateMachine.handleAccessPermissionResult(intent); } else if (intent.getAction().equals(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED)) { Log.v(TAG, "HeadsetService - Received BluetoothA2dp Play State changed"); mStateMachine.sendMessage(HeadsetStateMachine.UPDATE_A2DP_PLAY_STATE, intent); } else if (intent.getAction().equals(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED)) { Log.v(TAG, "HeadsetService - Received BluetoothA2dp Conn State changed"); mStateMachine.sendMessage(HeadsetStateMachine.UPDATE_A2DP_CONN_STATE, intent); } } }; Loading src/com/android/bluetooth/hfp/HeadsetStateMachine.java +160 −3 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ */ package com.android.bluetooth.hfp; import android.bluetooth.BluetoothA2dp; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothAssignedNumbers; import android.bluetooth.BluetoothDevice; Loading Loading @@ -105,6 +106,8 @@ final class HeadsetStateMachine extends StateMachine { static final int VIRTUAL_CALL_START = 14; static final int VIRTUAL_CALL_STOP = 15; static final int UPDATE_A2DP_PLAY_STATE = 16; static final int UPDATE_A2DP_CONN_STATE = 17; private static final int STACK_EVENT = 101; private static final int DIALING_OUT_TIMEOUT = 102; Loading Loading @@ -172,6 +175,11 @@ final class HeadsetStateMachine extends StateMachine { private IBluetoothHeadsetPhone mPhoneProxy; private boolean mNativeAvailable; private boolean mA2dpSuspend; private int mA2dpPlayState; private int mA2dpState; private boolean mPendingCiev; // mCurrentDevice is the device connected before the state changes // mTargetDevice is the device to be connected // mIncomingDevice is the device connecting to us, valid only in Pending state Loading Loading @@ -233,7 +241,6 @@ final class HeadsetStateMachine extends StateMachine { mConnection, 0)) { Log.e(TAG, "Could not bind to Bluetooth Headset Phone Service"); } initializeNative(); mNativeAvailable=true; Loading Loading @@ -359,6 +366,12 @@ final class HeadsetStateMachine extends StateMachine { processCallState((HeadsetCallState) message.obj, ((message.arg1 == 1)?true:false)); break; case UPDATE_A2DP_PLAY_STATE: processIntentA2dpPlayStateChanged((Intent) message.obj); break; case UPDATE_A2DP_CONN_STATE: processIntentA2dpStateChanged((Intent) message.obj); break; case STACK_EVENT: StackEvent event = (StackEvent) message.obj; if (DBG) { Loading Loading @@ -737,6 +750,12 @@ final class HeadsetStateMachine extends StateMachine { case VIRTUAL_CALL_STOP: terminateScoUsingVirtualVoiceCall(); break; case UPDATE_A2DP_PLAY_STATE: processIntentA2dpPlayStateChanged((Intent) message.obj); break; case UPDATE_A2DP_CONN_STATE: processIntentA2dpStateChanged((Intent) message.obj); break; case START_VR_TIMEOUT: if (mWaitingForVoiceRecognition) { mWaitingForVoiceRecognition = false; Loading Loading @@ -874,6 +893,16 @@ final class HeadsetStateMachine extends StateMachine { mPhoneState.listenForPhoneState(true); mPhoneProxy.queryPhoneState(); mCodec = CODEC_NONE; mA2dpSuspend = false;/*Reset at SLC*/ mPendingCiev = false; if ((isInCall()) && (mA2dpState == BluetoothProfile.STATE_CONNECTED)) { if (DBG) { log("Headset connected while we are in some call state"); log("Make A2dpSuspended=true here"); } mAudioManager.setParameters("A2dpSuspended=true"); mA2dpSuspend = true; } } catch (RemoteException e) { Log.e(TAG, Log.getStackTraceString(new Throwable())); } Loading Loading @@ -951,7 +980,12 @@ final class HeadsetStateMachine extends StateMachine { case VIRTUAL_CALL_STOP: terminateScoUsingVirtualVoiceCall(); break; case UPDATE_A2DP_PLAY_STATE: processIntentA2dpPlayStateChanged((Intent) message.obj); break; case UPDATE_A2DP_CONN_STATE: processIntentA2dpStateChanged((Intent) message.obj); break; case DIALING_OUT_TIMEOUT: if (mDialingOut) { mDialingOut= false; Loading Loading @@ -1064,6 +1098,13 @@ final class HeadsetStateMachine extends StateMachine { if (mAudioState != BluetoothHeadset.STATE_AUDIO_DISCONNECTED) { mAudioState = BluetoothHeadset.STATE_AUDIO_DISCONNECTED; mAudioManager.setBluetoothScoOn(false); if (mA2dpSuspend) { if ((!isInCall()) && (mPhoneState.getNumber().isEmpty())) { log("Audio is closed,Set A2dpSuspended=false"); mAudioManager.setParameters("A2dpSuspended=false"); mA2dpSuspend = false; } } broadcastAudioState(device, BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTED); } Loading Loading @@ -1451,6 +1492,16 @@ final class HeadsetStateMachine extends StateMachine { Log.e(TAG, "initiateScoUsingVirtualVoiceCall: Call in progress."); return false; } setVirtualCallInProgress(true); if (mA2dpState == BluetoothProfile.STATE_CONNECTED) { mAudioManager.setParameters("A2dpSuspended=true"); mA2dpSuspend = true; if (mA2dpPlayState == BluetoothA2dp.STATE_PLAYING) { log("suspending A2DP stream for SCO"); mPendingCiev = true; return true; } } // 2. Send virtual phone state changed to initialize SCO processCallState(new HeadsetCallState(0, 0, Loading @@ -1459,7 +1510,6 @@ final class HeadsetStateMachine extends StateMachine { HeadsetHalConstants.CALL_STATE_ALERTING, "", 0), true); processCallState(new HeadsetCallState(1, 0, HeadsetHalConstants.CALL_STATE_IDLE, "", 0), true); setVirtualCallInProgress(true); // Done if (DBG) log("initiateScoUsingVirtualVoiceCall: Done"); return true; Loading @@ -1478,11 +1528,84 @@ final class HeadsetStateMachine extends StateMachine { processCallState(new HeadsetCallState(0, 0, HeadsetHalConstants.CALL_STATE_IDLE, "", 0), true); setVirtualCallInProgress(false); // Virtual call is Ended set A2dpSuspended to false if (mA2dpSuspend) { mAudioManager.setParameters("A2dpSuspended=false"); mA2dpSuspend = false; } // Done if (DBG) log("terminateScoUsingVirtualVoiceCall: Done"); return true; } /* Check for a2dp state change.mA2dpSuspend is set if we had suspended stream and process only in that condition A2dp state could be in playing soon after connection if Headset got connected while in call and music was played before that (Special case to handle RINGER VOLUME zero + music + call) */ private void processIntentA2dpStateChanged(Intent intent) { int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_DISCONNECTED); int oldState = intent.getIntExtra(BluetoothProfile. EXTRA_PREVIOUS_STATE,BluetoothProfile.STATE_DISCONNECTED); if (DBG) { Log.v(TAG, "A2dp State Changed: Current State: " + state + "Prev State: " + oldState + "A2pSuspend: " + mA2dpSuspend); } mA2dpState = state; } private void processIntentA2dpPlayStateChanged(Intent intent) { int currState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, BluetoothA2dp.STATE_NOT_PLAYING); int prevState = intent.getIntExtra( BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothA2dp.STATE_NOT_PLAYING); if (DBG) { Log.v(TAG, "A2dp Play State Changed: Current State: " + currState + "Prev State: " + prevState + "A2pSuspend: " + mA2dpSuspend); } mA2dpPlayState = currState; if (prevState == BluetoothA2dp.STATE_PLAYING) { if (mA2dpSuspend && mPendingCiev) { if (isVirtualCallInProgress()) { //Send virtual phone state changed to initialize SCO processCallState(new HeadsetCallState(0, 0, HeadsetHalConstants.CALL_STATE_DIALING, "", 0), true); processCallState(new HeadsetCallState(0, 0, HeadsetHalConstants.CALL_STATE_ALERTING, "", 0), true); processCallState(new HeadsetCallState(1, 0, HeadsetHalConstants.CALL_STATE_IDLE, "", 0), true); } else { //send incomming phone status to remote device log("A2dp is suspended, updating phone status if any"); phoneStateChangeNative( mPhoneState.getNumActiveCall(), mPhoneState.getNumHeldCall(),mPhoneState.getCallState(), mPhoneState.getNumber(),mPhoneState.getType()); } mPendingCiev = false; } } else if (prevState == BluetoothA2dp.STATE_NOT_PLAYING) { Log.v(TAG,"A2dp Started " + currState); if ((isInCall() || isVirtualCallInProgress()) && isConnected()) { if(mA2dpSuspend) Log.e(TAG,"A2dp started while in call, ERROR"); else { log("Suspend A2dp"); mA2dpSuspend = true; mAudioManager.setParameters("A2dpSuspended=true"); } } } } private void processAnswerCall() { if (mPhoneProxy != null) { try { Loading Loading @@ -1591,6 +1714,8 @@ final class HeadsetStateMachine extends StateMachine { mPhoneState.setNumActiveCall(callState.mNumActive); mPhoneState.setNumHeldCall(callState.mNumHeld); mPhoneState.setCallState(callState.mCallState); mPhoneState.setNumber(callState.mNumber); mPhoneState.setType(callState.mType); if (mDialingOut && callState.mCallState == HeadsetHalConstants.CALL_STATE_DIALING) { atResponseCodeNative(HeadsetHalConstants.AT_RESPONSE_OK, 0); Loading @@ -1605,10 +1730,42 @@ final class HeadsetStateMachine extends StateMachine { before sending phoneStateChangeNative to BTIF */ terminateScoUsingVirtualVoiceCall(); } processA2dpState(callState); } /* This function makes sure that we send a2dp suspend before updating on Incomming call status. There may problem with some headsets if send ring and a2dp is not suspended, so here we suspend stream if active before updating remote.We resume streaming once callstate is idle and there are no active or held calls. */ private void processA2dpState(HeadsetCallState callState) { if (DBG) { log("mA2dpPlayState " + mA2dpPlayState + " mA2dpSuspend " + mA2dpSuspend ); } if ((isInCall()) && (isConnected()) && (mA2dpState == BluetoothProfile.STATE_CONNECTED) && (!mA2dpSuspend)) { mAudioManager.setParameters("A2dpSuspended=true"); mA2dpSuspend = true; if (mA2dpPlayState == BluetoothA2dp.STATE_PLAYING) { log("suspending A2DP stream for Call"); mPendingCiev = true; return ; } } if (getCurrentState() != mDisconnected) { if (DBG) { log("No A2dp playing to suspend"); } phoneStateChangeNative(callState.mNumActive, callState.mNumHeld, callState.mCallState, callState.mNumber, callState.mType); } if (mA2dpSuspend && (!isAudioOn())) { if ((!isInCall()) && (callState.mNumber.isEmpty())) { log("Set A2dpSuspended=false to reset the a2dp state to standby"); mAudioManager.setParameters("A2dpSuspended=false"); mA2dpSuspend = false; } } } // enable 1 enable noice reduction Loading Loading
src/com/android/bluetooth/hfp/HeadsetPhoneState.java +23 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,12 @@ class HeadsetPhoneState { // Number of held (background) calls private int mNumHeld = 0; // Phone Number private String mNumber; // Type of Phone Number private int mType = 0; // HFP 1.6 CIND signal private int mSignal = 0; Loading Loading @@ -116,6 +122,23 @@ class HeadsetPhoneState { mNumHeld = numHeldCall; } void setNumber(String mNumberCall ) { mNumber = mNumberCall; } String getNumber() { return mNumber; } void setType(int mTypeCall) { mType = mTypeCall; } int getType() { return mType; } int getSignal() { return mSignal; } Loading
src/com/android/bluetooth/hfp/HeadsetService.java 100755 → 100644 +9 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.bluetooth.hfp; import android.bluetooth.BluetoothA2dp; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHeadset; import android.bluetooth.BluetoothProfile; Loading Loading @@ -63,6 +64,8 @@ public class HeadsetService extends ProfileService { IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); filter.addAction(AudioManager.VOLUME_CHANGED_ACTION); filter.addAction(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY); filter.addAction(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED); filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED); try { registerReceiver(mHeadsetReceiver, filter); } catch (Exception e) { Loading Loading @@ -106,6 +109,12 @@ public class HeadsetService extends ProfileService { else if (action.equals(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY)) { Log.v(TAG, "HeadsetService - Received BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY"); mStateMachine.handleAccessPermissionResult(intent); } else if (intent.getAction().equals(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED)) { Log.v(TAG, "HeadsetService - Received BluetoothA2dp Play State changed"); mStateMachine.sendMessage(HeadsetStateMachine.UPDATE_A2DP_PLAY_STATE, intent); } else if (intent.getAction().equals(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED)) { Log.v(TAG, "HeadsetService - Received BluetoothA2dp Conn State changed"); mStateMachine.sendMessage(HeadsetStateMachine.UPDATE_A2DP_CONN_STATE, intent); } } }; Loading
src/com/android/bluetooth/hfp/HeadsetStateMachine.java +160 −3 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ */ package com.android.bluetooth.hfp; import android.bluetooth.BluetoothA2dp; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothAssignedNumbers; import android.bluetooth.BluetoothDevice; Loading Loading @@ -105,6 +106,8 @@ final class HeadsetStateMachine extends StateMachine { static final int VIRTUAL_CALL_START = 14; static final int VIRTUAL_CALL_STOP = 15; static final int UPDATE_A2DP_PLAY_STATE = 16; static final int UPDATE_A2DP_CONN_STATE = 17; private static final int STACK_EVENT = 101; private static final int DIALING_OUT_TIMEOUT = 102; Loading Loading @@ -172,6 +175,11 @@ final class HeadsetStateMachine extends StateMachine { private IBluetoothHeadsetPhone mPhoneProxy; private boolean mNativeAvailable; private boolean mA2dpSuspend; private int mA2dpPlayState; private int mA2dpState; private boolean mPendingCiev; // mCurrentDevice is the device connected before the state changes // mTargetDevice is the device to be connected // mIncomingDevice is the device connecting to us, valid only in Pending state Loading Loading @@ -233,7 +241,6 @@ final class HeadsetStateMachine extends StateMachine { mConnection, 0)) { Log.e(TAG, "Could not bind to Bluetooth Headset Phone Service"); } initializeNative(); mNativeAvailable=true; Loading Loading @@ -359,6 +366,12 @@ final class HeadsetStateMachine extends StateMachine { processCallState((HeadsetCallState) message.obj, ((message.arg1 == 1)?true:false)); break; case UPDATE_A2DP_PLAY_STATE: processIntentA2dpPlayStateChanged((Intent) message.obj); break; case UPDATE_A2DP_CONN_STATE: processIntentA2dpStateChanged((Intent) message.obj); break; case STACK_EVENT: StackEvent event = (StackEvent) message.obj; if (DBG) { Loading Loading @@ -737,6 +750,12 @@ final class HeadsetStateMachine extends StateMachine { case VIRTUAL_CALL_STOP: terminateScoUsingVirtualVoiceCall(); break; case UPDATE_A2DP_PLAY_STATE: processIntentA2dpPlayStateChanged((Intent) message.obj); break; case UPDATE_A2DP_CONN_STATE: processIntentA2dpStateChanged((Intent) message.obj); break; case START_VR_TIMEOUT: if (mWaitingForVoiceRecognition) { mWaitingForVoiceRecognition = false; Loading Loading @@ -874,6 +893,16 @@ final class HeadsetStateMachine extends StateMachine { mPhoneState.listenForPhoneState(true); mPhoneProxy.queryPhoneState(); mCodec = CODEC_NONE; mA2dpSuspend = false;/*Reset at SLC*/ mPendingCiev = false; if ((isInCall()) && (mA2dpState == BluetoothProfile.STATE_CONNECTED)) { if (DBG) { log("Headset connected while we are in some call state"); log("Make A2dpSuspended=true here"); } mAudioManager.setParameters("A2dpSuspended=true"); mA2dpSuspend = true; } } catch (RemoteException e) { Log.e(TAG, Log.getStackTraceString(new Throwable())); } Loading Loading @@ -951,7 +980,12 @@ final class HeadsetStateMachine extends StateMachine { case VIRTUAL_CALL_STOP: terminateScoUsingVirtualVoiceCall(); break; case UPDATE_A2DP_PLAY_STATE: processIntentA2dpPlayStateChanged((Intent) message.obj); break; case UPDATE_A2DP_CONN_STATE: processIntentA2dpStateChanged((Intent) message.obj); break; case DIALING_OUT_TIMEOUT: if (mDialingOut) { mDialingOut= false; Loading Loading @@ -1064,6 +1098,13 @@ final class HeadsetStateMachine extends StateMachine { if (mAudioState != BluetoothHeadset.STATE_AUDIO_DISCONNECTED) { mAudioState = BluetoothHeadset.STATE_AUDIO_DISCONNECTED; mAudioManager.setBluetoothScoOn(false); if (mA2dpSuspend) { if ((!isInCall()) && (mPhoneState.getNumber().isEmpty())) { log("Audio is closed,Set A2dpSuspended=false"); mAudioManager.setParameters("A2dpSuspended=false"); mA2dpSuspend = false; } } broadcastAudioState(device, BluetoothHeadset.STATE_AUDIO_DISCONNECTED, BluetoothHeadset.STATE_AUDIO_CONNECTED); } Loading Loading @@ -1451,6 +1492,16 @@ final class HeadsetStateMachine extends StateMachine { Log.e(TAG, "initiateScoUsingVirtualVoiceCall: Call in progress."); return false; } setVirtualCallInProgress(true); if (mA2dpState == BluetoothProfile.STATE_CONNECTED) { mAudioManager.setParameters("A2dpSuspended=true"); mA2dpSuspend = true; if (mA2dpPlayState == BluetoothA2dp.STATE_PLAYING) { log("suspending A2DP stream for SCO"); mPendingCiev = true; return true; } } // 2. Send virtual phone state changed to initialize SCO processCallState(new HeadsetCallState(0, 0, Loading @@ -1459,7 +1510,6 @@ final class HeadsetStateMachine extends StateMachine { HeadsetHalConstants.CALL_STATE_ALERTING, "", 0), true); processCallState(new HeadsetCallState(1, 0, HeadsetHalConstants.CALL_STATE_IDLE, "", 0), true); setVirtualCallInProgress(true); // Done if (DBG) log("initiateScoUsingVirtualVoiceCall: Done"); return true; Loading @@ -1478,11 +1528,84 @@ final class HeadsetStateMachine extends StateMachine { processCallState(new HeadsetCallState(0, 0, HeadsetHalConstants.CALL_STATE_IDLE, "", 0), true); setVirtualCallInProgress(false); // Virtual call is Ended set A2dpSuspended to false if (mA2dpSuspend) { mAudioManager.setParameters("A2dpSuspended=false"); mA2dpSuspend = false; } // Done if (DBG) log("terminateScoUsingVirtualVoiceCall: Done"); return true; } /* Check for a2dp state change.mA2dpSuspend is set if we had suspended stream and process only in that condition A2dp state could be in playing soon after connection if Headset got connected while in call and music was played before that (Special case to handle RINGER VOLUME zero + music + call) */ private void processIntentA2dpStateChanged(Intent intent) { int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_DISCONNECTED); int oldState = intent.getIntExtra(BluetoothProfile. EXTRA_PREVIOUS_STATE,BluetoothProfile.STATE_DISCONNECTED); if (DBG) { Log.v(TAG, "A2dp State Changed: Current State: " + state + "Prev State: " + oldState + "A2pSuspend: " + mA2dpSuspend); } mA2dpState = state; } private void processIntentA2dpPlayStateChanged(Intent intent) { int currState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, BluetoothA2dp.STATE_NOT_PLAYING); int prevState = intent.getIntExtra( BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothA2dp.STATE_NOT_PLAYING); if (DBG) { Log.v(TAG, "A2dp Play State Changed: Current State: " + currState + "Prev State: " + prevState + "A2pSuspend: " + mA2dpSuspend); } mA2dpPlayState = currState; if (prevState == BluetoothA2dp.STATE_PLAYING) { if (mA2dpSuspend && mPendingCiev) { if (isVirtualCallInProgress()) { //Send virtual phone state changed to initialize SCO processCallState(new HeadsetCallState(0, 0, HeadsetHalConstants.CALL_STATE_DIALING, "", 0), true); processCallState(new HeadsetCallState(0, 0, HeadsetHalConstants.CALL_STATE_ALERTING, "", 0), true); processCallState(new HeadsetCallState(1, 0, HeadsetHalConstants.CALL_STATE_IDLE, "", 0), true); } else { //send incomming phone status to remote device log("A2dp is suspended, updating phone status if any"); phoneStateChangeNative( mPhoneState.getNumActiveCall(), mPhoneState.getNumHeldCall(),mPhoneState.getCallState(), mPhoneState.getNumber(),mPhoneState.getType()); } mPendingCiev = false; } } else if (prevState == BluetoothA2dp.STATE_NOT_PLAYING) { Log.v(TAG,"A2dp Started " + currState); if ((isInCall() || isVirtualCallInProgress()) && isConnected()) { if(mA2dpSuspend) Log.e(TAG,"A2dp started while in call, ERROR"); else { log("Suspend A2dp"); mA2dpSuspend = true; mAudioManager.setParameters("A2dpSuspended=true"); } } } } private void processAnswerCall() { if (mPhoneProxy != null) { try { Loading Loading @@ -1591,6 +1714,8 @@ final class HeadsetStateMachine extends StateMachine { mPhoneState.setNumActiveCall(callState.mNumActive); mPhoneState.setNumHeldCall(callState.mNumHeld); mPhoneState.setCallState(callState.mCallState); mPhoneState.setNumber(callState.mNumber); mPhoneState.setType(callState.mType); if (mDialingOut && callState.mCallState == HeadsetHalConstants.CALL_STATE_DIALING) { atResponseCodeNative(HeadsetHalConstants.AT_RESPONSE_OK, 0); Loading @@ -1605,10 +1730,42 @@ final class HeadsetStateMachine extends StateMachine { before sending phoneStateChangeNative to BTIF */ terminateScoUsingVirtualVoiceCall(); } processA2dpState(callState); } /* This function makes sure that we send a2dp suspend before updating on Incomming call status. There may problem with some headsets if send ring and a2dp is not suspended, so here we suspend stream if active before updating remote.We resume streaming once callstate is idle and there are no active or held calls. */ private void processA2dpState(HeadsetCallState callState) { if (DBG) { log("mA2dpPlayState " + mA2dpPlayState + " mA2dpSuspend " + mA2dpSuspend ); } if ((isInCall()) && (isConnected()) && (mA2dpState == BluetoothProfile.STATE_CONNECTED) && (!mA2dpSuspend)) { mAudioManager.setParameters("A2dpSuspended=true"); mA2dpSuspend = true; if (mA2dpPlayState == BluetoothA2dp.STATE_PLAYING) { log("suspending A2DP stream for Call"); mPendingCiev = true; return ; } } if (getCurrentState() != mDisconnected) { if (DBG) { log("No A2dp playing to suspend"); } phoneStateChangeNative(callState.mNumActive, callState.mNumHeld, callState.mCallState, callState.mNumber, callState.mType); } if (mA2dpSuspend && (!isAudioOn())) { if ((!isInCall()) && (callState.mNumber.isEmpty())) { log("Set A2dpSuspended=false to reset the a2dp state to standby"); mAudioManager.setParameters("A2dpSuspended=false"); mA2dpSuspend = false; } } } // enable 1 enable noice reduction Loading