Fix bluetooth behavior.

This commit is contained in:
Alex Hart
2020-05-28 17:36:40 -03:00
committed by GitHub
parent 6b47618351
commit cd1bad0718
8 changed files with 188 additions and 39 deletions

View File

@@ -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);
}
}
}
}

View File

@@ -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,

View File

@@ -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) {

View File

@@ -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();

View File

@@ -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();
}
}