mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-12-22 23:58:47 +01:00
Stopping existing active live when starting a new one
This commit is contained in:
parent
70996655e1
commit
c2c58f81d8
@ -51,10 +51,14 @@ import org.matrix.android.sdk.internal.session.room.directory.DefaultSetRoomDire
|
||||
import org.matrix.android.sdk.internal.session.room.directory.GetPublicRoomTask
|
||||
import org.matrix.android.sdk.internal.session.room.directory.GetRoomDirectoryVisibilityTask
|
||||
import org.matrix.android.sdk.internal.session.room.directory.SetRoomDirectoryVisibilityTask
|
||||
import org.matrix.android.sdk.internal.session.room.location.CheckIfExistingActiveLiveTask
|
||||
import org.matrix.android.sdk.internal.session.room.location.DefaultCheckIfExistingActiveLiveTask
|
||||
import org.matrix.android.sdk.internal.session.room.location.DefaultGetActiveBeaconInfoForUserTask
|
||||
import org.matrix.android.sdk.internal.session.room.location.DefaultSendLiveLocationTask
|
||||
import org.matrix.android.sdk.internal.session.room.location.DefaultSendStaticLocationTask
|
||||
import org.matrix.android.sdk.internal.session.room.location.DefaultStartLiveLocationShareTask
|
||||
import org.matrix.android.sdk.internal.session.room.location.DefaultStopLiveLocationShareTask
|
||||
import org.matrix.android.sdk.internal.session.room.location.GetActiveBeaconInfoForUserTask
|
||||
import org.matrix.android.sdk.internal.session.room.location.SendLiveLocationTask
|
||||
import org.matrix.android.sdk.internal.session.room.location.SendStaticLocationTask
|
||||
import org.matrix.android.sdk.internal.session.room.location.StartLiveLocationShareTask
|
||||
@ -319,4 +323,10 @@ internal abstract class RoomModule {
|
||||
|
||||
@Binds
|
||||
abstract fun bindSendLiveLocationTask(task: DefaultSendLiveLocationTask): SendLiveLocationTask
|
||||
|
||||
@Binds
|
||||
abstract fun bindGetActiveBeaconInfoForUserTask(task: DefaultGetActiveBeaconInfoForUserTask): GetActiveBeaconInfoForUserTask
|
||||
|
||||
@Binds
|
||||
abstract fun bindCheckIfExistingActiveLiveTask(task: DefaultCheckIfExistingActiveLiveTask): CheckIfExistingActiveLiveTask
|
||||
}
|
||||
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* 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 org.matrix.android.sdk.internal.session.room.location
|
||||
|
||||
import org.matrix.android.sdk.api.extensions.orFalse
|
||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||
import org.matrix.android.sdk.api.session.room.model.message.MessageBeaconInfoContent
|
||||
import org.matrix.android.sdk.internal.task.Task
|
||||
import javax.inject.Inject
|
||||
|
||||
internal interface CheckIfExistingActiveLiveTask : Task<CheckIfExistingActiveLiveTask.Params, Boolean> {
|
||||
data class Params(
|
||||
val roomId: String,
|
||||
)
|
||||
}
|
||||
|
||||
// TODO unit tests
|
||||
internal class DefaultCheckIfExistingActiveLiveTask @Inject constructor(
|
||||
private val getActiveBeaconInfoForUserTask: GetActiveBeaconInfoForUserTask,
|
||||
) : CheckIfExistingActiveLiveTask {
|
||||
|
||||
override suspend fun execute(params: CheckIfExistingActiveLiveTask.Params): Boolean {
|
||||
val getActiveBeaconTaskParams = GetActiveBeaconInfoForUserTask.Params(
|
||||
roomId = params.roomId
|
||||
)
|
||||
return getActiveBeaconInfoForUserTask.execute(getActiveBeaconTaskParams)
|
||||
?.getClearContent()
|
||||
?.toModel<MessageBeaconInfoContent>()
|
||||
?.isLive
|
||||
.orFalse()
|
||||
}
|
||||
}
|
@ -41,6 +41,7 @@ internal class DefaultLocationSharingService @AssistedInject constructor(
|
||||
private val sendLiveLocationTask: SendLiveLocationTask,
|
||||
private val startLiveLocationShareTask: StartLiveLocationShareTask,
|
||||
private val stopLiveLocationShareTask: StopLiveLocationShareTask,
|
||||
private val stopCheckIfExistingActiveLiveTask: CheckIfExistingActiveLiveTask,
|
||||
private val liveLocationShareAggregatedSummaryMapper: LiveLocationShareAggregatedSummaryMapper,
|
||||
) : LocationSharingService {
|
||||
|
||||
@ -72,6 +73,10 @@ internal class DefaultLocationSharingService @AssistedInject constructor(
|
||||
}
|
||||
|
||||
override suspend fun startLiveLocationShare(timeoutMillis: Long): UpdateLiveLocationShareResult {
|
||||
// Ensure to stop any active live before starting a new one
|
||||
if (checkIfExistingActiveLive()) {
|
||||
stopLiveLocationShare()
|
||||
}
|
||||
val params = StartLiveLocationShareTask.Params(
|
||||
roomId = roomId,
|
||||
timeoutMillis = timeoutMillis
|
||||
@ -79,6 +84,13 @@ internal class DefaultLocationSharingService @AssistedInject constructor(
|
||||
return startLiveLocationShareTask.execute(params)
|
||||
}
|
||||
|
||||
private suspend fun checkIfExistingActiveLive(): Boolean {
|
||||
val params = CheckIfExistingActiveLiveTask.Params(
|
||||
roomId = roomId
|
||||
)
|
||||
return stopCheckIfExistingActiveLiveTask.execute(params)
|
||||
}
|
||||
|
||||
override suspend fun stopLiveLocationShare(): UpdateLiveLocationShareResult {
|
||||
val params = StopLiveLocationShareTask.Params(
|
||||
roomId = roomId,
|
||||
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* 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 org.matrix.android.sdk.internal.session.room.location
|
||||
|
||||
import org.matrix.android.sdk.api.extensions.orFalse
|
||||
import org.matrix.android.sdk.api.query.QueryStringValue
|
||||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||
import org.matrix.android.sdk.api.session.room.model.message.MessageBeaconInfoContent
|
||||
import org.matrix.android.sdk.internal.di.UserId
|
||||
import org.matrix.android.sdk.internal.session.room.state.StateEventDataSource
|
||||
import org.matrix.android.sdk.internal.task.Task
|
||||
import javax.inject.Inject
|
||||
|
||||
internal interface GetActiveBeaconInfoForUserTask : Task<GetActiveBeaconInfoForUserTask.Params, Event?> {
|
||||
data class Params(
|
||||
val roomId: String,
|
||||
)
|
||||
}
|
||||
|
||||
// TODO unit tests
|
||||
internal class DefaultGetActiveBeaconInfoForUserTask @Inject constructor(
|
||||
@UserId private val userId: String,
|
||||
private val stateEventDataSource: StateEventDataSource,
|
||||
) : GetActiveBeaconInfoForUserTask {
|
||||
|
||||
override suspend fun execute(params: GetActiveBeaconInfoForUserTask.Params): Event? {
|
||||
return EventType.STATE_ROOM_BEACON_INFO
|
||||
.mapNotNull {
|
||||
stateEventDataSource.getStateEvent(
|
||||
roomId = params.roomId,
|
||||
eventType = it,
|
||||
stateKey = QueryStringValue.Equals(userId)
|
||||
)
|
||||
}
|
||||
.firstOrNull { beaconInfoEvent ->
|
||||
beaconInfoEvent.getClearContent()?.toModel<MessageBeaconInfoContent>()?.isLive.orFalse()
|
||||
}
|
||||
}
|
||||
}
|
@ -16,17 +16,13 @@
|
||||
|
||||
package org.matrix.android.sdk.internal.session.room.location
|
||||
|
||||
import org.matrix.android.sdk.api.extensions.orFalse
|
||||
import org.matrix.android.sdk.api.query.QueryStringValue
|
||||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||
import org.matrix.android.sdk.api.session.events.model.toContent
|
||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||
import org.matrix.android.sdk.api.session.room.location.UpdateLiveLocationShareResult
|
||||
import org.matrix.android.sdk.api.session.room.model.message.MessageBeaconInfoContent
|
||||
import org.matrix.android.sdk.internal.di.UserId
|
||||
import org.matrix.android.sdk.internal.session.room.state.SendStateTask
|
||||
import org.matrix.android.sdk.internal.session.room.state.StateEventDataSource
|
||||
import org.matrix.android.sdk.internal.task.Task
|
||||
import javax.inject.Inject
|
||||
|
||||
@ -36,14 +32,14 @@ internal interface StopLiveLocationShareTask : Task<StopLiveLocationShareTask.Pa
|
||||
)
|
||||
}
|
||||
|
||||
// TODO update unit tests
|
||||
internal class DefaultStopLiveLocationShareTask @Inject constructor(
|
||||
@UserId private val userId: String,
|
||||
private val sendStateTask: SendStateTask,
|
||||
private val stateEventDataSource: StateEventDataSource,
|
||||
private val getActiveBeaconInfoForUserTask: GetActiveBeaconInfoForUserTask,
|
||||
) : StopLiveLocationShareTask {
|
||||
|
||||
override suspend fun execute(params: StopLiveLocationShareTask.Params): UpdateLiveLocationShareResult {
|
||||
val beaconInfoStateEvent = getLiveLocationBeaconInfoForUser(userId, params.roomId) ?: return getResultForIncorrectBeaconInfoEvent()
|
||||
val beaconInfoStateEvent = getActiveLiveLocationBeaconInfoForUser(params.roomId) ?: return getResultForIncorrectBeaconInfoEvent()
|
||||
val stateKey = beaconInfoStateEvent.stateKey ?: return getResultForIncorrectBeaconInfoEvent()
|
||||
val content = beaconInfoStateEvent.getClearContent()?.toModel<MessageBeaconInfoContent>() ?: return getResultForIncorrectBeaconInfoEvent()
|
||||
val updatedContent = content.copy(isLive = false).toContent()
|
||||
@ -68,17 +64,10 @@ internal class DefaultStopLiveLocationShareTask @Inject constructor(
|
||||
private fun getResultForIncorrectBeaconInfoEvent() =
|
||||
UpdateLiveLocationShareResult.Failure(Exception("incorrect last beacon info event"))
|
||||
|
||||
private fun getLiveLocationBeaconInfoForUser(userId: String, roomId: String): Event? {
|
||||
return EventType.STATE_ROOM_BEACON_INFO
|
||||
.mapNotNull {
|
||||
stateEventDataSource.getStateEvent(
|
||||
roomId = roomId,
|
||||
eventType = it,
|
||||
stateKey = QueryStringValue.Equals(userId)
|
||||
)
|
||||
}
|
||||
.firstOrNull { beaconInfoEvent ->
|
||||
beaconInfoEvent.getClearContent()?.toModel<MessageBeaconInfoContent>()?.isLive.orFalse()
|
||||
}
|
||||
private suspend fun getActiveLiveLocationBeaconInfoForUser(roomId: String): Event? {
|
||||
val params = GetActiveBeaconInfoForUserTask.Params(
|
||||
roomId = roomId
|
||||
)
|
||||
return getActiveBeaconInfoForUserTask.execute(params)
|
||||
}
|
||||
}
|
||||
|
@ -63,10 +63,11 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
|
||||
private val roomArgsMap = mutableMapOf<String, RoomArgs>()
|
||||
var callback: Callback? = null
|
||||
private val jobs = mutableListOf<Job>()
|
||||
private var startInProgress = false
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
Timber.i("### LocationSharingService.onCreate")
|
||||
Timber.i("onCreate")
|
||||
|
||||
initLocationTracking()
|
||||
}
|
||||
@ -85,9 +86,11 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
|
||||
}
|
||||
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
startInProgress = true
|
||||
|
||||
val roomArgs = intent?.getParcelableExtra(EXTRA_ROOM_ARGS) as? RoomArgs
|
||||
|
||||
Timber.i("### LocationSharingService.onStartCommand. sessionId - roomId ${roomArgs?.sessionId} - ${roomArgs?.roomId}")
|
||||
Timber.i("onStartCommand. sessionId - roomId ${roomArgs?.sessionId} - ${roomArgs?.roomId}")
|
||||
|
||||
if (roomArgs != null) {
|
||||
// Show a sticky notification
|
||||
@ -100,6 +103,8 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
|
||||
}
|
||||
}
|
||||
|
||||
startInProgress = false
|
||||
|
||||
return START_STICKY
|
||||
}
|
||||
|
||||
@ -124,19 +129,19 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
|
||||
}
|
||||
}
|
||||
?: run {
|
||||
Timber.w("### LocationSharingService.sendStartingLiveBeaconInfo error, no received beacon info id")
|
||||
Timber.w("sendStartingLiveBeaconInfo error, no received beacon info id")
|
||||
tryToDestroyMe()
|
||||
}
|
||||
}
|
||||
|
||||
private fun stopSharingLocation(roomId: String) {
|
||||
Timber.i("### LocationSharingService.stopSharingLocation for $roomId")
|
||||
removeRoomArgs(roomId)
|
||||
private fun stopSharingLocation(beaconEventId: String) {
|
||||
Timber.i("stopSharingLocation for beacon $beaconEventId")
|
||||
removeRoomArgs(beaconEventId)
|
||||
tryToDestroyMe()
|
||||
}
|
||||
|
||||
private fun onLocationUpdate(locationData: LocationData) {
|
||||
Timber.i("### LocationSharingService.onLocationUpdate. Uncertainty: ${locationData.uncertainty}")
|
||||
Timber.i("onLocationUpdate. Uncertainty: ${locationData.uncertainty}")
|
||||
|
||||
// Emit location update to all rooms in which live location sharing is active
|
||||
roomArgsMap.toMap().forEach { item ->
|
||||
@ -167,7 +172,7 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
|
||||
}
|
||||
|
||||
private fun tryToDestroyMe() {
|
||||
if (roomArgsMap.isEmpty()) {
|
||||
if (startInProgress.not() && roomArgsMap.isEmpty()) {
|
||||
Timber.i("### LocationSharingService. Destroying self, time is up for all rooms")
|
||||
stopSelf()
|
||||
}
|
||||
@ -182,21 +187,21 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
|
||||
}
|
||||
|
||||
private fun addRoomArgs(beaconEventId: String, roomArgs: RoomArgs) {
|
||||
Timber.i("adding roomArgs for beaconEventId: $beaconEventId")
|
||||
roomArgsMap[beaconEventId] = roomArgs
|
||||
}
|
||||
|
||||
private fun removeRoomArgs(roomId: String) {
|
||||
roomArgsMap.toMap()
|
||||
.filter { it.value.roomId == roomId }
|
||||
.forEach { roomArgsMap.remove(it.key) }
|
||||
private fun removeRoomArgs(beaconEventId: String) {
|
||||
Timber.i("removing roomArgs for beaconEventId: $beaconEventId")
|
||||
roomArgsMap.remove(beaconEventId)
|
||||
}
|
||||
|
||||
private fun listenForLiveSummaryChanges(roomId: String, eventId: String) {
|
||||
private fun listenForLiveSummaryChanges(roomId: String, beaconEventId: String) {
|
||||
launchWithActiveSession { session ->
|
||||
val job = getLiveLocationShareSummaryUseCase.execute(roomId, eventId)
|
||||
val job = getLiveLocationShareSummaryUseCase.execute(roomId, beaconEventId)
|
||||
.distinctUntilChangedBy { it.isActive }
|
||||
.filter { it.isActive == false }
|
||||
.onEach { stopSharingLocation(roomId) }
|
||||
.onEach { stopSharingLocation(beaconEventId) }
|
||||
.launchIn(session.coroutineScope)
|
||||
jobs.add(job)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user