Stop ongoing voice broadcast on app restart
This commit is contained in:
		
							parent
							
								
									a4eff0cc78
								
							
						
					
					
						commit
						6eeb54ae40
					
				@ -42,6 +42,8 @@ import im.vector.app.features.raw.wellknown.isSecureBackupRequired
 | 
			
		||||
import im.vector.app.features.raw.wellknown.withElementWellKnown
 | 
			
		||||
import im.vector.app.features.session.coroutineScope
 | 
			
		||||
import im.vector.app.features.settings.VectorPreferences
 | 
			
		||||
import im.vector.app.features.voicebroadcast.VoiceBroadcastHelper
 | 
			
		||||
import im.vector.app.features.voicebroadcast.model.asVoiceBroadcastEvent
 | 
			
		||||
import im.vector.lib.core.utils.compat.getParcelableExtraCompat
 | 
			
		||||
import kotlinx.coroutines.Dispatchers
 | 
			
		||||
import kotlinx.coroutines.delay
 | 
			
		||||
@ -60,12 +62,14 @@ import org.matrix.android.sdk.api.auth.data.LoginFlowTypes
 | 
			
		||||
import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse
 | 
			
		||||
import org.matrix.android.sdk.api.auth.registration.nextUncompletedStage
 | 
			
		||||
import org.matrix.android.sdk.api.extensions.tryOrNull
 | 
			
		||||
import org.matrix.android.sdk.api.query.QueryStringValue
 | 
			
		||||
import org.matrix.android.sdk.api.raw.RawService
 | 
			
		||||
import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes
 | 
			
		||||
import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService
 | 
			
		||||
import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo
 | 
			
		||||
import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap
 | 
			
		||||
import org.matrix.android.sdk.api.session.events.model.toModel
 | 
			
		||||
import org.matrix.android.sdk.api.session.getRoom
 | 
			
		||||
import org.matrix.android.sdk.api.session.getUserOrDefault
 | 
			
		||||
import org.matrix.android.sdk.api.session.pushrules.RuleIds
 | 
			
		||||
import org.matrix.android.sdk.api.session.room.model.Membership
 | 
			
		||||
@ -92,6 +96,7 @@ class HomeActivityViewModel @AssistedInject constructor(
 | 
			
		||||
        private val analyticsConfig: AnalyticsConfig,
 | 
			
		||||
        private val releaseNotesPreferencesStore: ReleaseNotesPreferencesStore,
 | 
			
		||||
        private val vectorFeatures: VectorFeatures,
 | 
			
		||||
        private val voiceBroadcastHelper: VoiceBroadcastHelper,
 | 
			
		||||
) : VectorViewModel<HomeActivityViewState, HomeActivityViewActions, HomeActivityViewEvents>(initialState) {
 | 
			
		||||
 | 
			
		||||
    @AssistedFactory
 | 
			
		||||
@ -123,6 +128,7 @@ class HomeActivityViewModel @AssistedInject constructor(
 | 
			
		||||
        observeReleaseNotes()
 | 
			
		||||
        observeLocalNotificationsSilenced()
 | 
			
		||||
        initThreadsMigration()
 | 
			
		||||
        stopOngoingVoiceBroadcast()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun observeReleaseNotes() = withState { state ->
 | 
			
		||||
@ -490,6 +496,30 @@ class HomeActivityViewModel @AssistedInject constructor(
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Stop ongoing voice broadcast if any.
 | 
			
		||||
     */
 | 
			
		||||
    private fun stopOngoingVoiceBroadcast() {
 | 
			
		||||
        val session = activeSessionHolder.getSafeActiveSession() ?: return
 | 
			
		||||
 | 
			
		||||
        // FIXME Iterate only on recent rooms for the moment, improve this
 | 
			
		||||
        val recentRooms = session.roomService().getBreadcrumbs(roomSummaryQueryParams {
 | 
			
		||||
            displayName = QueryStringValue.NoCondition
 | 
			
		||||
            memberships = listOf(Membership.JOIN)
 | 
			
		||||
        }).mapNotNull { session.getRoom(it.roomId) }
 | 
			
		||||
 | 
			
		||||
        recentRooms
 | 
			
		||||
                .forEach { room ->
 | 
			
		||||
                    val ongoingVoiceBroadcasts = voiceBroadcastHelper.getOngoingVoiceBroadcasts(room.roomId)
 | 
			
		||||
                    val myOngoingVoiceBroadcastId = ongoingVoiceBroadcasts.find { it.root.stateKey == session.myUserId }?.reference?.eventId
 | 
			
		||||
                    val initialEvent = myOngoingVoiceBroadcastId?.let { room.timelineService().getTimelineEvent(it)?.root?.asVoiceBroadcastEvent() }
 | 
			
		||||
                    if (myOngoingVoiceBroadcastId != null && initialEvent?.content?.deviceId == session.sessionParams.deviceId) {
 | 
			
		||||
                        viewModelScope.launch { voiceBroadcastHelper.stopVoiceBroadcast(room.roomId) }
 | 
			
		||||
                        return // No need to iterate more as we should not have more than one recording VB
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun handle(action: HomeActivityViewActions) {
 | 
			
		||||
        when (action) {
 | 
			
		||||
            HomeActivityViewActions.PushPromptHasBeenReviewed -> {
 | 
			
		||||
 | 
			
		||||
@ -16,6 +16,7 @@
 | 
			
		||||
 | 
			
		||||
package im.vector.app.features.voicebroadcast
 | 
			
		||||
 | 
			
		||||
import im.vector.app.features.voicebroadcast.usecase.GetOngoingVoiceBroadcastsUseCase
 | 
			
		||||
import im.vector.app.features.voicebroadcast.usecase.PauseVoiceBroadcastUseCase
 | 
			
		||||
import im.vector.app.features.voicebroadcast.usecase.ResumeVoiceBroadcastUseCase
 | 
			
		||||
import im.vector.app.features.voicebroadcast.usecase.StartVoiceBroadcastUseCase
 | 
			
		||||
@ -30,6 +31,7 @@ class VoiceBroadcastHelper @Inject constructor(
 | 
			
		||||
        private val pauseVoiceBroadcastUseCase: PauseVoiceBroadcastUseCase,
 | 
			
		||||
        private val resumeVoiceBroadcastUseCase: ResumeVoiceBroadcastUseCase,
 | 
			
		||||
        private val stopVoiceBroadcastUseCase: StopVoiceBroadcastUseCase,
 | 
			
		||||
        private val getOngoingVoiceBroadcastsUseCase: GetOngoingVoiceBroadcastsUseCase,
 | 
			
		||||
        private val voiceBroadcastPlayer: VoiceBroadcastPlayer,
 | 
			
		||||
) {
 | 
			
		||||
    suspend fun startVoiceBroadcast(roomId: String) = startVoiceBroadcastUseCase.execute(roomId)
 | 
			
		||||
@ -45,4 +47,6 @@ class VoiceBroadcastHelper @Inject constructor(
 | 
			
		||||
    fun pausePlayback() = voiceBroadcastPlayer.pause()
 | 
			
		||||
 | 
			
		||||
    fun stopPlayback() = voiceBroadcastPlayer.stop()
 | 
			
		||||
 | 
			
		||||
    fun getOngoingVoiceBroadcasts(roomId: String) = getOngoingVoiceBroadcastsUseCase.execute(roomId)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,45 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2022 New Vector Ltd
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package im.vector.app.features.voicebroadcast.usecase
 | 
			
		||||
 | 
			
		||||
import im.vector.app.features.voicebroadcast.VoiceBroadcastConstants
 | 
			
		||||
import im.vector.app.features.voicebroadcast.model.VoiceBroadcastEvent
 | 
			
		||||
import im.vector.app.features.voicebroadcast.model.VoiceBroadcastState
 | 
			
		||||
import im.vector.app.features.voicebroadcast.model.asVoiceBroadcastEvent
 | 
			
		||||
import org.matrix.android.sdk.api.query.QueryStringValue
 | 
			
		||||
import org.matrix.android.sdk.api.session.Session
 | 
			
		||||
import org.matrix.android.sdk.api.session.getRoom
 | 
			
		||||
import timber.log.Timber
 | 
			
		||||
import javax.inject.Inject
 | 
			
		||||
 | 
			
		||||
class GetOngoingVoiceBroadcastsUseCase @Inject constructor(
 | 
			
		||||
        private val session: Session,
 | 
			
		||||
) {
 | 
			
		||||
 | 
			
		||||
    fun execute(roomId: String): List<VoiceBroadcastEvent> {
 | 
			
		||||
        val room = session.getRoom(roomId) ?: error("Unknown roomId: $roomId")
 | 
			
		||||
 | 
			
		||||
        Timber.d("## GetLastVoiceBroadcastUseCase: get last voice broadcast in $roomId")
 | 
			
		||||
 | 
			
		||||
        return room.stateService().getStateEvents(
 | 
			
		||||
                setOf(VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO),
 | 
			
		||||
                QueryStringValue.IsNotEmpty
 | 
			
		||||
        )
 | 
			
		||||
                .mapNotNull { it.asVoiceBroadcastEvent() }
 | 
			
		||||
                .filter { it.content?.voiceBroadcastState != null && it.content?.voiceBroadcastState != VoiceBroadcastState.STOPPED }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -25,9 +25,7 @@ import im.vector.app.features.voicebroadcast.VoiceBroadcastRecorder
 | 
			
		||||
import im.vector.app.features.voicebroadcast.model.MessageVoiceBroadcastInfoContent
 | 
			
		||||
import im.vector.app.features.voicebroadcast.model.VoiceBroadcastChunk
 | 
			
		||||
import im.vector.app.features.voicebroadcast.model.VoiceBroadcastState
 | 
			
		||||
import im.vector.app.features.voicebroadcast.model.asVoiceBroadcastEvent
 | 
			
		||||
import im.vector.lib.multipicker.utils.toMultiPickerAudioType
 | 
			
		||||
import org.matrix.android.sdk.api.query.QueryStringValue
 | 
			
		||||
import org.matrix.android.sdk.api.session.Session
 | 
			
		||||
import org.matrix.android.sdk.api.session.events.model.RelationType
 | 
			
		||||
import org.matrix.android.sdk.api.session.events.model.toContent
 | 
			
		||||
@ -43,6 +41,7 @@ class StartVoiceBroadcastUseCase @Inject constructor(
 | 
			
		||||
        private val voiceBroadcastRecorder: VoiceBroadcastRecorder?,
 | 
			
		||||
        private val context: Context,
 | 
			
		||||
        private val buildMeta: BuildMeta,
 | 
			
		||||
        private val getOngoingVoiceBroadcastsUseCase: GetOngoingVoiceBroadcastsUseCase,
 | 
			
		||||
) {
 | 
			
		||||
 | 
			
		||||
    suspend fun execute(roomId: String): Result<Unit> = runCatching {
 | 
			
		||||
@ -50,12 +49,7 @@ class StartVoiceBroadcastUseCase @Inject constructor(
 | 
			
		||||
 | 
			
		||||
        Timber.d("## StartVoiceBroadcastUseCase: Start voice broadcast requested")
 | 
			
		||||
 | 
			
		||||
        val onGoingVoiceBroadcastEvents = room.stateService().getStateEvents(
 | 
			
		||||
                setOf(VoiceBroadcastConstants.STATE_ROOM_VOICE_BROADCAST_INFO),
 | 
			
		||||
                QueryStringValue.IsNotEmpty
 | 
			
		||||
        )
 | 
			
		||||
                .mapNotNull { it.asVoiceBroadcastEvent() }
 | 
			
		||||
                .filter { it.content?.voiceBroadcastState != null && it.content?.voiceBroadcastState != VoiceBroadcastState.STOPPED }
 | 
			
		||||
        val onGoingVoiceBroadcastEvents = getOngoingVoiceBroadcastsUseCase.execute(roomId)
 | 
			
		||||
 | 
			
		||||
        if (onGoingVoiceBroadcastEvents.isEmpty()) {
 | 
			
		||||
            startVoiceBroadcast(room)
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user