mirror of
https://gitlab.linphone.org/BC/public/linphone-android.git
synced 2026-01-17 11:28:06 +00:00
Prevent being stuck in full screen mode without video
This commit is contained in:
parent
a7fb2ccfec
commit
eb80a16202
11 changed files with 79 additions and 34 deletions
|
|
@ -1001,7 +1001,7 @@ class NotificationsManager @MainThread constructor(private val context: Context)
|
|||
}
|
||||
|
||||
Log.i(
|
||||
"Creating notification for ${if (isIncoming) "incoming" else "outgoing"} ${if (isConference) "conference" else "call"} with video ${if (isVideo) "enabled" else "disabled"} on channel [$channel]"
|
||||
"Creating notification for [${if (isIncoming) "incoming" else "outgoing"}] [${if (isConference) "conference" else "call"}] with video [${if (isVideo) "enabled" else "disabled"}] on channel [$channel]"
|
||||
)
|
||||
|
||||
val builder = NotificationCompat.Builder(
|
||||
|
|
|
|||
|
|
@ -202,11 +202,15 @@ class ActiveConferenceCallFragment : GenericCallFragment() {
|
|||
}
|
||||
}
|
||||
|
||||
callViewModel.fullScreenMode.observe(viewLifecycleOwner) { hide ->
|
||||
Log.i("$TAG Switching full screen mode to ${if (hide) "ON" else "OFF"}")
|
||||
callViewModel.conferenceModel.fullScreenMode.observe(viewLifecycleOwner) { hide ->
|
||||
Log.i("$TAG Switching full screen mode to [${if (hide) "ON" else "OFF"}]")
|
||||
sharedViewModel.toggleFullScreenEvent.value = Event(hide)
|
||||
callStatsBottomSheetBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
callMediaEncryptionStatsBottomSheetBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
|
||||
if (hide != callViewModel.fullScreenMode.value) {
|
||||
callViewModel.fullScreenMode.value = hide
|
||||
}
|
||||
}
|
||||
|
||||
callViewModel.conferenceModel.conferenceLayout.observe(viewLifecycleOwner) { layout ->
|
||||
|
|
@ -220,8 +224,10 @@ class ActiveConferenceCallFragment : GenericCallFragment() {
|
|||
Log.i("$TAG We are alone in that conference, using nativePreviewWindowId")
|
||||
core.nativePreviewWindowId = binding.localPreviewVideoSurface
|
||||
|
||||
// Don't forget to leave full screen mode, otherwise we won't be able to leave it by touching video surface...
|
||||
callViewModel.fullScreenMode.postValue(false)
|
||||
if (callViewModel.conferenceModel.fullScreenMode.value == true && callViewModel.conferenceModel.isMeParticipantSendingVideo.value == false) {
|
||||
// Don't forget to leave full screen mode, otherwise we won't be able to leave it by touching video surface...
|
||||
callViewModel.conferenceModel.fullScreenMode.postValue(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -230,9 +236,9 @@ class ActiveConferenceCallFragment : GenericCallFragment() {
|
|||
viewLifecycleOwner
|
||||
) {
|
||||
it.consume {
|
||||
if (callViewModel.fullScreenMode.value == false) {
|
||||
if (callViewModel.conferenceModel.fullScreenMode.value == false) {
|
||||
Log.i("$TAG First participant joined conference, switching to full screen mode")
|
||||
callViewModel.toggleFullScreen()
|
||||
callViewModel.conferenceModel.toggleFullScreen()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ class ConferenceParticipantDeviceModel @WorkerThread constructor(
|
|||
)
|
||||
} else {
|
||||
Log.i(
|
||||
"$TAG Participant [${device.address.asStringUriOnly()}] is ${if (inConference) "inside" else "outside"} the conference with state [${device.state}]"
|
||||
"$TAG Participant [${device.address.asStringUriOnly()}] is [${if (inConference) "inside" else "outside"}] the conference with state [${device.state}]"
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -75,6 +75,8 @@ class ConferenceViewModel @UiThread constructor() : GenericViewModel() {
|
|||
|
||||
val isConversationAvailable = MutableLiveData<Boolean>()
|
||||
|
||||
val fullScreenMode = MutableLiveData<Boolean>()
|
||||
|
||||
val firstParticipantOtherThanOurselvesJoinedEvent: MutableLiveData<Event<Boolean>> by lazy {
|
||||
MutableLiveData<Event<Boolean>>()
|
||||
}
|
||||
|
|
@ -123,8 +125,7 @@ class ConferenceViewModel @UiThread constructor() : GenericViewModel() {
|
|||
if (conference.isMe(device.address)) {
|
||||
val direction = device.getStreamCapability(StreamType.Video)
|
||||
val sendingVideo = direction == MediaDirection.SendRecv || direction == MediaDirection.SendOnly
|
||||
isMeParticipantSendingVideo.postValue(sendingVideo)
|
||||
Log.i("$TAG We ${if (sendingVideo) "are" else "aren't"} sending video")
|
||||
localVideoStreamToggled(sendingVideo)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -255,6 +256,8 @@ class ConferenceViewModel @UiThread constructor() : GenericViewModel() {
|
|||
init {
|
||||
isPaused.value = false
|
||||
isConversationAvailable.value = false
|
||||
isMeParticipantSendingVideo.value = false
|
||||
fullScreenMode.value = false
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
|
|
@ -283,7 +286,7 @@ class ConferenceViewModel @UiThread constructor() : GenericViewModel() {
|
|||
isPaused.postValue(!isIn)
|
||||
}
|
||||
Log.i(
|
||||
"$TAG We ${if (isIn) "are" else "aren't"} in the conference right now, current state is [$state]"
|
||||
"$TAG We [${if (isIn) "are" else "aren't"}] in the conference right now, current state is [$state]"
|
||||
)
|
||||
|
||||
val screenSharing = conference.screenSharingParticipant != null
|
||||
|
|
@ -317,6 +320,33 @@ class ConferenceViewModel @UiThread constructor() : GenericViewModel() {
|
|||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun toggleFullScreen() {
|
||||
if (fullScreenMode.value == true) {
|
||||
// Always allow to switch off full screen mode
|
||||
fullScreenMode.value = false
|
||||
return
|
||||
}
|
||||
|
||||
if (conferenceLayout.value == AUDIO_ONLY_LAYOUT) {
|
||||
// Do not allow turning full screen on for audio only conference
|
||||
return
|
||||
}
|
||||
|
||||
if (isMeParticipantSendingVideo.value == false && participants.value.orEmpty().size == 1) {
|
||||
// Do not allow turning full screen on if we're alone and not sending our video
|
||||
return
|
||||
}
|
||||
|
||||
fullScreenMode.value = true
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
fun localVideoStreamToggled(enabled: Boolean) {
|
||||
isMeParticipantSendingVideo.postValue(enabled)
|
||||
Log.i("$TAG We [${if (enabled) "are" else "aren't"}] sending video")
|
||||
}
|
||||
|
||||
@UiThread
|
||||
fun goToConversation() {
|
||||
coreContext.postOnCoreThread { core ->
|
||||
|
|
@ -559,8 +589,7 @@ class ConferenceViewModel @UiThread constructor() : GenericViewModel() {
|
|||
|
||||
val direction = device.getStreamCapability(StreamType.Video)
|
||||
val sendingVideo = direction == MediaDirection.SendRecv || direction == MediaDirection.SendOnly
|
||||
isMeParticipantSendingVideo.postValue(sendingVideo)
|
||||
Log.i("$TAG We ${if (sendingVideo) "are" else "aren't"} sending video right now")
|
||||
localVideoStreamToggled(sendingVideo)
|
||||
}
|
||||
|
||||
if (!activeSpeakerParticipantDeviceFound && devicesList.isNotEmpty()) {
|
||||
|
|
|
|||
|
|
@ -788,6 +788,9 @@ class CurrentCallViewModel @UiThread constructor() : GenericViewModel() {
|
|||
params?.videoDirection = MediaDirection.SendRecv
|
||||
}
|
||||
}
|
||||
|
||||
val sendingVideo = params?.videoDirection == MediaDirection.SendRecv || params?.videoDirection == MediaDirection.SendOnly
|
||||
conferenceModel.localVideoStreamToggled(sendingVideo)
|
||||
} else if (params != null) {
|
||||
params.isVideoEnabled = true
|
||||
params.videoDirection = when (currentCall.currentParams.videoDirection) {
|
||||
|
|
@ -857,8 +860,17 @@ class CurrentCallViewModel @UiThread constructor() : GenericViewModel() {
|
|||
|
||||
@UiThread
|
||||
fun toggleFullScreen() {
|
||||
if (fullScreenMode.value == false && isVideoEnabled.value == false) return
|
||||
fullScreenMode.value = fullScreenMode.value != true
|
||||
if (fullScreenMode.value == true) {
|
||||
// Always allow to switch off full screen mode
|
||||
fullScreenMode.value = false
|
||||
return
|
||||
}
|
||||
|
||||
if (isVideoEnabled.value == false) {
|
||||
// Do not allow turning full screen on for audio only calls
|
||||
return
|
||||
}
|
||||
fullScreenMode.value = true
|
||||
}
|
||||
|
||||
@UiThread
|
||||
|
|
@ -1214,19 +1226,18 @@ class CurrentCallViewModel @UiThread constructor() : GenericViewModel() {
|
|||
isReceivingVideo.postValue(isReceiving)
|
||||
}
|
||||
|
||||
if (((isReceiving) && !wasReceiving)) {
|
||||
if (fullScreenMode.value != true) {
|
||||
val inConference = conferenceModel.isCurrentCallInConference.value == true
|
||||
if (!inConference) {
|
||||
if (currentCall.conference == null) { // Let conference view model handle full screen while in conference
|
||||
if (isReceiving && !wasReceiving) { // Do not change full screen mode base on our video being sent when it wasn't
|
||||
if (fullScreenMode.value != true) {
|
||||
Log.i(
|
||||
"$TAG Video is being received (it wasn't before), switching to full-screen mode"
|
||||
"$TAG Video is being received or sent (and it wasn't before), switching to full-screen mode"
|
||||
)
|
||||
fullScreenMode.postValue(true)
|
||||
}
|
||||
} else if (!isSending && !isReceiving && fullScreenMode.value == true) {
|
||||
Log.w("$TAG Video is no longer sent nor received, leaving full screen mode")
|
||||
fullScreenMode.postValue(false)
|
||||
}
|
||||
} else if (!isSending && !isReceiving && fullScreenMode.value == true) {
|
||||
Log.w("$TAG Video is no longer enabled, leaving full screen mode")
|
||||
fullScreenMode.postValue(false)
|
||||
}
|
||||
|
||||
updateProximitySensor()
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ class ConversationsListFragment : AbstractMainFragment() {
|
|||
}
|
||||
|
||||
Log.i(
|
||||
"$TAG Navigating to ${if (isMedia) "media" else "file"} viewer fragment with path [$path]"
|
||||
"$TAG Navigating to [${if (isMedia) "media" else "file"}] viewer fragment with path [$path]"
|
||||
)
|
||||
if (isMedia) {
|
||||
val intent = Intent(requireActivity(), MediaViewerActivity::class.java)
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@ class ContactsListViewModel @UiThread constructor() : AbstractMainViewModel() {
|
|||
contactModel.friend.edit()
|
||||
val starred = !contactModel.friend.starred
|
||||
Log.i(
|
||||
"$TAG Friend [${contactModel.name.value}] will be ${if (starred) "added to" else "removed from"} favourites"
|
||||
"$TAG Friend [${contactModel.name.value}] will be [${if (starred) "added to" else "removed from"}] favourites"
|
||||
)
|
||||
contactModel.friend.starred = starred
|
||||
contactModel.friend.done()
|
||||
|
|
|
|||
|
|
@ -266,7 +266,7 @@ class MeetingViewModel @UiThread constructor() : GenericViewModel() {
|
|||
val participant = info.address
|
||||
val isOrganizer = organizer?.weakEqual(participant) == true
|
||||
Log.d(
|
||||
"$TAG Conference [${conferenceInfo.subject}] ${if (isOrganizer) "organizer" else "participant"} [${participant.asStringUriOnly()}] is a [${info.role}]"
|
||||
"$TAG Conference [${conferenceInfo.subject}] [${if (isOrganizer) "organizer" else "participant"}] [${participant.asStringUriOnly()}] is a [${info.role}]"
|
||||
)
|
||||
if (isOrganizer) {
|
||||
organizerFound = true
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ class AudioUtils {
|
|||
|
||||
val extendedAudioDevices = coreContext.core.extendedAudioDevices
|
||||
Log.i(
|
||||
"$TAG Looking for an ${if (output) "output" else "input"} audio device with capability [$capability], driver name [$preferredDriver] and type [$types] in extended audio devices list (size ${extendedAudioDevices.size})"
|
||||
"$TAG Looking for an [${if (output) "output" else "input"}] audio device with capability [$capability], driver name [$preferredDriver] and type [$types] in extended audio devices list (size ${extendedAudioDevices.size})"
|
||||
)
|
||||
val foundAudioDevice = extendedAudioDevices.find {
|
||||
it.driverName == preferredDriver && types.contains(it.type) && it.hasCapability(
|
||||
|
|
@ -143,7 +143,7 @@ class AudioUtils {
|
|||
}
|
||||
if (call != null) {
|
||||
Log.i(
|
||||
"$TAG Found [${audioDevice.type}] ${if (output) "playback" else "recorder"} audio device [${audioDevice.deviceName} (${audioDevice.driverName})], routing call audio to it"
|
||||
"$TAG Found [${audioDevice.type}] [${if (output) "playback" else "recorder"}] audio device [${audioDevice.deviceName} (${audioDevice.driverName})], routing call audio to it"
|
||||
)
|
||||
if (output) {
|
||||
call.outputAudioDevice = audioDevice
|
||||
|
|
@ -152,7 +152,7 @@ class AudioUtils {
|
|||
}
|
||||
} else {
|
||||
Log.i(
|
||||
"$TAG Found [${audioDevice.type}] ${if (output) "playback" else "recorder"} audio device [${audioDevice.deviceName} (${audioDevice.driverName})], changing core default audio device"
|
||||
"$TAG Found [${audioDevice.type}] [${if (output) "playback" else "recorder"}] audio device [${audioDevice.deviceName} (${audioDevice.driverName})], changing core default audio device"
|
||||
)
|
||||
if (output) {
|
||||
coreContext.core.outputAudioDevice = audioDevice
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/constraint_layout"
|
||||
android:onClick="@{() -> viewModel.conferenceModel.toggleFullScreen()}"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/gray_900">
|
||||
|
|
@ -235,7 +236,7 @@
|
|||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/conference_layout_nav_host_fragment"
|
||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||
android:onClick="@{() -> viewModel.toggleFullScreen()}"
|
||||
android:onClick="@{() -> viewModel.conferenceModel.toggleFullScreen()}"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginBottom="@{viewModel.fullScreenMode || viewModel.pipMode ? @dimen/zero : @dimen/call_main_actions_menu_margin, default=@dimen/call_main_actions_menu_margin}"
|
||||
|
|
|
|||
|
|
@ -145,11 +145,9 @@
|
|||
|
||||
<HorizontalScrollView
|
||||
android:id="@+id/active_speaker_miniatures_horizontal_layout"
|
||||
android:layout_width="0dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
app:layout_constraintBottom_toBottomOf="parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue