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 ce0b746d4f..7e5906b517 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 @@ -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. 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 c15cdda6f3..015c1cca0b 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 @@ -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, ) 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 8f2fa27288..dc12054d7b 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 @@ -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 { +internal interface StopLiveLocationShareTask : Task { 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() ?: 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() ?: return getResultForIncorrectBeaconInfoEvent() val updatedContent = content.copy(isLive = false).toContent() val sendStateTaskParams = SendStateTask.Params( roomId = params.roomId, @@ -53,9 +54,21 @@ 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 .mapNotNull { 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 7df84a4cee..27eea498e4 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 @@ -131,25 +131,28 @@ class LocationSharingService : VectorService(), LocationTracker.Callback { fun stopSharingLocation(roomId: String) { Timber.i("### LocationSharingService.stopSharingLocation for $roomId") - // Send a new beacon info state by setting live field as false - sendStoppedBeaconInfo(roomId) + launchInIO { session -> + // Send a new beacon info state by setting live field as false + when (sendStoppedBeaconInfo(session, roomId)) { + is UpdateLiveLocationShareResult.Success -> { + synchronized(roomArgsMap) { + val beaconIds = roomArgsMap + .filter { it.value.roomId == roomId } + .map { it.key } + beaconIds.forEach { roomArgsMap.remove(it) } - synchronized(roomArgsMap) { - val beaconIds = roomArgsMap - .filter { it.value.roomId == roomId } - .map { it.key } - beaconIds.forEach { roomArgsMap.remove(it) } - - tryToDestroyMe() + tryToDestroyMe() + } + } + else -> Unit + } } } - private fun sendStoppedBeaconInfo(roomId: String) { - launchInIO { session -> - session.getRoom(roomId) - ?.locationSharingService() - ?.stopLiveLocationShare() - } + private suspend fun sendStoppedBeaconInfo(session: Session, roomId: String): UpdateLiveLocationShareResult? { + return session.getRoom(roomId) + ?.locationSharingService() + ?.stopLiveLocationShare() } override fun onLocationUpdate(locationData: LocationData) { diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingServiceConnection.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingServiceConnection.kt index e72f77531b..97f447ec4b 100644 --- a/vector/src/main/java/im/vector/app/features/location/LocationSharingServiceConnection.kt +++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingServiceConnection.kt @@ -28,6 +28,7 @@ class LocationSharingServiceConnection @Inject constructor( ) : ServiceConnection { interface Callback { + // TODO add onLocationServiceError() fun onLocationServiceRunning() fun onLocationServiceStopped() }