Catching crash when offline during stop of a live location share

This commit is contained in:
Maxime NATUREL 2022-06-15 12:09:39 +02:00
parent e55c378683
commit 9eba3034db
5 changed files with 41 additions and 24 deletions

View File

@ -53,7 +53,7 @@ interface LocationSharingService {
/** /**
* Stops sharing live location in the room. * Stops sharing live location in the room.
*/ */
suspend fun stopLiveLocationShare() suspend fun stopLiveLocationShare(): UpdateLiveLocationShareResult
/** /**
* Returns a LiveData on the list of current running live location shares. * Returns a LiveData on the list of current running live location shares.

View File

@ -75,7 +75,7 @@ internal class DefaultLocationSharingService @AssistedInject constructor(
return startLiveLocationShareTask.execute(params) return startLiveLocationShareTask.execute(params)
} }
override suspend fun stopLiveLocationShare() { override suspend fun stopLiveLocationShare(): UpdateLiveLocationShareResult {
val params = StopLiveLocationShareTask.Params( val params = StopLiveLocationShareTask.Params(
roomId = roomId, roomId = roomId,
) )

View File

@ -22,6 +22,7 @@ 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.EventType
import org.matrix.android.sdk.api.session.events.model.toContent 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.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.api.session.room.model.message.MessageBeaconInfoContent
import org.matrix.android.sdk.internal.di.UserId 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.SendStateTask
@ -29,23 +30,23 @@ import org.matrix.android.sdk.internal.session.room.state.StateEventDataSource
import org.matrix.android.sdk.internal.task.Task import org.matrix.android.sdk.internal.task.Task
import javax.inject.Inject import javax.inject.Inject
internal interface StopLiveLocationShareTask : Task<StopLiveLocationShareTask.Params, Unit> { internal interface StopLiveLocationShareTask : Task<StopLiveLocationShareTask.Params, UpdateLiveLocationShareResult> {
data class Params( data class Params(
val roomId: String, val roomId: String,
) )
} }
// TODO update unit tests
internal class DefaultStopLiveLocationShareTask @Inject constructor( internal class DefaultStopLiveLocationShareTask @Inject constructor(
@UserId private val userId: String, @UserId private val userId: String,
private val sendStateTask: SendStateTask, private val sendStateTask: SendStateTask,
private val stateEventDataSource: StateEventDataSource, private val stateEventDataSource: StateEventDataSource,
) : StopLiveLocationShareTask { ) : StopLiveLocationShareTask {
@Throws override suspend fun execute(params: StopLiveLocationShareTask.Params): UpdateLiveLocationShareResult {
override suspend fun execute(params: StopLiveLocationShareTask.Params) { val beaconInfoStateEvent = getLiveLocationBeaconInfoForUser(userId, params.roomId) ?: return getResultForIncorrectBeaconInfoEvent()
val beaconInfoStateEvent = getLiveLocationBeaconInfoForUser(userId, params.roomId) ?: return val stateKey = beaconInfoStateEvent.stateKey ?: return getResultForIncorrectBeaconInfoEvent()
val stateKey = beaconInfoStateEvent.stateKey ?: return val content = beaconInfoStateEvent.getClearContent()?.toModel<MessageBeaconInfoContent>() ?: return getResultForIncorrectBeaconInfoEvent()
val content = beaconInfoStateEvent.getClearContent()?.toModel<MessageBeaconInfoContent>() ?: return
val updatedContent = content.copy(isLive = false).toContent() val updatedContent = content.copy(isLive = false).toContent()
val sendStateTaskParams = SendStateTask.Params( val sendStateTaskParams = SendStateTask.Params(
roomId = params.roomId, roomId = params.roomId,
@ -53,8 +54,20 @@ internal class DefaultStopLiveLocationShareTask @Inject constructor(
eventType = EventType.STATE_ROOM_BEACON_INFO.first(), eventType = EventType.STATE_ROOM_BEACON_INFO.first(),
body = updatedContent body = updatedContent
) )
sendStateTask.executeRetry(sendStateTaskParams, 3) return try {
val eventId = sendStateTask.executeRetry(sendStateTaskParams, 3)
if (eventId.isNotEmpty()) {
UpdateLiveLocationShareResult.Success(eventId)
} else {
UpdateLiveLocationShareResult.Failure(Exception("empty event id for new state event"))
} }
} catch (error: Throwable) {
UpdateLiveLocationShareResult.Failure(error)
}
}
private fun getResultForIncorrectBeaconInfoEvent() =
UpdateLiveLocationShareResult.Failure(Exception("incorrect last beacon info event"))
private fun getLiveLocationBeaconInfoForUser(userId: String, roomId: String): Event? { private fun getLiveLocationBeaconInfoForUser(userId: String, roomId: String): Event? {
return EventType.STATE_ROOM_BEACON_INFO return EventType.STATE_ROOM_BEACON_INFO

View File

@ -131,9 +131,10 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
fun stopSharingLocation(roomId: String) { fun stopSharingLocation(roomId: String) {
Timber.i("### LocationSharingService.stopSharingLocation for $roomId") Timber.i("### LocationSharingService.stopSharingLocation for $roomId")
launchInIO { session ->
// Send a new beacon info state by setting live field as false // Send a new beacon info state by setting live field as false
sendStoppedBeaconInfo(roomId) when (sendStoppedBeaconInfo(session, roomId)) {
is UpdateLiveLocationShareResult.Success -> {
synchronized(roomArgsMap) { synchronized(roomArgsMap) {
val beaconIds = roomArgsMap val beaconIds = roomArgsMap
.filter { it.value.roomId == roomId } .filter { it.value.roomId == roomId }
@ -143,14 +144,16 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
tryToDestroyMe() tryToDestroyMe()
} }
} }
else -> Unit
}
}
}
private fun sendStoppedBeaconInfo(roomId: String) { private suspend fun sendStoppedBeaconInfo(session: Session, roomId: String): UpdateLiveLocationShareResult? {
launchInIO { session -> return session.getRoom(roomId)
session.getRoom(roomId)
?.locationSharingService() ?.locationSharingService()
?.stopLiveLocationShare() ?.stopLiveLocationShare()
} }
}
override fun onLocationUpdate(locationData: LocationData) { override fun onLocationUpdate(locationData: LocationData) {
Timber.i("### LocationSharingService.onLocationUpdate. Uncertainty: ${locationData.uncertainty}") Timber.i("### LocationSharingService.onLocationUpdate. Uncertainty: ${locationData.uncertainty}")

View File

@ -28,6 +28,7 @@ class LocationSharingServiceConnection @Inject constructor(
) : ServiceConnection { ) : ServiceConnection {
interface Callback { interface Callback {
// TODO add onLocationServiceError()
fun onLocationServiceRunning() fun onLocationServiceRunning()
fun onLocationServiceStopped() fun onLocationServiceStopped()
} }