Loading android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java +40 −34 Original line number Diff line number Diff line Loading @@ -114,6 +114,9 @@ public class HeadsetClientStateMachine extends StateMachine { private long OUTGOING_TIMEOUT_MILLI = 10 * 1000; // 10 seconds private long QUERY_CURRENT_CALLS_WAIT_MILLIS = 2 * 1000; // 2 seconds // Keep track of audio routing across all devices. private static boolean sAudioIsRouted = true; private final Disconnected mDisconnected; private final Connecting mConnecting; private final Connected mConnected; Loading Loading @@ -147,7 +150,7 @@ public class HeadsetClientStateMachine extends StateMachine { // indicator private Pair<Integer, Object> mPendingAction; private final AudioManager mAudioManager; private static AudioManager sAudioManager; private int mAudioState; private boolean mAudioWbs; private final BluetoothAdapter mAdapter; Loading Loading @@ -479,11 +482,8 @@ public class HeadsetClientStateMachine extends StateMachine { } if (flag == BluetoothHeadsetClient.CALL_ACCEPT_HOLD) { // HFP is disabled when a call is put on hold to ensure correct audio routing for // cellular calls accepted while an HFP call is in progress. Reenable HFP when the HFP // call is put off hold. Log.d(TAG,"hfp_enable=true"); mAudioManager.setParameters("hfp_enable=true"); // When unholding a call over Bluetooth make sure to route audio. routeHfpAudio(true); } if (NativeInterface.handleCallActionNative(getByteAddress(mCurrentDevice), action, 0)) { Loading Loading @@ -580,7 +580,6 @@ public class HeadsetClientStateMachine extends StateMachine { if (c != null) { if (NativeInterface.handleCallActionNative(getByteAddress(mCurrentDevice), action, 0)) { addQueuedAction(TERMINATE_CALL, action); sendMessageDelayed(DISCONNECT_AUDIO, SCO_DISCONNECT_TIMEOUT_MS); } else { Log.e(TAG, "ERROR: Couldn't terminate outgoing call"); } Loading Loading @@ -669,7 +668,11 @@ public class HeadsetClientStateMachine extends StateMachine { mService = context; mAdapter = BluetoothAdapter.getDefaultAdapter(); mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); if (sAudioManager == null) { sAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); // Initialize hfp_enable into a known state. routeHfpAudio(false); } mAudioState = BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED; mAudioWbs = false; Loading @@ -680,8 +683,8 @@ public class HeadsetClientStateMachine extends StateMachine { mIndicatorNetworkSignal = 0; mIndicatorBatteryLevel = 0; mMaxAmVcVol = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL); mMinAmVcVol = mAudioManager.getStreamMinVolume(AudioManager.STREAM_VOICE_CALL); mMaxAmVcVol = sAudioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL); mMinAmVcVol = sAudioManager.getStreamMinVolume(AudioManager.STREAM_VOICE_CALL); mOperatorName = null; mSubscriberInfo = null; Loading Loading @@ -714,10 +717,22 @@ public class HeadsetClientStateMachine extends StateMachine { return hfcsm; } static synchronized void routeHfpAudio(boolean enable) { if (DBG) { Log.d(TAG, "hfp_enable=" + enable); } if (enable && !sAudioIsRouted) { sAudioManager.setParameters("hfp_enable=true"); } else if (!enable) { sAudioManager.setParameters("hfp_enable=false"); } sAudioIsRouted = enable; } public void doQuit() { Log.d(TAG, "doQuit"); if (mAudioManager != null) { mAudioManager.setParameters("hfp_enable=false"); if (sAudioManager != null) { routeHfpAudio(false); } quitNow(); } Loading Loading @@ -988,13 +1003,13 @@ public class HeadsetClientStateMachine extends StateMachine { } transitionTo(mConnected); int amVol = mAudioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL); int amVol = sAudioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL); sendMessage( obtainMessage(HeadsetClientStateMachine.SET_SPEAKER_VOLUME, amVol, 0)); // Mic is either in ON state (full volume) or OFF state. There is no way in // Android to change the MIC volume. sendMessage(obtainMessage(HeadsetClientStateMachine.SET_MIC_VOLUME, mAudioManager.isMicrophoneMute() ? 0 : 15, 0)); sAudioManager.isMicrophoneMute() ? 0 : 15, 0)); // query subscriber info sendMessage(HeadsetClientStateMachine.SUBSCRIBER_INFO); Loading Loading @@ -1106,7 +1121,7 @@ public class HeadsetClientStateMachine extends StateMachine { int amVol = message.arg1; int hfVol = amToHfVol(amVol); Log.d(TAG,"HF volume is set to " + hfVol); mAudioManager.setParameters("hfp_volume=" + hfVol); sAudioManager.setParameters("hfp_volume=" + hfVol); // We do not set the volume in native because multiple devices might be // connected and it does not make sense to synchronize them. Car becomes the // master in such case. Loading Loading @@ -1292,13 +1307,11 @@ public class HeadsetClientStateMachine extends StateMachine { if (event.valueInt == HeadsetClientHalConstants.VOLUME_TYPE_SPK) { Log.d(TAG, "AM volume set to " + hfToAmVol(event.valueInt2)); mAudioManager.setStreamVolume( AudioManager.STREAM_VOICE_CALL, hfToAmVol(event.valueInt2), AudioManager.FLAG_SHOW_UI); sAudioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL, hfToAmVol(event.valueInt2), AudioManager.FLAG_SHOW_UI); } else if (event.valueInt == HeadsetClientHalConstants.VOLUME_TYPE_MIC) { mAudioManager.setMicrophoneMute(event.valueInt2 == 0); sAudioManager.setMicrophoneMute(event.valueInt2 == 0); } break; case StackEvent.EVENT_TYPE_CMD_RESULT: Loading Loading @@ -1408,8 +1421,7 @@ public class HeadsetClientStateMachine extends StateMachine { // We need to set the volume after switching into HFP mode as some Audio HALs // reset the volume to a known-default on mode switch. final int amVol = mAudioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL); final int amVol = sAudioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL); final int hfVol = amToHfVol(amVol); if (DBG) { Loading @@ -1419,19 +1431,19 @@ public class HeadsetClientStateMachine extends StateMachine { if (DBG) { Log.d(TAG,"Setting sampling rate as 16000"); } mAudioManager.setParameters("hfp_set_sampling_rate=16000"); sAudioManager.setParameters("hfp_set_sampling_rate=16000"); } else { if (DBG) { Log.d(TAG,"Setting sampling rate as 8000"); } mAudioManager.setParameters("hfp_set_sampling_rate=8000"); sAudioManager.setParameters("hfp_set_sampling_rate=8000"); } if (DBG) { Log.d(TAG, "hf_volume " + hfVol); } mAudioManager.setParameters("hfp_enable=true"); mAudioManager.setParameters("hfp_volume=" + hfVol); routeHfpAudio(true); sAudioManager.setParameters("hfp_volume=" + hfVol); transitionTo(mAudioOn); break; Loading Loading @@ -1501,10 +1513,7 @@ public class HeadsetClientStateMachine extends StateMachine { * Machines state changing */ if (NativeInterface.disconnectAudioNative(getByteAddress(mCurrentDevice))) { if (DBG) { Log.d(TAG,"hfp_enable=false"); } mAudioManager.setParameters("hfp_enable=false"); routeHfpAudio(false); } break; Loading Loading @@ -1578,10 +1587,7 @@ public class HeadsetClientStateMachine extends StateMachine { // (such as Telecom) and hence this will still keep the call around, there // is not much we can do here since dropping the call without user consent // even if the audio connection snapped may not be a good idea. if (DBG) { Log.d(TAG, "hfp_enable=false"); } mAudioManager.setParameters("hfp_enable=false"); routeHfpAudio(false); broadcastAudioState(device, BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED, BluetoothHeadsetClient.STATE_AUDIO_CONNECTED); transitionTo(mConnected); Loading android/app/src/com/android/bluetooth/hfpclient/connserv/HfpClientConference.java +0 −5 Original line number Diff line number Diff line Loading @@ -73,11 +73,6 @@ public class HfpClientConference extends Conference { @Override public void onUnhold() { if (getPrimaryConnection().getConnectionService() .getAllConnections().size() > 1) { Log.w(TAG, "Ignoring unhold; call hold on the foreground call"); return; } Log.d(TAG, "onUnhold"); mHeadsetProfile.acceptCall(mDevice, BluetoothHeadsetClient.CALL_ACCEPT_HOLD); } Loading Loading
android/app/src/com/android/bluetooth/hfpclient/HeadsetClientStateMachine.java +40 −34 Original line number Diff line number Diff line Loading @@ -114,6 +114,9 @@ public class HeadsetClientStateMachine extends StateMachine { private long OUTGOING_TIMEOUT_MILLI = 10 * 1000; // 10 seconds private long QUERY_CURRENT_CALLS_WAIT_MILLIS = 2 * 1000; // 2 seconds // Keep track of audio routing across all devices. private static boolean sAudioIsRouted = true; private final Disconnected mDisconnected; private final Connecting mConnecting; private final Connected mConnected; Loading Loading @@ -147,7 +150,7 @@ public class HeadsetClientStateMachine extends StateMachine { // indicator private Pair<Integer, Object> mPendingAction; private final AudioManager mAudioManager; private static AudioManager sAudioManager; private int mAudioState; private boolean mAudioWbs; private final BluetoothAdapter mAdapter; Loading Loading @@ -479,11 +482,8 @@ public class HeadsetClientStateMachine extends StateMachine { } if (flag == BluetoothHeadsetClient.CALL_ACCEPT_HOLD) { // HFP is disabled when a call is put on hold to ensure correct audio routing for // cellular calls accepted while an HFP call is in progress. Reenable HFP when the HFP // call is put off hold. Log.d(TAG,"hfp_enable=true"); mAudioManager.setParameters("hfp_enable=true"); // When unholding a call over Bluetooth make sure to route audio. routeHfpAudio(true); } if (NativeInterface.handleCallActionNative(getByteAddress(mCurrentDevice), action, 0)) { Loading Loading @@ -580,7 +580,6 @@ public class HeadsetClientStateMachine extends StateMachine { if (c != null) { if (NativeInterface.handleCallActionNative(getByteAddress(mCurrentDevice), action, 0)) { addQueuedAction(TERMINATE_CALL, action); sendMessageDelayed(DISCONNECT_AUDIO, SCO_DISCONNECT_TIMEOUT_MS); } else { Log.e(TAG, "ERROR: Couldn't terminate outgoing call"); } Loading Loading @@ -669,7 +668,11 @@ public class HeadsetClientStateMachine extends StateMachine { mService = context; mAdapter = BluetoothAdapter.getDefaultAdapter(); mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); if (sAudioManager == null) { sAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); // Initialize hfp_enable into a known state. routeHfpAudio(false); } mAudioState = BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED; mAudioWbs = false; Loading @@ -680,8 +683,8 @@ public class HeadsetClientStateMachine extends StateMachine { mIndicatorNetworkSignal = 0; mIndicatorBatteryLevel = 0; mMaxAmVcVol = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL); mMinAmVcVol = mAudioManager.getStreamMinVolume(AudioManager.STREAM_VOICE_CALL); mMaxAmVcVol = sAudioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL); mMinAmVcVol = sAudioManager.getStreamMinVolume(AudioManager.STREAM_VOICE_CALL); mOperatorName = null; mSubscriberInfo = null; Loading Loading @@ -714,10 +717,22 @@ public class HeadsetClientStateMachine extends StateMachine { return hfcsm; } static synchronized void routeHfpAudio(boolean enable) { if (DBG) { Log.d(TAG, "hfp_enable=" + enable); } if (enable && !sAudioIsRouted) { sAudioManager.setParameters("hfp_enable=true"); } else if (!enable) { sAudioManager.setParameters("hfp_enable=false"); } sAudioIsRouted = enable; } public void doQuit() { Log.d(TAG, "doQuit"); if (mAudioManager != null) { mAudioManager.setParameters("hfp_enable=false"); if (sAudioManager != null) { routeHfpAudio(false); } quitNow(); } Loading Loading @@ -988,13 +1003,13 @@ public class HeadsetClientStateMachine extends StateMachine { } transitionTo(mConnected); int amVol = mAudioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL); int amVol = sAudioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL); sendMessage( obtainMessage(HeadsetClientStateMachine.SET_SPEAKER_VOLUME, amVol, 0)); // Mic is either in ON state (full volume) or OFF state. There is no way in // Android to change the MIC volume. sendMessage(obtainMessage(HeadsetClientStateMachine.SET_MIC_VOLUME, mAudioManager.isMicrophoneMute() ? 0 : 15, 0)); sAudioManager.isMicrophoneMute() ? 0 : 15, 0)); // query subscriber info sendMessage(HeadsetClientStateMachine.SUBSCRIBER_INFO); Loading Loading @@ -1106,7 +1121,7 @@ public class HeadsetClientStateMachine extends StateMachine { int amVol = message.arg1; int hfVol = amToHfVol(amVol); Log.d(TAG,"HF volume is set to " + hfVol); mAudioManager.setParameters("hfp_volume=" + hfVol); sAudioManager.setParameters("hfp_volume=" + hfVol); // We do not set the volume in native because multiple devices might be // connected and it does not make sense to synchronize them. Car becomes the // master in such case. Loading Loading @@ -1292,13 +1307,11 @@ public class HeadsetClientStateMachine extends StateMachine { if (event.valueInt == HeadsetClientHalConstants.VOLUME_TYPE_SPK) { Log.d(TAG, "AM volume set to " + hfToAmVol(event.valueInt2)); mAudioManager.setStreamVolume( AudioManager.STREAM_VOICE_CALL, hfToAmVol(event.valueInt2), AudioManager.FLAG_SHOW_UI); sAudioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL, hfToAmVol(event.valueInt2), AudioManager.FLAG_SHOW_UI); } else if (event.valueInt == HeadsetClientHalConstants.VOLUME_TYPE_MIC) { mAudioManager.setMicrophoneMute(event.valueInt2 == 0); sAudioManager.setMicrophoneMute(event.valueInt2 == 0); } break; case StackEvent.EVENT_TYPE_CMD_RESULT: Loading Loading @@ -1408,8 +1421,7 @@ public class HeadsetClientStateMachine extends StateMachine { // We need to set the volume after switching into HFP mode as some Audio HALs // reset the volume to a known-default on mode switch. final int amVol = mAudioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL); final int amVol = sAudioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL); final int hfVol = amToHfVol(amVol); if (DBG) { Loading @@ -1419,19 +1431,19 @@ public class HeadsetClientStateMachine extends StateMachine { if (DBG) { Log.d(TAG,"Setting sampling rate as 16000"); } mAudioManager.setParameters("hfp_set_sampling_rate=16000"); sAudioManager.setParameters("hfp_set_sampling_rate=16000"); } else { if (DBG) { Log.d(TAG,"Setting sampling rate as 8000"); } mAudioManager.setParameters("hfp_set_sampling_rate=8000"); sAudioManager.setParameters("hfp_set_sampling_rate=8000"); } if (DBG) { Log.d(TAG, "hf_volume " + hfVol); } mAudioManager.setParameters("hfp_enable=true"); mAudioManager.setParameters("hfp_volume=" + hfVol); routeHfpAudio(true); sAudioManager.setParameters("hfp_volume=" + hfVol); transitionTo(mAudioOn); break; Loading Loading @@ -1501,10 +1513,7 @@ public class HeadsetClientStateMachine extends StateMachine { * Machines state changing */ if (NativeInterface.disconnectAudioNative(getByteAddress(mCurrentDevice))) { if (DBG) { Log.d(TAG,"hfp_enable=false"); } mAudioManager.setParameters("hfp_enable=false"); routeHfpAudio(false); } break; Loading Loading @@ -1578,10 +1587,7 @@ public class HeadsetClientStateMachine extends StateMachine { // (such as Telecom) and hence this will still keep the call around, there // is not much we can do here since dropping the call without user consent // even if the audio connection snapped may not be a good idea. if (DBG) { Log.d(TAG, "hfp_enable=false"); } mAudioManager.setParameters("hfp_enable=false"); routeHfpAudio(false); broadcastAudioState(device, BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED, BluetoothHeadsetClient.STATE_AUDIO_CONNECTED); transitionTo(mConnected); Loading
android/app/src/com/android/bluetooth/hfpclient/connserv/HfpClientConference.java +0 −5 Original line number Diff line number Diff line Loading @@ -73,11 +73,6 @@ public class HfpClientConference extends Conference { @Override public void onUnhold() { if (getPrimaryConnection().getConnectionService() .getAllConnections().size() > 1) { Log.w(TAG, "Ignoring unhold; call hold on the foreground call"); return; } Log.d(TAG, "onUnhold"); mHeadsetProfile.acceptCall(mDevice, BluetoothHeadsetClient.CALL_ACCEPT_HOLD); } Loading