mirror of
https://gitlab.linphone.org/BC/public/linphone-android.git
synced 2026-01-17 11:28:06 +00:00
Added support for screen sharing using new SDK APIs
This commit is contained in:
parent
719fa62752
commit
0fac6150c7
5 changed files with 89 additions and 18 deletions
|
|
@ -61,6 +61,8 @@ class ConferenceModel {
|
|||
|
||||
val conferenceLayout = MutableLiveData<Int>()
|
||||
|
||||
val isScreenSharing = MutableLiveData<Boolean>()
|
||||
|
||||
val isPaused = MutableLiveData<Boolean>()
|
||||
|
||||
val isMeParticipantSendingVideo = MutableLiveData<Boolean>()
|
||||
|
|
@ -88,6 +90,7 @@ class ConferenceModel {
|
|||
removeParticipant(participant)
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
override fun onParticipantDeviceMediaCapabilityChanged(
|
||||
conference: Conference,
|
||||
device: ParticipantDevice
|
||||
|
|
@ -170,6 +173,32 @@ class ConferenceModel {
|
|||
)
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
override fun onParticipantDeviceScreenSharingChanged(
|
||||
conference: Conference,
|
||||
device: ParticipantDevice,
|
||||
enabled: Boolean
|
||||
) {
|
||||
Log.i(
|
||||
"$TAG Participant device [${device.address.asStringUriOnly()}] is ${if (enabled) "sharing it's screen" else "no longer sharing it's screen"}"
|
||||
)
|
||||
isScreenSharing.postValue(enabled)
|
||||
if (enabled) {
|
||||
val call = conference.call
|
||||
if (call != null) {
|
||||
val currentLayout = getCurrentLayout(call)
|
||||
if (currentLayout == GRID_LAYOUT) {
|
||||
Log.w(
|
||||
"$TAG Current layout is mosaic but screen sharing was enabled, switching to active speaker layout"
|
||||
)
|
||||
setNewLayout(ACTIVE_SPEAKER_LAYOUT)
|
||||
}
|
||||
} else {
|
||||
Log.e("$TAG Screen sharing was enabled but conference's call is null!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
override fun onStateChanged(conference: Conference, state: Conference.State) {
|
||||
Log.i("$TAG State changed [$state]")
|
||||
|
|
@ -199,6 +228,8 @@ class ConferenceModel {
|
|||
conference = conf
|
||||
conference.addListener(conferenceListener)
|
||||
isPaused.postValue(conference.isIn)
|
||||
val screenSharing = conference.screenSharingParticipant != null
|
||||
isScreenSharing.postValue(screenSharing)
|
||||
|
||||
Log.i(
|
||||
"$TAG Configuring conference with subject [${conference.subject}] from call [${call.callLog.callId}]"
|
||||
|
|
@ -212,6 +243,12 @@ class ConferenceModel {
|
|||
|
||||
val currentLayout = getCurrentLayout(call)
|
||||
conferenceLayout.postValue(currentLayout)
|
||||
if (currentLayout == GRID_LAYOUT && screenSharing) {
|
||||
Log.w(
|
||||
"$TAG Conference has a participant sharing it's screen, changing layout from mosaic to active speaker"
|
||||
)
|
||||
setNewLayout(ACTIVE_SPEAKER_LAYOUT)
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ class ConferenceParticipantDeviceModel @WorkerThread constructor(
|
|||
|
||||
val isActiveSpeaker = MutableLiveData<Boolean>()
|
||||
|
||||
val isScreenSharing = MutableLiveData<Boolean>()
|
||||
|
||||
val isVideoAvailable = MutableLiveData<Boolean>()
|
||||
|
||||
val isSendingVideo = MutableLiveData<Boolean>()
|
||||
|
|
@ -110,12 +112,9 @@ class ConferenceParticipantDeviceModel @WorkerThread constructor(
|
|||
available: Boolean,
|
||||
streamType: StreamType?
|
||||
) {
|
||||
Log.i(
|
||||
Log.d(
|
||||
"$TAG Participant device [${participantDevice.address.asStringUriOnly()}] stream [$streamType] availability changed to ${if (available) "available" else "not available"}"
|
||||
)
|
||||
if (streamType == StreamType.Video) {
|
||||
isVideoAvailable.postValue(available)
|
||||
}
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
|
|
@ -124,15 +123,43 @@ class ConferenceParticipantDeviceModel @WorkerThread constructor(
|
|||
direction: MediaDirection?,
|
||||
streamType: StreamType?
|
||||
) {
|
||||
Log.i(
|
||||
Log.d(
|
||||
"$TAG Participant device [${participantDevice.address.asStringUriOnly()}] stream [$streamType] capability changed to [$direction]"
|
||||
)
|
||||
if (streamType == StreamType.Video) {
|
||||
val sending = direction == MediaDirection.SendRecv || direction == MediaDirection.SendOnly
|
||||
isSendingVideo.postValue(
|
||||
sending
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
override fun onScreenSharingChanged(
|
||||
participantDevice: ParticipantDevice,
|
||||
screenSharing: Boolean
|
||||
) {
|
||||
Log.i(
|
||||
"$TAG Participant device [${participantDevice.address.asStringUriOnly()}] is ${if (screenSharing) "sharing it's screen" else "no longer sharing it's screen"}"
|
||||
)
|
||||
isScreenSharing.postValue(screenSharing)
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
override fun onThumbnailStreamAvailabilityChanged(
|
||||
participantDevice: ParticipantDevice,
|
||||
available: Boolean
|
||||
) {
|
||||
Log.i(
|
||||
"$TAG Participant device [${participantDevice.address.asStringUriOnly()}] thumbnail availability changed to ${if (available) "available" else "not available"}"
|
||||
)
|
||||
isVideoAvailable.postValue(available)
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
override fun onThumbnailStreamCapabilityChanged(
|
||||
participantDevice: ParticipantDevice,
|
||||
direction: MediaDirection?
|
||||
) {
|
||||
Log.i(
|
||||
"$TAG Participant device [${participantDevice.address.asStringUriOnly()}] thumbnail capability changed to [$direction]"
|
||||
)
|
||||
val sending = direction == MediaDirection.SendRecv || direction == MediaDirection.SendOnly
|
||||
isSendingVideo.postValue(sending)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -156,11 +183,17 @@ class ConferenceParticipantDeviceModel @WorkerThread constructor(
|
|||
|
||||
isMuted.postValue(device.isMuted)
|
||||
isSpeaking.postValue(device.isSpeaking)
|
||||
isActiveSpeaker.postValue(false)
|
||||
Log.i(
|
||||
"$TAG Participant [${device.address.asStringUriOnly()}] is in state [${device.state}]"
|
||||
)
|
||||
|
||||
isActiveSpeaker.postValue(false)
|
||||
val screenSharing = device.isScreenSharingEnabled
|
||||
isScreenSharing.postValue(screenSharing)
|
||||
if (screenSharing) {
|
||||
Log.i("$TAG Participant [${device.address.asStringUriOnly()}] is sharing it's screen")
|
||||
}
|
||||
|
||||
isVideoAvailable.postValue(device.getStreamAvailability(StreamType.Video))
|
||||
val videoCapability = device.getStreamCapability(StreamType.Video)
|
||||
isSendingVideo.postValue(
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="@dimen/call_conference_active_speaker_miniature_size"
|
||||
android:layout_height="@dimen/call_conference_active_speaker_miniature_size"
|
||||
android:visibility="@{model.isActiveSpeaker ? View.GONE : View.VISIBLE}"
|
||||
android:visibility="@{model.isActiveSpeaker && !model.isScreenSharing ? View.GONE : View.VISIBLE}"
|
||||
android:padding="2dp">
|
||||
|
||||
<ImageView
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
<data>
|
||||
<import type="android.view.View" />
|
||||
<import type="org.linphone.ui.call.model.ConferenceModel" />
|
||||
<variable
|
||||
name="gridClickListener"
|
||||
type="View.OnClickListener" />
|
||||
|
|
@ -37,8 +38,8 @@
|
|||
android:layout_marginBottom="1dp"
|
||||
android:drawableEnd="@drawable/squares_four"
|
||||
android:drawableTint="@color/in_call_label_color"
|
||||
android:enabled="@{viewModel.participantDevices.size() < 7, default=false}"
|
||||
android:checked="@{viewModel.conferenceLayout == 0}"
|
||||
android:enabled="@{viewModel.participantDevices.size() < 7 && !viewModel.isScreenSharing, default=false}"
|
||||
android:checked="@{viewModel.conferenceLayout == ConferenceModel.GRID_LAYOUT}"
|
||||
app:useMaterialThemeColors="false"
|
||||
app:buttonTint="@color/in_call_label_color"/>
|
||||
|
||||
|
|
@ -55,7 +56,7 @@
|
|||
android:layout_marginBottom="1dp"
|
||||
android:drawableEnd="@drawable/picture_in_picture"
|
||||
android:drawableTint="@color/white"
|
||||
android:checked="@{viewModel.conferenceLayout == 1}"
|
||||
android:checked="@{viewModel.conferenceLayout == ConferenceModel.ACTIVE_SPEAKER_LAYOUT}"
|
||||
app:useMaterialThemeColors="false"
|
||||
app:buttonTint="@color/white"/>
|
||||
|
||||
|
|
@ -72,7 +73,7 @@
|
|||
android:layout_marginBottom="1dp"
|
||||
android:drawableEnd="@drawable/waveform"
|
||||
android:drawableTint="@color/white"
|
||||
android:checked="@{viewModel.conferenceLayout == -1}"
|
||||
android:checked="@{viewModel.conferenceLayout == ConferenceModel.AUDIO_ONLY_LAYOUT}"
|
||||
app:useMaterialThemeColors="false"
|
||||
app:buttonTint="@color/white"/>
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
<string name="notification_channel_missed_call_name">&appName; notifications d\'appels manqués</string>
|
||||
<string name="notification_channel_service_name">&appName; notification de service</string>
|
||||
<string name="notification_channel_chat_name">&appName; notifications des conversations</string>
|
||||
<string name="notification_chat_message_reaction_received">%s a réagi à %s par : %s</string>
|
||||
<string name="notification_chat_message_reaction_received">%s a réagi par %s à : %s</string>
|
||||
<string name="notification_mark_message_as_read">Marquer comme lu</string>
|
||||
<string name="notification_reply_to_message">Répondre</string>
|
||||
<string name="notification_missed_call">Appel manqué de %s</string>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue