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.
*/
suspend fun stopLiveLocationShare()
suspend fun stopLiveLocationShare(): UpdateLiveLocationShareResult
/**
* 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)
}
override suspend fun stopLiveLocationShare() {
override suspend fun stopLiveLocationShare(): UpdateLiveLocationShareResult {
val params = StopLiveLocationShareTask.Params(
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.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
@ -29,23 +30,23 @@ import org.matrix.android.sdk.internal.session.room.state.StateEventDataSource
import org.matrix.android.sdk.internal.task.Task
import javax.inject.Inject
internal interface StopLiveLocationShareTask : Task<StopLiveLocationShareTask.Params, Unit> {
internal interface StopLiveLocationShareTask : Task<StopLiveLocationShareTask.Params, UpdateLiveLocationShareResult> {
data class Params(
val roomId: String,
)
}
// TODO update unit tests
internal class DefaultStopLiveLocationShareTask @Inject constructor(
@UserId private val userId: String,
private val sendStateTask: SendStateTask,
private val stateEventDataSource: StateEventDataSource,
) : StopLiveLocationShareTask {
@Throws
override suspend fun execute(params: StopLiveLocationShareTask.Params) {
val beaconInfoStateEvent = getLiveLocationBeaconInfoForUser(userId, params.roomId) ?: return
val stateKey = beaconInfoStateEvent.stateKey ?: return
val content = beaconInfoStateEvent.getClearContent()?.toModel<MessageBeaconInfoContent>() ?: return
override suspend fun execute(params: StopLiveLocationShareTask.Params): UpdateLiveLocationShareResult {
val beaconInfoStateEvent = getLiveLocationBeaconInfoForUser(userId, 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()
val sendStateTaskParams = SendStateTask.Params(
roomId = params.roomId,
@ -53,8 +54,20 @@ internal class DefaultStopLiveLocationShareTask @Inject constructor(
eventType = EventType.STATE_ROOM_BEACON_INFO.first(),
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? {
return EventType.STATE_ROOM_BEACON_INFO

View File

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

View File

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