From 4ed37ea81a239f189e65be89651b988e47e836ca Mon Sep 17 00:00:00 2001 From: Jean-Michel Trivi Date: Thu, 26 Jan 2012 11:10:29 -0800 Subject: [PATCH] Bug 5567648 Request and abandon audio focus in calls Up to now, audio focus was implicitly requested and abandoned when changing the audio mode. This is no longer the case so the behavior with regards to audio focus can be indepently set by the CallManager. The logic implemented here is the same as the one previously used in AudioService: - only request audio focus when the ring volume index is > 0 when ringing, - request focus before setting the audio mode to a mode other than normal - abandon audio focus after setting the audio mode to normal Change-Id: Ia543dc779563dbff09414771fee60e589dfaab9d --- .../internal/telephony/CallManager.java | 39 ++++++++++++++----- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/telephony/java/com/android/internal/telephony/CallManager.java b/telephony/java/com/android/internal/telephony/CallManager.java index 3dd57ee742f24..f825f31dd005f 100644 --- a/telephony/java/com/android/internal/telephony/CallManager.java +++ b/telephony/java/com/android/internal/telephony/CallManager.java @@ -373,10 +373,19 @@ public final class CallManager { AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); - int mode = AudioManager.MODE_NORMAL; + // change the audio mode and request/abandon audio focus according to phone state, + // but only on audio mode transitions switch (getState()) { case RINGING: - mode = AudioManager.MODE_RINGTONE; + if (audioManager.getMode() != AudioManager.MODE_RINGTONE) { + // only request audio focus if the ringtone is going to be heard + if (audioManager.getStreamVolume(AudioManager.STREAM_RING) > 0) { + if (VDBG) Log.d(LOG_TAG, "requestAudioFocus on STREAM_RING"); + audioManager.requestAudioFocusForCall(AudioManager.STREAM_RING, + AudioManager.AUDIOFOCUS_GAIN_TRANSIENT); + } + audioManager.setMode(AudioManager.MODE_RINGTONE); + } break; case OFFHOOK: Phone offhookPhone = getFgPhone(); @@ -386,18 +395,28 @@ public final class CallManager { offhookPhone = getBgPhone(); } + int newAudioMode = AudioManager.MODE_IN_CALL; if (offhookPhone instanceof SipPhone) { - // enable IN_COMMUNICATION audio mode for sipPhone - mode = AudioManager.MODE_IN_COMMUNICATION; - } else { - // enable IN_CALL audio mode for telephony - mode = AudioManager.MODE_IN_CALL; + // enable IN_COMMUNICATION audio mode instead for sipPhone + newAudioMode = AudioManager.MODE_IN_COMMUNICATION; + } + if (audioManager.getMode() != newAudioMode) { + // request audio focus before setting the new mode + if (VDBG) Log.d(LOG_TAG, "requestAudioFocus on STREAM_VOICE_CALL"); + audioManager.requestAudioFocusForCall(AudioManager.STREAM_VOICE_CALL, + AudioManager.AUDIOFOCUS_GAIN_TRANSIENT); + audioManager.setMode(newAudioMode); + } + break; + case IDLE: + if (audioManager.getMode() != AudioManager.MODE_NORMAL) { + audioManager.setMode(AudioManager.MODE_NORMAL); + if (VDBG) Log.d(LOG_TAG, "abandonAudioFocus"); + // abandon audio focus after the mode has been set back to normal + audioManager.abandonAudioFocusForCall(); } break; } - // calling audioManager.setMode() multiple times in a short period of - // time seems to break the audio recorder in in-call mode - if (audioManager.getMode() != mode) audioManager.setMode(mode); } private Context getContext() {