From 29f48249e2670c99a0ea91af53b9c9cdc6d21d9f Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Thu, 9 Jun 2022 15:32:28 +0200 Subject: [PATCH] Start live location share API --- .../room/location/LocationSharingService.kt | 10 ++++ .../api/session/room/state/StateService.kt | 2 + .../sdk/internal/session/room/RoomModule.kt | 5 ++ .../location/DefaultLocationSharingService.kt | 9 +++ .../location/StartLiveLocationShareTask.kt | 57 +++++++++++++++++++ .../location/LocationSharingService.kt | 20 +------ 6 files changed, 85 insertions(+), 18 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/location/StartLiveLocationShareTask.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 dd48d51f45..418ba6fbf2 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 @@ -23,5 +23,15 @@ import org.matrix.android.sdk.api.session.room.model.livelocation.LiveLocationSh * Manage all location sharing related features. */ 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 + */ + suspend fun startLiveLocationShare(timeoutMillis: Long): String + + /** + * Returns a LiveData on the list of current running live location shares. + */ fun getRunningLiveLocationShareSummaries(): LiveData> } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateService.kt index 49c0debe1b..8fb3afe36b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateService.kt @@ -66,12 +66,14 @@ interface StateService { */ suspend fun deleteAvatar() + // TODO delete /** * Stops sharing live location in the room. * @param userId user id */ suspend fun stopLiveLocation(userId: String) + // TODO delete /** * Returns beacon info state event of a user. * @param userId user id who is sharing location diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomModule.kt index f3845f1f15..164b6cd4e5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/RoomModule.kt @@ -51,6 +51,8 @@ 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.DefaultStartLiveLocationShareTask +import org.matrix.android.sdk.internal.session.room.location.StartLiveLocationShareTask import org.matrix.android.sdk.internal.session.room.membership.DefaultLoadRoomMembersTask import org.matrix.android.sdk.internal.session.room.membership.LoadRoomMembersTask import org.matrix.android.sdk.internal.session.room.membership.admin.DefaultMembershipAdminTask @@ -299,4 +301,7 @@ internal abstract class RoomModule { @Binds abstract fun bindFetchThreadSummariesTask(task: DefaultFetchThreadSummariesTask): FetchThreadSummariesTask + + @Binds + abstract fun bindStartLiveLocationShareTask(task: DefaultStartLiveLocationShareTask): StartLiveLocationShareTask } 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 8cf6fcdfbf..078c261b8a 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 @@ -32,6 +32,7 @@ import org.matrix.android.sdk.internal.di.SessionDatabase internal class DefaultLocationSharingService @AssistedInject constructor( @Assisted private val roomId: String, @SessionDatabase private val monarchy: Monarchy, + private val startLiveLocationShareTask: StartLiveLocationShareTask, private val liveLocationShareAggregatedSummaryMapper: LiveLocationShareAggregatedSummaryMapper, ) : LocationSharingService { @@ -40,6 +41,14 @@ internal class DefaultLocationSharingService @AssistedInject constructor( fun create(roomId: String): DefaultLocationSharingService } + override suspend fun startLiveLocationShare(timeoutMillis: Long): String { + val params = StartLiveLocationShareTask.Params( + roomId = roomId, + timeoutMillis = timeoutMillis + ) + return startLiveLocationShareTask.execute(params) + } + override fun getRunningLiveLocationShareSummaries(): LiveData> { return monarchy.findAllMappedWithChanges( { LiveLocationShareAggregatedSummaryEntity.findRunningLiveInRoom(it, roomId = roomId) }, 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 new file mode 100644 index 0000000000..85bd90cf20 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/location/StartLiveLocationShareTask.kt @@ -0,0 +1,57 @@ +/* + * 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.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.toContent +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.task.Task +import org.matrix.android.sdk.internal.util.time.Clock +import javax.inject.Inject + +internal interface StartLiveLocationShareTask : Task { + data class Params( + val roomId: String, + val timeoutMillis: Long, + ) +} + +// TODO add unit tests +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 { + val beaconContent = MessageBeaconInfoContent( + timeout = params.timeoutMillis, + isLive = true, + unstableTimestampMillis = clock.epochMillis() + ).toContent() + val eventType = EventType.STATE_ROOM_BEACON_INFO.first() + val sendStateTaskParams = SendStateTask.Params( + roomId = params.roomId, + stateKey = userId, + eventType = eventType, + body = beaconContent + ) + return sendStateTask.executeRetry(sendStateTaskParams, 3) + } +} 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 62aba9318c..c9479f4536 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 @@ -23,16 +23,12 @@ import android.os.Parcelable import dagger.hilt.android.AndroidEntryPoint import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.services.VectorService -import im.vector.app.core.time.Clock import im.vector.app.features.notifications.NotificationUtils import im.vector.app.features.session.coroutineScope import kotlinx.coroutines.launch import kotlinx.parcelize.Parcelize import org.matrix.android.sdk.api.session.Session -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.getRoom -import org.matrix.android.sdk.api.session.room.model.message.MessageBeaconInfoContent import timber.log.Timber import java.util.Timer import java.util.TimerTask @@ -51,7 +47,6 @@ class LocationSharingService : VectorService(), LocationTracker.Callback { @Inject lateinit var notificationUtils: NotificationUtils @Inject lateinit var locationTracker: LocationTracker @Inject lateinit var activeSessionHolder: ActiveSessionHolder - @Inject lateinit var clock: Clock private val binder = LocalBinder() @@ -97,21 +92,10 @@ class LocationSharingService : VectorService(), LocationTracker.Callback { } private suspend fun sendStartingLiveBeaconInfo(session: Session, roomArgs: RoomArgs) { - val beaconContent = MessageBeaconInfoContent( - timeout = roomArgs.durationMillis, - isLive = true, - unstableTimestampMillis = clock.epochMillis() - ).toContent() - - val stateKey = session.myUserId val beaconEventId = session .getRoom(roomArgs.roomId) - ?.stateService() - ?.sendStateEvent( - eventType = EventType.STATE_ROOM_BEACON_INFO.first(), - stateKey = stateKey, - body = beaconContent - ) + ?.locationSharingService() + ?.startLiveLocationShare(timeoutMillis = roomArgs.durationMillis) beaconEventId ?.takeUnless { it.isEmpty() }