From e55c378683f5026055051ce6eb80fa0e32fb2c11 Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Wed, 15 Jun 2022 10:01:35 +0200 Subject: [PATCH] Catching crash when offline during start of a live location share --- .../room/location/LocationSharingService.kt | 4 +-- .../location/UpdateLiveLocationShareResult.kt | 32 +++++++++++++++++++ .../location/DefaultLocationSharingService.kt | 3 +- .../location/StartLiveLocationShareTask.kt | 17 ++++++++-- .../location/StopLiveLocationShareTask.kt | 1 + .../location/LocationSharingService.kt | 28 +++++++++++----- 6 files changed, 71 insertions(+), 14 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/location/UpdateLiveLocationShareResult.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/location/LocationSharingService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/location/LocationSharingService.kt index 11b74ecd7f..ce0b746d4f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/location/LocationSharingService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/location/LocationSharingService.kt @@ -46,9 +46,9 @@ interface LocationSharingService { /** * Starts sharing live location in the room. * @param timeoutMillis timeout of the live in milliseconds - * @return the id of the created beacon info event + * @return the result of the update of the live */ - suspend fun startLiveLocationShare(timeoutMillis: Long): String + suspend fun startLiveLocationShare(timeoutMillis: Long): UpdateLiveLocationShareResult /** * Stops sharing live location in the room. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/location/UpdateLiveLocationShareResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/location/UpdateLiveLocationShareResult.kt new file mode 100644 index 0000000000..6c6bc1029a --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/location/UpdateLiveLocationShareResult.kt @@ -0,0 +1,32 @@ +/* + * 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 org.matrix.android.sdk.api.session.room.location + +/** + * Represents the result of an update of live location share like a start or a stop. + */ +sealed interface UpdateLiveLocationShareResult { + /** + * @param beaconEventId event id of the updated state event + */ + data class Success(val beaconEventId: String) : UpdateLiveLocationShareResult + + /** + * @param error thrown during the update + */ + data class Failure(val error: Throwable) : UpdateLiveLocationShareResult +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/location/DefaultLocationSharingService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/location/DefaultLocationSharingService.kt index 3fa00fa077..c15cdda6f3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/location/DefaultLocationSharingService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/location/DefaultLocationSharingService.kt @@ -22,6 +22,7 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import org.matrix.android.sdk.api.session.room.location.LocationSharingService +import org.matrix.android.sdk.api.session.room.location.UpdateLiveLocationShareResult import org.matrix.android.sdk.api.session.room.model.livelocation.LiveLocationShareAggregatedSummary import org.matrix.android.sdk.api.util.Cancelable import org.matrix.android.sdk.internal.database.mapper.LiveLocationShareAggregatedSummaryMapper @@ -66,7 +67,7 @@ internal class DefaultLocationSharingService @AssistedInject constructor( return sendLiveLocationTask.execute(params) } - override suspend fun startLiveLocationShare(timeoutMillis: Long): String { + override suspend fun startLiveLocationShare(timeoutMillis: Long): UpdateLiveLocationShareResult { val params = StartLiveLocationShareTask.Params( roomId = roomId, timeoutMillis = timeoutMillis diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/location/StartLiveLocationShareTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/location/StartLiveLocationShareTask.kt index 7da67d7539..bf6a0049d8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/location/StartLiveLocationShareTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/location/StartLiveLocationShareTask.kt @@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.session.room.location 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.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 @@ -25,20 +26,21 @@ import org.matrix.android.sdk.internal.task.Task import org.matrix.android.sdk.internal.util.time.Clock import javax.inject.Inject -internal interface StartLiveLocationShareTask : Task { +internal interface StartLiveLocationShareTask : Task { data class Params( val roomId: String, val timeoutMillis: Long, ) } +// TODO update unit test internal class DefaultStartLiveLocationShareTask @Inject constructor( @UserId private val userId: String, private val clock: Clock, private val sendStateTask: SendStateTask, ) : StartLiveLocationShareTask { - override suspend fun execute(params: StartLiveLocationShareTask.Params): String { + override suspend fun execute(params: StartLiveLocationShareTask.Params): UpdateLiveLocationShareResult { val beaconContent = MessageBeaconInfoContent( timeout = params.timeoutMillis, isLive = true, @@ -51,6 +53,15 @@ internal class DefaultStartLiveLocationShareTask @Inject constructor( eventType = eventType, body = beaconContent ) - return 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) + } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/location/StopLiveLocationShareTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/location/StopLiveLocationShareTask.kt index 1c282684a4..8f2fa27288 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/location/StopLiveLocationShareTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/location/StopLiveLocationShareTask.kt @@ -41,6 +41,7 @@ internal class DefaultStopLiveLocationShareTask @Inject constructor( 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 diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingService.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingService.kt index 77f3abcc28..7df84a4cee 100644 --- a/vector/src/main/java/im/vector/app/features/location/LocationSharingService.kt +++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingService.kt @@ -30,6 +30,7 @@ import kotlinx.coroutines.launch import kotlinx.parcelize.Parcelize import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.getRoom +import org.matrix.android.sdk.api.session.room.location.UpdateLiveLocationShareResult import timber.log.Timber import java.util.Timer import java.util.TimerTask @@ -95,13 +96,20 @@ class LocationSharingService : VectorService(), LocationTracker.Callback { ?.startLiveLocationShare(timeoutMillis = roomArgs.durationMillis) beaconEventId - ?.takeUnless { it.isEmpty() } - ?.let { - roomArgsMap[it] = roomArgs - locationTracker.requestLastKnownLocation() + ?.let { result -> + when (result) { + is UpdateLiveLocationShareResult.Success -> { + roomArgsMap[result.beaconEventId] = roomArgs + locationTracker.requestLastKnownLocation() + } + is UpdateLiveLocationShareResult.Failure -> { + tryToDestroyMe() + } + } } ?: run { Timber.w("### LocationSharingService.sendStartingLiveBeaconInfo error, no received beacon info id") + tryToDestroyMe() } } @@ -132,10 +140,7 @@ class LocationSharingService : VectorService(), LocationTracker.Callback { .map { it.key } beaconIds.forEach { roomArgsMap.remove(it) } - if (roomArgsMap.isEmpty()) { - Timber.i("### LocationSharingService. Destroying self, time is up for all rooms") - destroyMe() - } + tryToDestroyMe() } } @@ -178,6 +183,13 @@ class LocationSharingService : VectorService(), LocationTracker.Callback { stopSelf() } + private fun tryToDestroyMe() { + if (roomArgsMap.isEmpty()) { + Timber.i("### LocationSharingService. Destroying self, time is up for all rooms") + destroyMe() + } + } + private fun destroyMe() { locationTracker.removeCallback(this) timers.forEach { it.cancel() }