feat: adding remainder of basic functionality to services and CallManager.kt

This commit is contained in:
jubb
2021-11-05 16:35:40 +11:00
parent f069d35b14
commit 3755315b4c
13 changed files with 165 additions and 286 deletions

View File

@@ -141,10 +141,6 @@ public class ApplicationContext extends Application implements DefaultLifecycleO
return (ApplicationContext) context.getApplicationContext();
}
public CallComponent getCallComponent() {
return EntryPoints.get(getApplicationContext(), CallComponent.class);
}
public DatabaseComponent getDatabaseComponent() {
return EntryPoints.get(getApplicationContext(), DatabaseComponent.class);
}

View File

@@ -43,10 +43,6 @@ class WebRtcCallActivity: PassphraseRequiredActionBarActivity() {
const val ACTION_ANSWER = "answer"
const val ACTION_END = "end-call"
const val EXTRA_SDP = "WebRtcTestsActivity_EXTRA_SDP"
const val EXTRA_ADDRESS = "WebRtcTestsActivity_EXTRA_ADDRESS"
const val EXTRA_CALL_ID = "WebRtcTestsActivity_EXTRA_CALL_ID"
const val BUSY_SIGNAL_DELAY_FINISH = 5500L
}
@@ -59,13 +55,9 @@ class WebRtcCallActivity: PassphraseRequiredActionBarActivity() {
private lateinit var callAddress: Address
private lateinit var callId: UUID
override fun onBackPressed() {
endCall()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == android.R.id.home) {
endCall()
finish()
return true
}
return super.onOptionsItemSelected(item)
@@ -94,227 +86,19 @@ class WebRtcCallActivity: PassphraseRequiredActionBarActivity() {
}
}
local_renderer.run {
setEnableHardwareScaler(true)
init(eglBase.eglBaseContext, null)
}
remote_renderer.run {
setEnableHardwareScaler(true)
init(eglBase.eglBaseContext, null)
}
end_call_button.setOnClickListener {
endCall()
}
switch_camera_button.setOnClickListener {
videoCapturer?.switchCamera(null)
}
switch_audio_button.setOnClickListener {
}
// create either call or answer
callId = intent.getStringExtra(EXTRA_CALL_ID).let(UUID::fromString)
if (intent.action == ACTION_ANSWER) {
callAddress = intent.getParcelableExtra(EXTRA_ADDRESS) ?: run { finish(); return }
val offerSdp = intent.getStringArrayExtra(EXTRA_SDP)!![0]
peerConnection.setRemoteDescription(this, SessionDescription(SessionDescription.Type.OFFER, offerSdp))
peerConnection.createAnswer(this, MediaConstraints())
} else {
callAddress = intent.getParcelableExtra(EXTRA_ADDRESS) ?: run { finish(); return }
peerConnection.createOffer(this, MediaConstraints())
}
lifecycleScope.launchWhenCreated {
while (this.isActive) {
val answer = synchronized(WebRtcUtils.callCache) {
WebRtcUtils.callCache[callId]?.firstOrNull { it.type == SignalServiceProtos.CallMessage.Type.ANSWER }
}
if (answer != null) {
peerConnection.setRemoteDescription(
this@WebRtcCallActivity,
SessionDescription(SessionDescription.Type.ANSWER, answer.sdps[0])
)
break
}
delay(2_000L)
}
}
registerReceiver(object: BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
endCall()
finish()
}
}, IntentFilter(ACTION_END))
lifecycleScope.launchWhenResumed {
while (this.isActive) {
delay(2_000L)
peerConnection.getStats(this@WebRtcCallActivity)
synchronized(WebRtcUtils.callCache) {
val set = WebRtcUtils.callCache[callId] ?: mutableSetOf()
set.filter { it.hashCode() !in acceptedCallMessageHashes
&& it.type == SignalServiceProtos.CallMessage.Type.ICE_CANDIDATES }.forEach { callMessage ->
callMessage.iceCandidates().forEach { candidate ->
peerConnection.addIceCandidate(candidate)
}
acceptedCallMessageHashes.add(callMessage.hashCode())
}
}
}
}
}
private fun initializeResources() {
}
private fun endCall() {
if (isFinishing) return
val uuid = callId
MessageSender.sendNonDurably(
CallMessage.endCall(uuid),
callAddress
)
peerConnection.close()
finish()
}
override fun onDestroy() {
super.onDestroy()
endCall()
}
private fun setupStreams() {
val videoSource = connectionFactory.createVideoSource(false)
videoCapturer?.initialize(surfaceHelper, local_renderer.context, videoSource.capturerObserver) ?: run {
finish()
return
}
videoCapturer?.startCapture(HD_VIDEO_WIDTH, HD_VIDEO_HEIGHT, 10)
val audioTrack = connectionFactory.createAudioTrack(LOCAL_TRACK_ID + "_audio", audioSource)
val videoTrack = connectionFactory.createVideoTrack(LOCAL_TRACK_ID, videoSource)
videoTrack.addSink(local_renderer)
val stream = connectionFactory.createLocalMediaStream(LOCAL_STREAM_ID)
stream.addTrack(videoTrack)
stream.addTrack(audioTrack)
peerConnection.addStream(stream)
}
override fun onSignalingChange(p0: PeerConnection.SignalingState?) {
Log.d("Loki-RTC", "onSignalingChange: $p0")
}
override fun onIceConnectionChange(p0: PeerConnection.IceConnectionState?) {
Log.d("Loki-RTC", "onIceConnectionChange: $p0")
}
override fun onIceConnectionReceivingChange(p0: Boolean) {
Log.d("Loki-RTC", "onIceConnectionReceivingChange: $p0")
}
override fun onIceGatheringChange(p0: PeerConnection.IceGatheringState?) {
Log.d("Loki-RTC", "onIceGatheringChange: $p0")
}
override fun onIceCandidate(iceCandidate: IceCandidate?) {
Log.d("Loki-RTC", "onIceCandidate: $iceCandidate")
if (iceCandidate == null) return
// TODO: in a lokinet world, these might have to be filtered specifically to drop anything that is not .loki
peerConnection.addIceCandidate(iceCandidate)
candidates.add(iceCandidate)
iceDebouncer.publish {
MessageSender.sendNonDurably(
CallMessage(SignalServiceProtos.CallMessage.Type.ICE_CANDIDATES,
candidates.map { it.sdp },
candidates.map { it.sdpMLineIndex },
candidates.map { it.sdpMid },
callId
),
callAddress
)
}
}
override fun onIceCandidatesRemoved(p0: Array<out IceCandidate>?) {
Log.d("Loki-RTC", "onIceCandidatesRemoved: $p0")
peerConnection.removeIceCandidates(p0)
}
override fun onAddStream(remoteStream: MediaStream?) {
Log.d("Loki-RTC", "onAddStream: $remoteStream")
if (remoteStream == null) {
return
}
remoteStream.videoTracks.firstOrNull()?.addSink(remote_renderer)
}
override fun onRemoveStream(p0: MediaStream?) {
Log.d("Loki-RTC", "onRemoveStream: $p0")
}
override fun onDataChannel(p0: DataChannel?) {
Log.d("Loki-RTC", "onDataChannel: $p0")
}
override fun onRenegotiationNeeded() {
Log.d("Loki-RTC", "onRenegotiationNeeded")
}
override fun onAddTrack(p0: RtpReceiver?, p1: Array<out MediaStream>?) {
Log.d("Loki-RTC", "onAddTrack: $p0: $p1")
}
override fun onCreateSuccess(sdp: SessionDescription) {
Log.d("Loki-RTC", "onCreateSuccess: ${sdp.type}")
when (sdp.type) {
SessionDescription.Type.OFFER -> {
peerConnection.setLocalDescription(this, sdp)
MessageSender.sendNonDurably(
CallMessage(SignalServiceProtos.CallMessage.Type.OFFER,
listOf(sdp.description),
listOf(),
listOf(),
callId
),
callAddress
)
}
SessionDescription.Type.ANSWER -> {
peerConnection.setLocalDescription(this, sdp)
MessageSender.sendNonDurably(
CallMessage(SignalServiceProtos.CallMessage.Type.ANSWER,
listOf(sdp.description),
listOf(),
listOf(),
callId
),
callAddress
)
}
null, SessionDescription.Type.PRANSWER -> TODO("do the PR answer create success handling") // MessageSender.send()
}
}
override fun onSetSuccess() {
Log.d("Loki-RTC", "onSetSuccess")
}
override fun onCreateFailure(p0: String?) {
Log.d("Loki-RTC", "onCreateFailure: $p0")
}
override fun onSetFailure(p0: String?) {
Log.d("Loki-RTC", "onSetFailure: $p0")
}
}

View File

@@ -187,17 +187,10 @@ object ConversationMenuHelper {
.setTitle("Call")
.setMessage("Use relay?")
.setPositiveButton("Use Relay") { d, w ->
val intent = Intent(context, WebRtcCallActivity::class.java)
intent.putExtra(WebRtcCallActivity.EXTRA_CALL_ID, UUID.randomUUID().toString())
intent.putExtra(WebRtcCallActivity.EXTRA_ADDRESS, thread.address)
val activity = context as AppCompatActivity
activity.startActivity(intent)
TODO()
}
.setNeutralButton("P2P only") { d, w ->
val intent = Intent(context, WebRtcCallActivity::class.java)
intent.putExtra(WebRtcCallActivity.EXTRA_ADDRESS, thread.address)
val activity = context as AppCompatActivity
activity.startActivity(intent)
TODO()
}
.show()
}

View File

@@ -5,19 +5,19 @@ import dagger.Binds
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ServiceComponent
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.android.scopes.ServiceScoped
import dagger.hilt.components.SingletonComponent
import org.session.libsession.database.CallDataProvider
import org.thoughtcrime.securesms.database.Storage
import org.thoughtcrime.securesms.webrtc.CallManager
import org.thoughtcrime.securesms.webrtc.audio.AudioManagerCompat
import org.thoughtcrime.securesms.webrtc.audio.SignalAudioManager
import org.thoughtcrime.securesms.webrtc.data.SessionCallDataProvider
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
abstract class CallModule {
object CallModule {
@Provides
@Singleton
@@ -25,11 +25,7 @@ abstract class CallModule {
@Provides
@Singleton
fun provideCallManager(@ApplicationContext context: Context, storage: Storage, audioManagerCompat: AudioManagerCompat) =
fun provideCallManager(@ApplicationContext context: Context, audioManagerCompat: AudioManagerCompat) =
CallManager(context, audioManagerCompat)
@Binds
@Singleton
abstract fun bindCallDataProvider(sessionCallDataProvider: SessionCallDataProvider): CallDataProvider
}

View File

@@ -14,7 +14,6 @@ import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider
import org.thoughtcrime.securesms.crypto.DatabaseSecretProvider
import org.thoughtcrime.securesms.database.*
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper
import org.thoughtcrime.securesms.webrtc.data.SessionCallDataProvider
import javax.inject.Singleton
@Module

View File

@@ -28,7 +28,8 @@ import org.thoughtcrime.securesms.webrtc.*
import org.thoughtcrime.securesms.webrtc.CallManager.CallState.*
import org.thoughtcrime.securesms.webrtc.audio.OutgoingRinger
import org.thoughtcrime.securesms.webrtc.locks.LockManager
import org.webrtc.SessionDescription
import org.webrtc.*
import org.webrtc.PeerConnection.IceConnectionState.*
import java.lang.AssertionError
import java.util.*
import java.util.concurrent.ExecutionException
@@ -37,7 +38,7 @@ import java.util.concurrent.TimeUnit
import javax.inject.Inject
@AndroidEntryPoint
class WebRtcCallService: Service() {
class WebRtcCallService: Service(), PeerConnection.Observer {
@Inject lateinit var callManager: CallManager
@@ -62,7 +63,6 @@ class WebRtcCallService: Service() {
const val ACTION_RESPONSE_MESSAGE = "RESPONSE_MESSAGE"
const val ACTION_ICE_MESSAGE = "ICE_MESSAGE"
const val ACTION_ICE_CANDIDATE = "ICE_CANDIDATE"
const val ACTION_CALL_CONNECTED = "CALL_CONNECTED"
const val ACTION_REMOTE_HANGUP = "REMOTE_HANGUP"
const val ACTION_REMOTE_BUSY = "REMOTE_BUSY"
@@ -118,6 +118,7 @@ class WebRtcCallService: Service() {
private var callReceiver: IncomingPstnCallReceiver? = null
private var wiredHeadsetStateReceiver: WiredHeadsetStateReceiver? = null
private var uncaughtExceptionHandlerManager: UncaughtExceptionHandlerManager? = null
@Synchronized
private fun terminate() {
@@ -155,7 +156,7 @@ class WebRtcCallService: Service() {
action == ACTION_REMOTE_VIDEO_MUTE -> handleRemoteVideoMute(intent)
action == ACTION_RESPONSE_MESSAGE -> handleResponseMessage(intent)
action == ACTION_ICE_MESSAGE -> handleRemoteIceCandidate(intent)
action == ACTION_ICE_CANDIDATE -> handleLocalIceCandidate(intent)
action == ACTION_ICE_CONNECTED -> handleIceConnected(intent)
action == ACTION_CALL_CONNECTED -> handleCallConnected(intent)
action == ACTION_CHECK_TIMEOUT -> handleCheckTimeout(intent)
action == ACTION_IS_IN_CALL_QUERY -> handleIsInCallQuery(intent)
@@ -166,15 +167,18 @@ class WebRtcCallService: Service() {
override fun onCreate() {
super.onCreate()
// create audio manager
callManager.registerListener(this)
registerIncomingPstnCallReceiver()
registerWiredHeadsetStateReceiver()
getSystemService(TelephonyManager::class.java)
.listen(hangupOnCallAnswered, PhoneStateListener.LISTEN_CALL_STATE)
// reset call notification
// register uncaught exception handler
// register network receiver
// telephony listen to call state
registerUncaughtExceptionHandler()
}
private fun registerUncaughtExceptionHandler() {
uncaughtExceptionHandlerManager = UncaughtExceptionHandlerManager().apply {
registerHandler(ProximityLockRelease(lockManager))
}
}
private fun registerIncomingPstnCallReceiver() {
@@ -215,7 +219,7 @@ class WebRtcCallService: Service() {
private fun handleBusyMessage(intent: Intent) {
val recipient = getRemoteRecipient(intent)
val callId = getCallId(intent)
if (callManager.currentConnectionState != STATE_DIALING || callManager.callId != callManager.callId || callManager.recipient != callManager.recipient) {
if (callManager.currentConnectionState != STATE_DIALING || callManager.callId != callId || callManager.recipient != recipient) {
Log.w(TAG,"Got busy message for inactive session...")
return
}
@@ -412,10 +416,25 @@ class WebRtcCallService: Service() {
}
private fun handleRemoteIceCandidate(intent: Intent) {
val callId = getCallId(intent)
val sdpMids = intent.getStringArrayExtra(EXTRA_ICE_SDP_MID) ?: return
val sdpLineIndexes = intent.getIntArrayExtra(EXTRA_ICE_SDP_LINE_INDEX) ?: return
val sdps = intent.getStringArrayExtra(EXTRA_ICE_SDP) ?: return
if (sdpMids.size != sdpLineIndexes.size || sdpLineIndexes.size != sdps.size) {
Log.w(TAG,"sdp info not of equal length")
return
}
val iceCandidates = (0 until sdpMids.size).map { index ->
IceCandidate(
sdpMids[index],
sdpLineIndexes[index],
sdps[index]
)
}
callManager.handleRemoteIceCandidate(iceCandidates, callId)
}
private fun handleLocalIceCandidate(intent: Intent) {
private fun handleIceConnected(intent: Intent) {
}
@@ -469,12 +488,14 @@ class WebRtcCallService: Service() {
System.currentTimeMillis() - intent.getLongExtra(EXTRA_TIMESTAMP, -1) > TimeUnit.MINUTES.toMillis(2)
override fun onDestroy() {
super.onDestroy()
callManager.unregisterListener(this)
callReceiver?.let { receiver ->
unregisterReceiver(receiver)
}
callReceiver = null
// unregister exception handler
uncaughtExceptionHandlerManager?.unregister()
callManager.onDestroy()
super.onDestroy()
// shutdown audiomanager
// unregister network receiver
// unregister power button
@@ -553,4 +574,37 @@ class WebRtcCallService: Service() {
return expectedState == currentState && expectedCallId == currentCallId
}
override fun onSignalingChange(p0: PeerConnection.SignalingState?) {}
override fun onIceConnectionChange(newState: PeerConnection.IceConnectionState?) {
if (newState in arrayOf(CONNECTED, COMPLETED)) {
val intent = Intent(this, WebRtcCallService::class.java)
.setAction(ACTION_ICE_CONNECTED)
startService(intent)
} else if (newState == FAILED) {
val intent = Intent(this, WebRtcCallService::class.java)
.setAction(ACTION_REMOTE_HANGUP)
.putExtra(EXTRA_CALL_ID, callManager.callId)
startService(intent)
}
}
override fun onIceConnectionReceivingChange(p0: Boolean) {}
override fun onIceGatheringChange(p0: PeerConnection.IceGatheringState?) {}
override fun onIceCandidate(p0: IceCandidate?) {}
override fun onIceCandidatesRemoved(p0: Array<out IceCandidate>?) {}
override fun onAddStream(p0: MediaStream?) {}
override fun onRemoveStream(p0: MediaStream?) {}
override fun onDataChannel(p0: DataChannel?) {}
override fun onRenegotiationNeeded() {}
override fun onAddTrack(p0: RtpReceiver?, p1: Array<out MediaStream>?) {}
}

View File

@@ -10,6 +10,12 @@ open class AudioManagerCommand: Parcelable {
@Parcelize
object Initialize: AudioManagerCommand()
@Parcelize
object Shutdown: AudioManagerCommand()
@Parcelize
object UpdateAudioDeviceState: AudioManagerCommand()
@Parcelize
data class StartOutgoingRinger(val type: OutgoingRinger.Type): AudioManagerCommand()

View File

@@ -1,7 +1,6 @@
package org.thoughtcrime.securesms.webrtc
import android.content.Context
import android.content.Intent
import android.telephony.TelephonyManager
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asSharedFlow
@@ -64,6 +63,16 @@ class CallManager(context: Context, audioManager: AudioManagerCompat): PeerConne
private val signalAudioManager: SignalAudioManager = SignalAudioManager(context, this, audioManager)
private val peerConnectionObservers = mutableSetOf<PeerConnection.Observer>()
fun registerListener(listener: PeerConnection.Observer) {
peerConnectionObservers.add(listener)
}
fun unregisterListener(listener: PeerConnection.Observer) {
peerConnectionObservers.remove(listener)
}
private val _audioEvents = MutableStateFlow(StateEvent.AudioEnabled(false))
val audioEvents = _audioEvents.asSharedFlow()
private val _videoEvents = MutableStateFlow(StateEvent.VideoEnabled(false))
@@ -183,47 +192,47 @@ class CallManager(context: Context, audioManager: AudioManagerCompat): PeerConne
}
override fun onSignalingChange(newState: PeerConnection.SignalingState) {
peerConnectionObservers.forEach { listener -> listener.onSignalingChange(newState) }
}
override fun onIceConnectionChange(newState: PeerConnection.IceConnectionState) {
peerConnectionObservers.forEach { listener -> listener.onIceConnectionChange(newState) }
}
override fun onIceConnectionReceivingChange(receiving: Boolean) {
peerConnectionObservers.forEach { listener -> listener.onIceConnectionReceivingChange(receiving) }
}
override fun onIceGatheringChange(newState: PeerConnection.IceGatheringState) {
peerConnectionObservers.forEach { listener -> listener.onIceGatheringChange(newState) }
}
override fun onIceCandidate(p0: IceCandidate?) {
override fun onIceCandidate(iceCandidate: IceCandidate?) {
peerConnectionObservers.forEach { listener -> listener.onIceCandidate(iceCandidate) }
}
override fun onIceCandidatesRemoved(p0: Array<out IceCandidate>?) {
override fun onIceCandidatesRemoved(candidates: Array<out IceCandidate>?) {
peerConnectionObservers.forEach { listener -> listener.onIceCandidatesRemoved(candidates) }
}
override fun onAddStream(p0: MediaStream?) {
peerConnectionObservers.forEach { listener -> listener.onAddStream(p0) }
}
override fun onRemoveStream(p0: MediaStream?) {
peerConnectionObservers.forEach { listener -> listener.onRemoveStream(p0) }
}
override fun onDataChannel(p0: DataChannel?) {
peerConnectionObservers.forEach { listener -> listener.onDataChannel(p0) }
}
override fun onRenegotiationNeeded() {
peerConnectionObservers.forEach { listener -> listener.onRenegotiationNeeded() }
}
override fun onAddTrack(p0: RtpReceiver?, p1: Array<out MediaStream>?) {
peerConnectionObservers.forEach { listener -> listener.onAddTrack(p0, p1) }
}
override fun onBufferedAmountChange(l: Long) {
@@ -476,4 +485,8 @@ class CallManager(context: Context, audioManager: AudioManagerCompat): PeerConne
}
}
fun onDestroy() {
signalAudioManager.handleCommand(AudioManagerCommand.Shutdown)
}
}

View File

@@ -0,0 +1,42 @@
package org.thoughtcrime.securesms.webrtc;
import org.session.libsignal.utilities.Log;
import java.util.ArrayList;
import java.util.List;
/**
* Allows multiple default uncaught exception handlers to be registered
*
* Calls all registered handlers in reverse order of registration.
* Errors in one handler do not prevent subsequent handlers from being called.
*/
public class UncaughtExceptionHandlerManager implements Thread.UncaughtExceptionHandler {
private final Thread.UncaughtExceptionHandler originalHandler;
private final List<Thread.UncaughtExceptionHandler> handlers = new ArrayList<Thread.UncaughtExceptionHandler>();
public UncaughtExceptionHandlerManager() {
originalHandler = Thread.getDefaultUncaughtExceptionHandler();
registerHandler(originalHandler);
Thread.setDefaultUncaughtExceptionHandler(this);
}
public void registerHandler(Thread.UncaughtExceptionHandler handler) {
handlers.add(handler);
}
public void unregister() {
Thread.setDefaultUncaughtExceptionHandler(originalHandler);
}
@Override
public void uncaughtException(Thread thread, Throwable throwable) {
for (int i = handlers.size() - 1; i >= 0; i--) {
try {
handlers.get(i).uncaughtException(thread, throwable);
} catch(Throwable t) {
Log.e("UncaughtExceptionHandlerManager", "Error in uncaught exception handling", t);
}
}
}
}

View File

@@ -8,6 +8,7 @@ import android.telephony.TelephonyManager
import dagger.hilt.android.AndroidEntryPoint
import org.session.libsignal.utilities.Log
import org.thoughtcrime.securesms.service.WebRtcCallService
import org.thoughtcrime.securesms.webrtc.locks.LockManager
import javax.inject.Inject
@@ -26,11 +27,11 @@ class HangUpRtcOnPstnCallAnsweredListener(private val hangupListener: ()->Unit):
}
}
@AndroidEntryPoint
//@AndroidEntryPoint
class NetworkReceiver: BroadcastReceiver() {
@Inject
lateinit var callManager: CallManager
// @Inject
// lateinit var callManager: CallManager
override fun onReceive(context: Context, intent: Intent) {
TODO("Not yet implemented")
@@ -47,13 +48,13 @@ class PowerButtonReceiver : BroadcastReceiver() {
}
}
class ProximityLockRelease: Thread.UncaughtExceptionHandler {
class ProximityLockRelease(private val lockManager: LockManager): Thread.UncaughtExceptionHandler {
companion object {
private val TAG = Log.tag(ProximityLockRelease::class.java)
}
override fun uncaughtException(t: Thread, e: Throwable) {
Log.e(TAG,"Uncaught exception - releasing proximity lock", e)
// lockManager update phone state
lockManager.updatePhoneState(LockManager.PhoneState.IDLE)
}
}

View File

@@ -37,7 +37,7 @@ class SignalAudioManager(private val context: Context,
private val androidAudioManager: AudioManagerCompat) {
private var commandAndControlThread: HandlerThread? = HandlerThread("call-audio").apply { start() }
private val handler = SignalAudioHandler(commandAndControlThread!!.looper)
private var handler = SignalAudioHandler(commandAndControlThread!!.looper)
private val signalBluetoothManager = SignalBluetoothManager(context, this, androidAudioManager, handler)
@@ -69,6 +69,8 @@ class SignalAudioManager(private val context: Context,
handler.post {
when (command) {
is AudioManagerCommand.Initialize -> initialize()
is AudioManagerCommand.Shutdown -> shutdown()
is AudioManagerCommand.UpdateAudioDeviceState -> updateAudioDeviceState()
is AudioManagerCommand.Start -> start()
is AudioManagerCommand.Stop -> stop(command.playDisconnect)
is AudioManagerCommand.SetDefaultDevice -> setDefaultAudioDevice(command.device, command.clearUserEarpieceSelection)
@@ -84,6 +86,9 @@ class SignalAudioManager(private val context: Context,
Log.i(TAG, "Initializing audio manager state: $state")
if (state == State.UNINITIALIZED) {
commandAndControlThread = HandlerThread("call-audio").apply { start() }
handler = SignalAudioHandler(commandAndControlThread!!.looper)
savedAudioMode = androidAudioManager.mode
savedIsSpeakerPhoneOn = androidAudioManager.isSpeakerphoneOn
savedIsMicrophoneMute = androidAudioManager.isMicrophoneMute

View File

@@ -9,6 +9,7 @@ import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import org.session.libsignal.utilities.Log
import org.thoughtcrime.securesms.webrtc.AudioManagerCommand
import java.util.concurrent.TimeUnit
/**
@@ -181,7 +182,7 @@ class SignalBluetoothManager(
}
private fun updateAudioDeviceState() {
audioManager.updateAudioDeviceState()
audioManager.handleCommand(AudioManagerCommand.UpdateAudioDeviceState)
}
private fun startTimer() {

View File

@@ -1,11 +0,0 @@
package org.thoughtcrime.securesms.webrtc.data
import org.session.libsession.database.CallDataProvider
import org.session.libsession.database.StorageProtocol
import org.thoughtcrime.securesms.webrtc.CallManager
import javax.inject.Inject
class SessionCallDataProvider @Inject constructor(private val storage: StorageProtocol,
private val callManager: CallManager): CallDataProvider {
}