Skip to content

Commit

Permalink
Merge pull request #4014 from vector-im/feature/fga/hide_jitsi_event
Browse files Browse the repository at this point in the history
Jitsi: introduces ConferenceEvent
  • Loading branch information
bmarty authored Sep 17, 2021
2 parents b5f7351 + 8e9cd52 commit f418683
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 45 deletions.
1 change: 1 addition & 0 deletions changelog.d/4014.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Introduces ConferenceEvent to abstract usage of Jitsi BroadcastEvent class.
Original file line number Diff line number Diff line change
Expand Up @@ -28,29 +28,31 @@ import com.facebook.react.bridge.JavaOnlyMap
import org.jitsi.meet.sdk.BroadcastEmitter
import org.jitsi.meet.sdk.BroadcastEvent
import org.jitsi.meet.sdk.JitsiMeet
import org.matrix.android.sdk.api.extensions.tryOrNull
import timber.log.Timber

private const val CONFERENCE_URL_DATA_KEY = "url"

fun BroadcastEvent.extractConferenceUrl(): String? {
return when (type) {
BroadcastEvent.Type.CONFERENCE_TERMINATED,
BroadcastEvent.Type.CONFERENCE_WILL_JOIN,
BroadcastEvent.Type.CONFERENCE_JOINED -> data[CONFERENCE_URL_DATA_KEY] as? String
else -> null
sealed class ConferenceEvent(open val data: Map<String, Any>) {
data class Terminated(override val data: Map<String, Any>) : ConferenceEvent(data)
data class WillJoin(override val data: Map<String, Any>) : ConferenceEvent(data)
data class Joined(override val data: Map<String, Any>) : ConferenceEvent(data)

fun extractConferenceUrl(): String? {
return data[CONFERENCE_URL_DATA_KEY] as? String
}
}

class JitsiBroadcastEmitter(private val context: Context) {
class ConferenceEventEmitter(private val context: Context) {

fun emitConferenceEnded() {
val broadcastEventData = JavaOnlyMap.of(CONFERENCE_URL_DATA_KEY, JitsiMeet.getCurrentConference())
BroadcastEmitter(context).sendBroadcast(BroadcastEvent.Type.CONFERENCE_TERMINATED.name, broadcastEventData)
}
}

class JitsiBroadcastEventObserver(private val context: Context,
private val onBroadcastEvent: (BroadcastEvent) -> Unit) : LifecycleObserver {
class ConferenceEventObserver(private val context: Context,
private val onBroadcastEvent: (ConferenceEvent) -> Unit)
: LifecycleObserver {

// See https://jitsi.github.io/handbook/docs/dev-guide/dev-guide-android-sdk#listening-for-broadcasted-events
private val broadcastReceiver = object : BroadcastReceiver() {
Expand All @@ -61,8 +63,10 @@ class JitsiBroadcastEventObserver(private val context: Context,

@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun unregisterForBroadcastMessages() {
tryOrNull("Unable to unregister receiver") {
try {
LocalBroadcastManager.getInstance(context).unregisterReceiver(broadcastReceiver)
} catch (throwable: Throwable) {
Timber.v("Unable to unregister receiver")
}
}

Expand All @@ -72,13 +76,23 @@ class JitsiBroadcastEventObserver(private val context: Context,
for (type in BroadcastEvent.Type.values()) {
intentFilter.addAction(type.action)
}
tryOrNull("Unable to register receiver") {
try {
LocalBroadcastManager.getInstance(context).registerReceiver(broadcastReceiver, intentFilter)
} catch (throwable: Throwable) {
Timber.v("Unable to register receiver")
}
}

private fun onBroadcastReceived(intent: Intent) {
val event = BroadcastEvent(intent)
onBroadcastEvent(event)
val conferenceEvent = when (event.type) {
BroadcastEvent.Type.CONFERENCE_JOINED -> ConferenceEvent.Joined(event.data)
BroadcastEvent.Type.CONFERENCE_TERMINATED -> ConferenceEvent.Terminated(event.data)
BroadcastEvent.Type.CONFERENCE_WILL_JOIN -> ConferenceEvent.WillJoin(event.data)
else -> null
}
if (conferenceEvent != null) {
onBroadcastEvent(conferenceEvent)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package im.vector.app.features.call.conference

import android.content.Context
import androidx.lifecycle.ProcessLifecycleOwner
import org.jitsi.meet.sdk.BroadcastEvent
import org.matrix.android.sdk.api.extensions.orFalse
import javax.inject.Inject
import javax.inject.Singleton
Expand All @@ -29,18 +28,18 @@ class JitsiActiveConferenceHolder @Inject constructor(context: Context) {
private var activeConference: String? = null

init {
ProcessLifecycleOwner.get().lifecycle.addObserver(JitsiBroadcastEventObserver(context, this::onBroadcastEvent))
ProcessLifecycleOwner.get().lifecycle.addObserver(ConferenceEventObserver(context, this::onBroadcastEvent))
}

fun isJoined(confId: String?): Boolean {
return confId != null && activeConference?.endsWith(confId).orFalse()
}

private fun onBroadcastEvent(broadcastEvent: BroadcastEvent) {
when (broadcastEvent.type) {
BroadcastEvent.Type.CONFERENCE_JOINED -> activeConference = broadcastEvent.extractConferenceUrl()
BroadcastEvent.Type.CONFERENCE_TERMINATED -> activeConference = null
else -> Unit
private fun onBroadcastEvent(conferenceEvent: ConferenceEvent) {
when (conferenceEvent) {
is ConferenceEvent.Joined -> activeConference = conferenceEvent.extractConferenceUrl()
is ConferenceEvent.Terminated -> activeConference = null
else -> Unit
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@ import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.databinding.ActivityJitsiBinding
import kotlinx.parcelize.Parcelize
import org.jitsi.meet.sdk.BroadcastEvent
import org.jitsi.meet.sdk.JitsiMeet
import org.jitsi.meet.sdk.JitsiMeetActivityDelegate
import org.jitsi.meet.sdk.JitsiMeetActivityInterface
import org.jitsi.meet.sdk.JitsiMeetConferenceOptions
import org.jitsi.meet.sdk.JitsiMeetView
import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.api.util.JsonDict
import timber.log.Timber
import java.net.URL
import javax.inject.Inject
Expand Down Expand Up @@ -87,7 +87,7 @@ class VectorJitsiActivity : VectorBaseActivity<ActivityJitsiBinding>(), JitsiMee
JitsiCallViewEvents.LeaveConference -> handleLeaveConference()
}.exhaustive
}
lifecycle.addObserver(JitsiBroadcastEventObserver(this, this::onBroadcastEvent))
lifecycle.addObserver(ConferenceEventObserver(this, this::onBroadcastEvent))
}

override fun onResume() {
Expand All @@ -113,7 +113,7 @@ class VectorJitsiActivity : VectorBaseActivity<ActivityJitsiBinding>(), JitsiMee
jitsiMeetView?.dispose()
// Fake emitting CONFERENCE_TERMINATED event when currentConf is not null (probably when closing the PiP screen).
if (currentConf != null) {
JitsiBroadcastEmitter(this).emitConferenceEnded()
ConferenceEventEmitter(this).emitConferenceEnded()
}
JitsiMeetActivityDelegate.onHostDestroy(this)
super.onDestroy()
Expand Down Expand Up @@ -223,15 +223,15 @@ class VectorJitsiActivity : VectorBaseActivity<ActivityJitsiBinding>(), JitsiMee
JitsiMeetActivityDelegate.onRequestPermissionsResult(requestCode, permissions, grantResults)
}

private fun onBroadcastEvent(event: BroadcastEvent) {
Timber.v("Broadcast received: ${event.type}")
when (event.type) {
BroadcastEvent.Type.CONFERENCE_TERMINATED -> onConferenceTerminated(event.data)
else -> Unit
private fun onBroadcastEvent(event: ConferenceEvent) {
Timber.v("Broadcast received: $event")
when (event) {
is ConferenceEvent.Terminated -> onConferenceTerminated(event.data)
else -> Unit
}
}

private fun onConferenceTerminated(data: Map<String, Any>) {
private fun onConferenceTerminated(data: JsonDict) {
Timber.v("JitsiMeetViewListener.onConferenceTerminated()")
// Do not finish if there is an error
if (data["error"] == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ package im.vector.app.features.home.room.detail
import android.net.Uri
import android.view.View
import im.vector.app.core.platform.VectorViewModelAction
import org.jitsi.meet.sdk.BroadcastEvent
import im.vector.app.features.call.conference.ConferenceEvent
import org.matrix.android.sdk.api.session.content.ContentAttachmentData
import org.matrix.android.sdk.api.session.room.model.message.MessageAudioContent
import org.matrix.android.sdk.api.session.room.model.message.MessageStickerContent
Expand Down Expand Up @@ -97,7 +97,7 @@ sealed class RoomDetailAction : VectorViewModelAction {
data class EnsureNativeWidgetAllowed(val widget: Widget,
val userJustAccepted: Boolean,
val grantedEvents: RoomDetailViewEvents) : RoomDetailAction()
data class UpdateJoinJitsiCallStatus(val jitsiEvent: BroadcastEvent): RoomDetailAction()
data class UpdateJoinJitsiCallStatus(val conferenceEvent: ConferenceEvent): RoomDetailAction()

data class OpenOrCreateDm(val userId: String) : RoomDetailAction()
data class JumpToReadReceipt(val userId: String) : RoomDetailAction()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,9 @@ import im.vector.app.features.attachments.preview.AttachmentsPreviewArgs
import im.vector.app.features.attachments.toGroupedContentAttachmentData
import im.vector.app.features.call.SharedKnownCallsViewModel
import im.vector.app.features.call.VectorCallActivity
import im.vector.app.features.call.conference.JitsiBroadcastEmitter
import im.vector.app.features.call.conference.JitsiBroadcastEventObserver
import im.vector.app.features.call.conference.ConferenceEvent
import im.vector.app.features.call.conference.ConferenceEventEmitter
import im.vector.app.features.call.conference.ConferenceEventObserver
import im.vector.app.features.call.conference.JitsiCallViewModel
import im.vector.app.features.call.webrtc.WebRtcCallManager
import im.vector.app.features.command.Command
Expand Down Expand Up @@ -184,7 +185,6 @@ import nl.dionsegijn.konfetti.models.Shape
import nl.dionsegijn.konfetti.models.Size
import org.billcarsonfr.jsonviewer.JSonViewerDialog
import org.commonmark.parser.Parser
import org.jitsi.meet.sdk.BroadcastEvent
import org.matrix.android.sdk.api.extensions.orFalse
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.content.ContentAttachmentData
Expand Down Expand Up @@ -324,7 +324,7 @@ class RoomDetailFragment @Inject constructor(
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
lifecycle.addObserver(JitsiBroadcastEventObserver(vectorBaseActivity, this::onBroadcastJitsiEvent))
lifecycle.addObserver(ConferenceEventObserver(vectorBaseActivity, this::onBroadcastJitsiEvent))
super.onViewCreated(view, savedInstanceState)
sharedActionViewModel = activityViewModelProvider.get(MessageSharedActionViewModel::class.java)
knownCallsViewModel = activityViewModelProvider.get(SharedKnownCallsViewModel::class.java)
Expand Down Expand Up @@ -366,10 +366,10 @@ class RoomDetailFragment @Inject constructor(

knownCallsViewModel
.liveKnownCalls
.observe(viewLifecycleOwner, {
.observe(viewLifecycleOwner) {
currentCallsViewPresenter.updateCall(callManager.getCurrentCall(), it)
invalidateOptionsMenu()
})
}

roomDetailViewModel.selectSubscribe(RoomDetailViewState::canShowJumpToReadMarker, RoomDetailViewState::unreadState) { _, _ ->
updateJumpToReadMarkerViewVisibility()
Expand Down Expand Up @@ -454,11 +454,11 @@ class RoomDetailFragment @Inject constructor(
}

private fun leaveJitsiConference() {
JitsiBroadcastEmitter(vectorBaseActivity).emitConferenceEnded()
ConferenceEventEmitter(vectorBaseActivity).emitConferenceEnded()
}

private fun onBroadcastJitsiEvent(jitsiEvent: BroadcastEvent) {
roomDetailViewModel.handle(RoomDetailAction.UpdateJoinJitsiCallStatus(jitsiEvent))
private fun onBroadcastJitsiEvent(conferenceEvent: ConferenceEvent) {
roomDetailViewModel.handle(RoomDetailAction.UpdateJoinJitsiCallStatus(conferenceEvent))
}

private fun onCannotRecord() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider
import im.vector.app.features.call.conference.JitsiActiveConferenceHolder
import im.vector.app.features.attachments.toContentAttachmentData
import im.vector.app.features.call.conference.ConferenceEvent
import im.vector.app.features.call.conference.JitsiService
import im.vector.app.features.call.lookup.CallProtocolsChecker
import im.vector.app.features.call.webrtc.WebRtcCallManager
Expand All @@ -66,7 +67,6 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.commonmark.parser.Parser
import org.commonmark.renderer.html.HtmlRenderer
import org.jitsi.meet.sdk.BroadcastEvent
import org.matrix.android.sdk.api.MatrixCallback
import org.matrix.android.sdk.api.MatrixPatterns
import org.matrix.android.sdk.api.extensions.tryOrNull
Expand Down Expand Up @@ -368,12 +368,12 @@ class RoomDetailViewModel @AssistedInject constructor(
}
return@withState
}
when (action.jitsiEvent.type) {
BroadcastEvent.Type.CONFERENCE_JOINED,
BroadcastEvent.Type.CONFERENCE_TERMINATED -> {
when (action.conferenceEvent) {
is ConferenceEvent.Joined,
is ConferenceEvent.Terminated -> {
setState { copy(jitsiState = jitsiState.copy(hasJoined = activeConferenceHolder.isJoined(jitsiState.confId))) }
}
else -> Unit
else -> Unit
}
}

Expand Down

0 comments on commit f418683

Please sign in to comment.