refactor: more bluetooth improvements
This commit is contained in:
parent
787fefc237
commit
644213ea32
|
@ -155,8 +155,8 @@ dependencies {
|
|||
testImplementation 'org.robolectric:shadows-multidex:4.4'
|
||||
}
|
||||
|
||||
def canonicalVersionCode = 236
|
||||
def canonicalVersionName = "1.12.0-ALPHA3"
|
||||
def canonicalVersionCode = 237
|
||||
def canonicalVersionName = "1.12.0-ALPHA4"
|
||||
|
||||
def postFixSize = 10
|
||||
def abiPostFix = ['armeabi-v7a' : 1,
|
||||
|
@ -246,6 +246,7 @@ android {
|
|||
buildTypes {
|
||||
release {
|
||||
signingConfig signingConfigs.release
|
||||
debuggable true
|
||||
minifyEnabled false
|
||||
}
|
||||
debug {
|
||||
|
|
|
@ -176,6 +176,7 @@ class WebRtcCallService: Service(), CallManager.WebRtcListener {
|
|||
@Synchronized
|
||||
private fun terminate() {
|
||||
sendBroadcast(Intent(WebRtcCallActivity.ACTION_END))
|
||||
lockManager.updatePhoneState(LockManager.PhoneState.IDLE)
|
||||
callManager.stop()
|
||||
stopForeground(true)
|
||||
}
|
||||
|
@ -377,7 +378,7 @@ class WebRtcCallService: Service(), CallManager.WebRtcListener {
|
|||
callManager.startOutgoingRinger(OutgoingRinger.Type.RINGING)
|
||||
setCallInProgressNotification(TYPE_OUTGOING_RINGING, callManager.recipient)
|
||||
callManager.insertCallMessage(recipient.address.serialize(), CallMessageType.CALL_OUTGOING)
|
||||
timeoutExecutor.schedule(TimeoutRunnable(callId, this), 2, TimeUnit.MINUTES)
|
||||
timeoutExecutor.schedule(TimeoutRunnable(callId, this), 1, TimeUnit.MINUTES)
|
||||
|
||||
val expectedState = callManager.currentConnectionState
|
||||
val expectedCallId = callManager.callId
|
||||
|
@ -425,7 +426,7 @@ class WebRtcCallService: Service(), CallManager.WebRtcListener {
|
|||
return
|
||||
}
|
||||
|
||||
timeoutExecutor.schedule(TimeoutRunnable(callId, this), 2, TimeUnit.MINUTES)
|
||||
timeoutExecutor.schedule(TimeoutRunnable(callId, this), 1, TimeUnit.MINUTES)
|
||||
|
||||
callManager.initializeAudioForCall()
|
||||
callManager.initializeVideo(this)
|
||||
|
@ -490,11 +491,6 @@ class WebRtcCallService: Service(), CallManager.WebRtcListener {
|
|||
callManager.handleSetCameraFlip()
|
||||
}
|
||||
|
||||
private fun handleBluetoothChange(intent: Intent) {
|
||||
val bluetoothAvailable = intent.getBooleanExtra(EXTRA_AVAILABLE, false)
|
||||
callManager.postBluetoothAvailable(bluetoothAvailable)
|
||||
}
|
||||
|
||||
private fun handleWiredHeadsetChanged(intent: Intent) {
|
||||
callManager.handleWiredHeadsetChanged(intent.getBooleanExtra(EXTRA_AVAILABLE, false))
|
||||
}
|
||||
|
@ -611,6 +607,7 @@ class WebRtcCallService: Service(), CallManager.WebRtcListener {
|
|||
System.currentTimeMillis() - intent.getLongExtra(EXTRA_TIMESTAMP, -1) > TimeUnit.MINUTES.toMillis(2)
|
||||
|
||||
override fun onDestroy() {
|
||||
Log.d(TAG,"onDestroy()")
|
||||
callManager.unregisterListener(this)
|
||||
callReceiver?.let { receiver ->
|
||||
unregisterReceiver(receiver)
|
||||
|
@ -621,7 +618,6 @@ class WebRtcCallService: Service(), CallManager.WebRtcListener {
|
|||
networkChangedReceiver = null
|
||||
callReceiver = null
|
||||
uncaughtExceptionHandlerManager?.unregister()
|
||||
callManager.onDestroy()
|
||||
super.onDestroy()
|
||||
// shutdown audiomanager
|
||||
// unregister network receiver
|
||||
|
|
|
@ -10,9 +10,6 @@ open class AudioManagerCommand: Parcelable {
|
|||
@Parcelize
|
||||
object Initialize: AudioManagerCommand()
|
||||
|
||||
@Parcelize
|
||||
object Shutdown: AudioManagerCommand()
|
||||
|
||||
@Parcelize
|
||||
object UpdateAudioDeviceState: AudioManagerCommand()
|
||||
|
||||
|
|
|
@ -309,8 +309,6 @@ class CallManager(context: Context, audioManager: AudioManagerCompat, private va
|
|||
} else if (json.containsKey("hangup")) {
|
||||
peerConnectionObservers.forEach(WebRtcListener::onHangup)
|
||||
}
|
||||
val videoEnabled = Json.decodeFromString(VideoEnabledMessage.serializer(), byteArray.decodeToString())
|
||||
_remoteVideoEvents.value = VideoEnabled(videoEnabled.video)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Failed to deserialize data channel message", e)
|
||||
}
|
||||
|
@ -519,7 +517,8 @@ class CallManager(context: Context, audioManager: AudioManagerCompat, private va
|
|||
|
||||
fun handleSetMuteVideo(muted: Boolean, lockManager: LockManager) {
|
||||
_videoEvents.value = VideoEnabled(!muted)
|
||||
peerConnection?.setVideoEnabled(!muted)
|
||||
val connection = peerConnection ?: return
|
||||
connection.setVideoEnabled(!muted)
|
||||
dataChannel?.let { channel ->
|
||||
val toSend = if (muted) VIDEO_DISABLED_JSON else VIDEO_ENABLED_JSON
|
||||
val buffer = DataChannel.Buffer(ByteBuffer.wrap(toSend.toString().encodeToByteArray()), false)
|
||||
|
@ -527,7 +526,7 @@ class CallManager(context: Context, audioManager: AudioManagerCompat, private va
|
|||
}
|
||||
|
||||
if (currentConnectionState == CallState.STATE_CONNECTED) {
|
||||
if (localCameraState.enabled) lockManager.updatePhoneState(LockManager.PhoneState.IN_VIDEO)
|
||||
if (connection.isVideoEnabled()) lockManager.updatePhoneState(LockManager.PhoneState.IN_VIDEO)
|
||||
else lockManager.updatePhoneState(LockManager.PhoneState.IN_CALL)
|
||||
}
|
||||
|
||||
|
@ -548,10 +547,6 @@ class CallManager(context: Context, audioManager: AudioManagerCompat, private va
|
|||
}
|
||||
}
|
||||
|
||||
fun postBluetoothAvailable(available: Boolean) {
|
||||
// TODO: _bluetoothEnabled.value = available
|
||||
}
|
||||
|
||||
fun handleWiredHeadsetChanged(present: Boolean) {
|
||||
if (currentConnectionState in arrayOf(CallState.STATE_CONNECTED,
|
||||
CallState.STATE_DIALING,
|
||||
|
@ -601,10 +596,6 @@ class CallManager(context: Context, audioManager: AudioManagerCompat, private va
|
|||
}
|
||||
}
|
||||
|
||||
fun onDestroy() {
|
||||
signalAudioManager.handleCommand(AudioManagerCommand.Shutdown)
|
||||
}
|
||||
|
||||
fun startIncomingRinger() {
|
||||
signalAudioManager.handleCommand(AudioManagerCommand.StartIncomingRinger(true))
|
||||
}
|
||||
|
@ -612,7 +603,7 @@ class CallManager(context: Context, audioManager: AudioManagerCompat, private va
|
|||
fun startCommunication(lockManager: LockManager) {
|
||||
signalAudioManager.handleCommand(AudioManagerCommand.Start)
|
||||
val connection = peerConnection ?: return
|
||||
if (localCameraState.enabled) lockManager.updatePhoneState(LockManager.PhoneState.IN_VIDEO)
|
||||
if (connection.isVideoEnabled()) lockManager.updatePhoneState(LockManager.PhoneState.IN_VIDEO)
|
||||
else lockManager.updatePhoneState(LockManager.PhoneState.IN_CALL)
|
||||
connection.setCommunicationMode()
|
||||
setAudioEnabled(true)
|
||||
|
@ -649,9 +640,6 @@ class CallManager(context: Context, audioManager: AudioManagerCompat, private va
|
|||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class VideoEnabledMessage(val video: Boolean)
|
||||
|
||||
interface WebRtcListener: PeerConnection.Observer {
|
||||
fun onHangup()
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ class PeerConnectionWrapper(context: Context,
|
|||
private val videoTrack: VideoTrack?
|
||||
|
||||
val readyForIce
|
||||
get() = peerConnection.localDescription != null && peerConnection.remoteDescription != null
|
||||
get() = peerConnection.localDescription != null && peerConnection.remoteDescription != null
|
||||
|
||||
init {
|
||||
val turn = PeerConnection.IceServer.builder("turn:freyr.getsession.org").setUsername("session").setPassword("session").createIceServer()
|
||||
|
@ -269,6 +269,8 @@ class PeerConnectionWrapper(context: Context,
|
|||
}
|
||||
}
|
||||
|
||||
fun isVideoEnabled() = camera.enabled
|
||||
|
||||
fun flipCamera() {
|
||||
camera.flip()
|
||||
}
|
||||
|
|
|
@ -17,6 +17,9 @@ class IncomingRinger(private val context: Context) {
|
|||
private val vibrator: Vibrator? = ServiceUtil.getVibrator(context)
|
||||
var mediaPlayer: MediaPlayer? = null
|
||||
|
||||
val isRinging: Boolean
|
||||
get() = mediaPlayer?.isPlaying ?: false
|
||||
|
||||
fun start(vibrate: Boolean) {
|
||||
val audioManager = ServiceUtil.getAudioManager(context)
|
||||
mediaPlayer?.release()
|
||||
|
@ -31,16 +34,14 @@ class IncomingRinger(private val context: Context) {
|
|||
}
|
||||
|
||||
mediaPlayer?.let { player ->
|
||||
if (ringerMode == AudioManager.RINGER_MODE_NORMAL) {
|
||||
try {
|
||||
if (!player.isPlaying) {
|
||||
player.prepare()
|
||||
player.start()
|
||||
Log.i(TAG,"Playing ringtone")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG,"Failed to start mediaPlayer", e)
|
||||
try {
|
||||
if (!player.isPlaying) {
|
||||
player.prepare()
|
||||
player.start()
|
||||
Log.i(TAG,"Playing ringtone")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG,"Failed to start mediaPlayer", e)
|
||||
}
|
||||
} ?: run {
|
||||
Log.w(TAG,"Not ringing, mediaPlayer: ${mediaPlayer?.let{"available"}}, mode: $ringerMode")
|
||||
|
|
|
@ -11,6 +11,7 @@ import android.os.HandlerThread
|
|||
import network.loki.messenger.R
|
||||
import org.session.libsignal.utilities.Log
|
||||
import org.thoughtcrime.securesms.webrtc.AudioManagerCommand
|
||||
import org.thoughtcrime.securesms.webrtc.audio.SignalBluetoothManager.State as BState
|
||||
|
||||
private val TAG = Log.tag(SignalAudioManager::class.java)
|
||||
|
||||
|
@ -68,7 +69,6 @@ class SignalAudioManager(private val context: Context,
|
|||
}
|
||||
handler?.post {
|
||||
when (command) {
|
||||
is AudioManagerCommand.Shutdown -> shutdown()
|
||||
is AudioManagerCommand.UpdateAudioDeviceState -> updateAudioDeviceState()
|
||||
is AudioManagerCommand.Start -> start()
|
||||
is AudioManagerCommand.Stop -> stop(command.playDisconnect)
|
||||
|
@ -144,15 +144,23 @@ class SignalAudioManager(private val context: Context,
|
|||
return
|
||||
}
|
||||
|
||||
incomingRinger.stop()
|
||||
outgoingRinger.stop()
|
||||
handler?.post {
|
||||
incomingRinger.stop()
|
||||
outgoingRinger.stop()
|
||||
stop(false)
|
||||
if (commandAndControlThread != null) {
|
||||
Log.i(TAG, "Shutting down command and control")
|
||||
commandAndControlThread?.quitSafely()
|
||||
commandAndControlThread = null
|
||||
}
|
||||
}
|
||||
|
||||
if (playDisconnect) {
|
||||
val volume: Float = androidAudioManager.ringVolumeWithMinimum()
|
||||
soundPool.play(disconnectedSoundId, volume, volume, 0, 0, 1.0f)
|
||||
}
|
||||
|
||||
state = State.PREINITIALIZED
|
||||
state = State.UNINITIALIZED
|
||||
|
||||
wiredHeadsetReceiver?.let { receiver ->
|
||||
try {
|
||||
|
@ -175,19 +183,6 @@ class SignalAudioManager(private val context: Context,
|
|||
Log.d(TAG, "Stopped")
|
||||
}
|
||||
|
||||
private fun shutdown() {
|
||||
handler?.post {
|
||||
incomingRinger.stop()
|
||||
outgoingRinger.stop()
|
||||
stop(false)
|
||||
if (commandAndControlThread != null) {
|
||||
Log.i(TAG, "Shutting down command and control")
|
||||
commandAndControlThread?.quitSafely()
|
||||
commandAndControlThread = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateAudioDeviceState() {
|
||||
handler!!.assertHandlerThread()
|
||||
|
||||
|
@ -223,7 +218,7 @@ class SignalAudioManager(private val context: Context,
|
|||
var audioDeviceSetUpdated = audioDevices != newAudioDevices
|
||||
audioDevices = newAudioDevices
|
||||
|
||||
if (signalBluetoothManager!!.state == SignalBluetoothManager.State.UNAVAILABLE && userSelectedAudioDevice == AudioDevice.BLUETOOTH) {
|
||||
if (signalBluetoothManager!!.state == BState.UNAVAILABLE && userSelectedAudioDevice == AudioDevice.BLUETOOTH) {
|
||||
userSelectedAudioDevice = AudioDevice.NONE
|
||||
}
|
||||
|
||||
|
@ -236,13 +231,14 @@ class SignalAudioManager(private val context: Context,
|
|||
userSelectedAudioDevice = AudioDevice.NONE
|
||||
}
|
||||
|
||||
val needBluetoothAudioStart = signalBluetoothManager!!.state == SignalBluetoothManager.State.AVAILABLE && signalBluetoothManager!!.state != SignalBluetoothManager.State.CONNECTING
|
||||
val btState = signalBluetoothManager!!.state
|
||||
val needBluetoothAudioStart = btState == BState.AVAILABLE &&
|
||||
(userSelectedAudioDevice == AudioDevice.NONE || userSelectedAudioDevice == AudioDevice.BLUETOOTH || autoSwitchToBluetooth)
|
||||
|
||||
val needBluetoothAudioStop = (signalBluetoothManager!!.state == SignalBluetoothManager.State.CONNECTED || signalBluetoothManager!!.state != SignalBluetoothManager.State.CONNECTING) &&
|
||||
val needBluetoothAudioStop = (btState == BState.CONNECTED || btState == BState.CONNECTING) &&
|
||||
(userSelectedAudioDevice != AudioDevice.NONE && userSelectedAudioDevice != AudioDevice.BLUETOOTH)
|
||||
|
||||
if (signalBluetoothManager!!.state.hasDevice()) {
|
||||
if (btState.hasDevice()) {
|
||||
Log.i(TAG, "Need bluetooth audio: state: ${signalBluetoothManager!!.state} start: $needBluetoothAudioStart stop: $needBluetoothAudioStop")
|
||||
}
|
||||
|
||||
|
@ -251,18 +247,19 @@ class SignalAudioManager(private val context: Context,
|
|||
signalBluetoothManager!!.updateDevice()
|
||||
}
|
||||
|
||||
if (!autoSwitchToBluetooth && signalBluetoothManager!!.state == SignalBluetoothManager.State.UNAVAILABLE) {
|
||||
if (!autoSwitchToBluetooth && signalBluetoothManager!!.state == BState.UNAVAILABLE) {
|
||||
autoSwitchToBluetooth = true
|
||||
}
|
||||
|
||||
if (needBluetoothAudioStart && !needBluetoothAudioStop) {
|
||||
if (!signalBluetoothManager!!.startScoAudio()) {
|
||||
Log.e(TAG,"Failed to start sco audio")
|
||||
audioDevices.remove(AudioDevice.BLUETOOTH)
|
||||
audioDeviceSetUpdated = true
|
||||
}
|
||||
}
|
||||
|
||||
if (autoSwitchToBluetooth && signalBluetoothManager!!.state == SignalBluetoothManager.State.CONNECTED) {
|
||||
if (autoSwitchToBluetooth && signalBluetoothManager!!.state == BState.CONNECTED) {
|
||||
userSelectedAudioDevice = AudioDevice.BLUETOOTH
|
||||
autoSwitchToBluetooth = false
|
||||
}
|
||||
|
@ -342,7 +339,6 @@ class SignalAudioManager(private val context: Context,
|
|||
private fun startIncomingRinger(vibrate: Boolean) {
|
||||
Log.i(TAG, "startIncomingRinger(): vibrate: $vibrate")
|
||||
androidAudioManager.mode = AudioManager.MODE_RINGTONE
|
||||
setDefaultAudioDevice(AudioDevice.SPEAKER_PHONE, false)
|
||||
|
||||
incomingRinger.start(vibrate)
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import android.content.BroadcastReceiver
|
|||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.media.AudioManager
|
||||
import org.session.libsignal.utilities.Log
|
||||
import org.thoughtcrime.securesms.webrtc.AudioManagerCommand
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
@ -73,7 +74,7 @@ class SignalBluetoothManager(
|
|||
|
||||
val bluetoothHeadsetFilter = IntentFilter().apply {
|
||||
addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)
|
||||
addAction(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)
|
||||
addAction(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED)
|
||||
}
|
||||
|
||||
bluetoothReceiver = BluetoothHeadsetBroadcastReceiver()
|
||||
|
@ -134,7 +135,6 @@ class SignalBluetoothManager(
|
|||
|
||||
state = State.CONNECTING
|
||||
androidAudioManager.startBluetoothSco()
|
||||
androidAudioManager.isBluetoothScoOn = true
|
||||
scoConnectionAttempts++
|
||||
startTimer()
|
||||
|
||||
|
@ -165,7 +165,7 @@ class SignalBluetoothManager(
|
|||
return
|
||||
}
|
||||
|
||||
if (bluetoothAdapter!!.getProfileConnectionState(BluetoothProfile.HEADSET) !in arrayOf(BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_CONNECTED)) {
|
||||
if (bluetoothAdapter!!.getProfileConnectionState(BluetoothProfile.HEADSET) !in arrayOf(BluetoothProfile.STATE_CONNECTED)) {
|
||||
state = State.UNAVAILABLE
|
||||
Log.i(TAG, "No connected bluetooth headset")
|
||||
} else {
|
||||
|
@ -216,6 +216,7 @@ class SignalBluetoothManager(
|
|||
|
||||
private fun onServiceConnected(proxy: BluetoothHeadset?) {
|
||||
bluetoothHeadset = proxy
|
||||
androidAudioManager.isBluetoothScoOn = true
|
||||
updateAudioDeviceState()
|
||||
}
|
||||
|
||||
|
@ -244,9 +245,9 @@ class SignalBluetoothManager(
|
|||
private fun onAudioStateChanged(audioState: Int, isInitialStateChange: Boolean) {
|
||||
Log.i(TAG, "onAudioStateChanged: state: $state audioState: ${audioState.toStateString()} initialSticky: $isInitialStateChange")
|
||||
|
||||
if (audioState == BluetoothHeadset.STATE_AUDIO_CONNECTED) {
|
||||
if (audioState == AudioManager.SCO_AUDIO_STATE_CONNECTED) {
|
||||
cancelTimer()
|
||||
if (state === State.CONNECTING) {
|
||||
if (state == State.CONNECTING) {
|
||||
Log.d(TAG, "Bluetooth audio SCO is now connected")
|
||||
state = State.CONNECTED
|
||||
scoConnectionAttempts = 0
|
||||
|
@ -254,9 +255,9 @@ class SignalBluetoothManager(
|
|||
} else {
|
||||
Log.w(TAG, "Unexpected state ${audioState.toStateString()}")
|
||||
}
|
||||
} else if (audioState == BluetoothHeadset.STATE_AUDIO_CONNECTING) {
|
||||
} else if (audioState == AudioManager.SCO_AUDIO_STATE_CONNECTING) {
|
||||
Log.d(TAG, "Bluetooth audio SCO is now connecting...")
|
||||
} else if (audioState == BluetoothHeadset.STATE_AUDIO_DISCONNECTED) {
|
||||
} else if (audioState == AudioManager.SCO_AUDIO_STATE_DISCONNECTED) {
|
||||
Log.d(TAG, "Bluetooth audio SCO is now disconnected")
|
||||
if (isInitialStateChange) {
|
||||
Log.d(TAG, "Ignore ${audioState.toStateString()} initial sticky broadcast.")
|
||||
|
@ -298,10 +299,17 @@ class SignalBluetoothManager(
|
|||
}
|
||||
}
|
||||
} else if (intent.action == BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED) {
|
||||
val connectionState: Int = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, BluetoothHeadset.STATE_AUDIO_DISCONNECTED)
|
||||
// val connectionState: Int = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, BluetoothHeadset.STATE_AUDIO_DISCONNECTED)
|
||||
// handler.post {
|
||||
// if (state != State.UNINITIALIZED) {
|
||||
// onAudioStateChanged(connectionState, isInitialStickyBroadcast)
|
||||
// }
|
||||
// }
|
||||
} else if (intent.action == AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED) {
|
||||
val scoState: Int = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, AudioManager.ERROR)
|
||||
handler.post {
|
||||
if (state != State.UNINITIALIZED) {
|
||||
onAudioStateChanged(connectionState, isInitialStickyBroadcast)
|
||||
onAudioStateChanged(scoState, isInitialStickyBroadcast)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -346,3 +354,11 @@ private fun Int.toStateString(): String {
|
|||
else -> "UNKNOWN"
|
||||
}
|
||||
}
|
||||
|
||||
private fun Int.toScoString(): String = when (this) {
|
||||
AudioManager.SCO_AUDIO_STATE_DISCONNECTED -> "DISCONNECTED"
|
||||
AudioManager.SCO_AUDIO_STATE_CONNECTED -> "CONNECTED"
|
||||
AudioManager.SCO_AUDIO_STATE_CONNECTING -> "CONNECTING"
|
||||
AudioManager.SCO_AUDIO_STATE_ERROR -> "ERROR"
|
||||
else -> "UNKNOWN"
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue