diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/BeginCallActionProcessorDelegate.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/BeginCallActionProcessorDelegate.java index 8f19bc20e7..829674f0dd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/BeginCallActionProcessorDelegate.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/BeginCallActionProcessorDelegate.java @@ -76,6 +76,7 @@ public class BeginCallActionProcessorDelegate extends WebRtcActionProcessor { webRtcInteractor.setCallInProgressNotification(TYPE_INCOMING_CONNECTING, remotePeer); webRtcInteractor.retrieveTurnServers(remotePeer); + webRtcInteractor.initializeAudioForCall(); return currentState.builder() .actionProcessor(new IncomingCallActionProcessor(webRtcInteractor)) diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/IncomingCallActionProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/IncomingCallActionProcessor.java index 59d1743a1f..5f3a4f3d8f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/IncomingCallActionProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/IncomingCallActionProcessor.java @@ -146,7 +146,6 @@ public class IncomingCallActionProcessor extends DeviceAwareActionProcessor { } } - webRtcInteractor.initializeAudioForCall(); if (shouldDisturbUserWithCall && SignalStore.settings().isCallNotificationsEnabled()) { Uri ringtone = recipient.resolve().getCallRingtone(); RecipientDatabase.VibrateState vibrateState = recipient.resolve().getCallVibrate(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/webrtc/audio/AudioManagerCompat.java b/app/src/main/java/org/thoughtcrime/securesms/webrtc/audio/AudioManagerCompat.java index e591185473..f47384910a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/webrtc/audio/AudioManagerCompat.java +++ b/app/src/main/java/org/thoughtcrime/securesms/webrtc/audio/AudioManagerCompat.java @@ -23,10 +23,12 @@ public abstract class AudioManagerCompat { private static final int AUDIOFOCUS_GAIN = AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE; protected final AudioManager audioManager; + protected boolean hasFocus; @SuppressWarnings("CodeBlock2Expr") protected final AudioManager.OnAudioFocusChangeListener onAudioFocusChangeListener = focusChange -> { Log.i(TAG, "onAudioFocusChangeListener: " + focusChange); + hasFocus = focusChange == AudioManager.AUDIOFOCUS_GAIN; }; private AudioManagerCompat(@NonNull Context context) { @@ -116,7 +118,7 @@ public abstract class AudioManagerCompat { } abstract public SoundPool createSoundPool(); - abstract public void requestCallAudioFocus(); + abstract public boolean requestCallAudioFocus(); abstract public void abandonCallAudioFocus(); public static AudioManagerCompat create(@NonNull Context context) { @@ -152,22 +154,29 @@ public abstract class AudioManagerCompat { } @Override - public void requestCallAudioFocus() { - if (audioFocusRequest != null) { + public boolean requestCallAudioFocus() { + if (audioFocusRequest != null && hasFocus) { Log.w(TAG, "Already requested audio focus. Ignoring..."); - return; + return true; } - audioFocusRequest = new AudioFocusRequest.Builder(AUDIOFOCUS_GAIN) - .setAudioAttributes(AUDIO_ATTRIBUTES) - .setOnAudioFocusChangeListener(onAudioFocusChangeListener) - .build(); + if (audioFocusRequest == null) { + audioFocusRequest = new AudioFocusRequest.Builder(AUDIOFOCUS_GAIN) + .setAudioAttributes(AUDIO_ATTRIBUTES) + .setOnAudioFocusChangeListener(onAudioFocusChangeListener) + .build(); + } else { + Log.w(TAG, "Trying again to request audio focus"); + } int result = audioManager.requestAudioFocus(audioFocusRequest); if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { Log.w(TAG, "Audio focus not granted. Result code: " + result); + return false; } + + return true; } @Override @@ -183,6 +192,7 @@ public abstract class AudioManagerCompat { Log.w(TAG, "Audio focus abandon failed. Result code: " + result); } + hasFocus = false; audioFocusRequest = null; } } @@ -217,16 +227,19 @@ public abstract class AudioManagerCompat { @Override public SoundPool createSoundPool() { - return new SoundPool(1, AudioManager.STREAM_VOICE_CALL, 0); + return new SoundPool(1, AudioManager.STREAM_NOTIFICATION, 0); } @Override - public void requestCallAudioFocus() { + public boolean requestCallAudioFocus() { int result = audioManager.requestAudioFocus(onAudioFocusChangeListener, AudioManager.STREAM_VOICE_CALL, AUDIOFOCUS_GAIN); if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { Log.w(TAG, "Audio focus not granted. Result code: " + result); + return false; } + + return true; } @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/webrtc/audio/IncomingRinger.java b/app/src/main/java/org/thoughtcrime/securesms/webrtc/audio/IncomingRinger.java index 6fc8525fed..1eea3aeb8e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/webrtc/audio/IncomingRinger.java +++ b/app/src/main/java/org/thoughtcrime/securesms/webrtc/audio/IncomingRinger.java @@ -117,8 +117,8 @@ public class IncomingRinger { if (Build.VERSION.SDK_INT <= 21) { mediaPlayer.setAudioStreamType(AudioManager.STREAM_RING); } else { - mediaPlayer.setAudioAttributes(new AudioAttributes.Builder().setContentType(AudioAttributes.CONTENT_TYPE_SPEECH) - .setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING) + mediaPlayer.setAudioAttributes(new AudioAttributes.Builder().setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE) .build()); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/webrtc/audio/SignalAudioManager.kt b/app/src/main/java/org/thoughtcrime/securesms/webrtc/audio/SignalAudioManager.kt index ae0f60fcd7..3cfc22a645 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/webrtc/audio/SignalAudioManager.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/webrtc/audio/SignalAudioManager.kt @@ -87,7 +87,10 @@ class SignalAudioManager(private val context: Context, private val eventListener savedIsMicrophoneMute = androidAudioManager.isMicrophoneMute hasWiredHeadset = androidAudioManager.isWiredHeadsetOn - androidAudioManager.requestCallAudioFocus() + val focusedGained = androidAudioManager.requestCallAudioFocus() + if (!focusedGained) { + handler.postDelayed({ androidAudioManager.requestCallAudioFocus() }, 500) + } setMicrophoneMute(false) @@ -116,6 +119,11 @@ class SignalAudioManager(private val context: Context, private val eventListener incomingRinger.stop() outgoingRinger.stop() + val focusedGained = androidAudioManager.requestCallAudioFocus() + if (!focusedGained) { + handler.postDelayed({ androidAudioManager.requestCallAudioFocus() }, 500) + } + state = State.RUNNING androidAudioManager.mode = AudioManager.MODE_IN_COMMUNICATION