mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-21 17:29:32 +01:00
Fix bluetooth behavior.
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
package org.thoughtcrime.securesms.webrtc.audio;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.AudioAttributes;
|
||||
import android.media.AudioFocusRequest;
|
||||
import android.media.AudioManager;
|
||||
import android.media.SoundPool;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import org.thoughtcrime.securesms.util.ServiceUtil;
|
||||
|
||||
public abstract class AudioManagerCompat {
|
||||
|
||||
protected final AudioManager audioManager;
|
||||
|
||||
private AudioManagerCompat(@NonNull Context context) {
|
||||
audioManager = ServiceUtil.getAudioManager(context);
|
||||
}
|
||||
|
||||
abstract public SoundPool createSoundPool();
|
||||
abstract public void requestCallAudioFocus();
|
||||
abstract public void abandonCallAudioFocus();
|
||||
|
||||
public static AudioManagerCompat create(@NonNull Context context) {
|
||||
if (Build.VERSION.SDK_INT >= 26) {
|
||||
return new Api26AudioManagerCompat(context);
|
||||
} else if (Build.VERSION.SDK_INT >= 21) {
|
||||
return new Api21AudioManagerCompat(context);
|
||||
} else {
|
||||
return new Api19AudioManagerCompat(context);
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(26)
|
||||
private static class Api26AudioManagerCompat extends AudioManagerCompat {
|
||||
|
||||
private static AudioAttributes AUDIO_ATTRIBUTES = new AudioAttributes.Builder()
|
||||
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
|
||||
.setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
|
||||
.build();
|
||||
|
||||
private AudioFocusRequest audioFocusRequest;
|
||||
|
||||
private Api26AudioManagerCompat(@NonNull Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundPool createSoundPool() {
|
||||
return new SoundPool.Builder()
|
||||
.setAudioAttributes(AUDIO_ATTRIBUTES)
|
||||
.setMaxStreams(1)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestCallAudioFocus() {
|
||||
if (audioFocusRequest != null) {
|
||||
throw new IllegalStateException("Already focused.");
|
||||
}
|
||||
|
||||
audioFocusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT)
|
||||
.setAudioAttributes(AUDIO_ATTRIBUTES)
|
||||
.build();
|
||||
|
||||
int result = audioManager.requestAudioFocus(audioFocusRequest);
|
||||
|
||||
if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
|
||||
throw new IllegalStateException("Got " + result);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void abandonCallAudioFocus() {
|
||||
if (audioFocusRequest == null) {
|
||||
throw new IllegalStateException("Not focused.");
|
||||
}
|
||||
|
||||
int result = audioManager.abandonAudioFocusRequest(audioFocusRequest);
|
||||
|
||||
if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
|
||||
throw new IllegalStateException("Got " + result);
|
||||
}
|
||||
|
||||
audioFocusRequest = null;
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(21)
|
||||
private static class Api21AudioManagerCompat extends Api19AudioManagerCompat {
|
||||
|
||||
private static AudioAttributes AUDIO_ATTRIBUTES = new AudioAttributes.Builder()
|
||||
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
|
||||
.setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
|
||||
.setLegacyStreamType(AudioManager.STREAM_VOICE_CALL)
|
||||
.build();
|
||||
|
||||
private Api21AudioManagerCompat(@NonNull Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundPool createSoundPool() {
|
||||
return new SoundPool.Builder()
|
||||
.setAudioAttributes(AUDIO_ATTRIBUTES)
|
||||
.setMaxStreams(1)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
private static class Api19AudioManagerCompat extends AudioManagerCompat {
|
||||
|
||||
private Api19AudioManagerCompat(@NonNull Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundPool createSoundPool() {
|
||||
return new SoundPool(1, AudioManager.STREAM_VOICE_CALL, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestCallAudioFocus() {
|
||||
int result = audioManager.requestAudioFocus(null, AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
|
||||
|
||||
if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
|
||||
throw new IllegalStateException("Got " + result);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void abandonCallAudioFocus() {
|
||||
int result = audioManager.abandonAudioFocus(null);
|
||||
|
||||
if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
|
||||
throw new IllegalStateException("Got " + result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class BluetoothStateManager {
|
||||
|
||||
private static final String TAG = BluetoothStateManager.class.getSimpleName();
|
||||
private static final String TAG = Log.tag(BluetoothStateManager.class);
|
||||
|
||||
private enum ScoConnection {
|
||||
DISCONNECTED,
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.webrtc.audio;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.media.AudioAttributes;
|
||||
import android.media.AudioManager;
|
||||
import android.media.MediaPlayer;
|
||||
import android.net.Uri;
|
||||
@@ -109,7 +110,15 @@ public class IncomingRinger {
|
||||
mediaPlayer.setOnErrorListener(new MediaPlayerErrorListener());
|
||||
mediaPlayer.setDataSource(context, ringtoneUri);
|
||||
mediaPlayer.setLooping(true);
|
||||
mediaPlayer.setAudioStreamType(AudioManager.STREAM_RING);
|
||||
|
||||
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)
|
||||
.build());
|
||||
}
|
||||
|
||||
return mediaPlayer;
|
||||
} catch (IOException e) {
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
package org.thoughtcrime.securesms.webrtc.audio;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.AudioAttributes;
|
||||
import android.media.AudioManager;
|
||||
import android.media.MediaPlayer;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
|
||||
@@ -40,7 +43,15 @@ public class OutgoingRinger {
|
||||
}
|
||||
|
||||
mediaPlayer = new MediaPlayer();
|
||||
mediaPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);
|
||||
|
||||
if (Build.VERSION.SDK_INT <= 21) {
|
||||
mediaPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);
|
||||
} else {
|
||||
mediaPlayer.setAudioAttributes(new AudioAttributes.Builder()
|
||||
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
|
||||
.setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
|
||||
.build());
|
||||
}
|
||||
mediaPlayer.setLooping(true);
|
||||
|
||||
String packageName = context.getPackageName();
|
||||
|
||||
@@ -25,19 +25,21 @@ public class SignalAudioManager {
|
||||
private final int connectedSoundId;
|
||||
private final int disconnectedSoundId;
|
||||
|
||||
private final AudioManagerCompat audioManagerCompat;
|
||||
|
||||
public SignalAudioManager(@NonNull Context context) {
|
||||
this.context = context.getApplicationContext();
|
||||
this.incomingRinger = new IncomingRinger(context);
|
||||
this.outgoingRinger = new OutgoingRinger(context);
|
||||
this.soundPool = new SoundPool(1, AudioManager.STREAM_VOICE_CALL, 0);
|
||||
this.context = context.getApplicationContext();
|
||||
this.incomingRinger = new IncomingRinger(context);
|
||||
this.outgoingRinger = new OutgoingRinger(context);
|
||||
this.audioManagerCompat = AudioManagerCompat.create(context);
|
||||
this.soundPool = audioManagerCompat.createSoundPool();
|
||||
|
||||
this.connectedSoundId = this.soundPool.load(context, R.raw.webrtc_completed, 1);
|
||||
this.disconnectedSoundId = this.soundPool.load(context, R.raw.webrtc_disconnected, 1);
|
||||
}
|
||||
|
||||
public void initializeAudioForCall() {
|
||||
AudioManager audioManager = ServiceUtil.getAudioManager(context);
|
||||
audioManager.requestAudioFocus(null, AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE);
|
||||
audioManagerCompat.requestCallAudioFocus();
|
||||
}
|
||||
|
||||
public void startIncomingRinger(@Nullable Uri ringtoneUri, boolean vibrate) {
|
||||
@@ -89,14 +91,8 @@ public class SignalAudioManager {
|
||||
soundPool.play(disconnectedSoundId, 1.0f, 1.0f, 0, 0, 1.0f);
|
||||
}
|
||||
|
||||
if (audioManager.isBluetoothScoOn()) {
|
||||
audioManager.setBluetoothScoOn(false);
|
||||
audioManager.stopBluetoothSco();
|
||||
}
|
||||
|
||||
audioManager.setSpeakerphoneOn(false);
|
||||
audioManager.setMicrophoneMute(false);
|
||||
audioManager.setMode(AudioManager.MODE_NORMAL);
|
||||
audioManager.abandonAudioFocus(null);
|
||||
|
||||
audioManagerCompat.abandonCallAudioFocus();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user