Send live location API

This commit is contained in:
Maxime NATUREL 2022-06-09 17:40:14 +02:00
parent 9b61c1aead
commit 7b159c5b71
7 changed files with 108 additions and 45 deletions

View File

@ -33,6 +33,16 @@ interface LocationSharingService {
*/
suspend fun sendStaticLocation(latitude: Double, longitude: Double, uncertainty: Double?, isUserLocation: Boolean): Cancelable
/**
* Send a live location event to the room.
* To get the beacon info event id, [startLiveLocationShare] must be called before sending live location updates.
* @param beaconInfoEventId event id of the initial beacon info state event
* @param latitude required latitude of the location
* @param longitude required longitude of the location
* @param uncertainty Accuracy of the location in meters
*/
suspend fun sendLiveLocation(beaconInfoEventId: String, latitude: Double, longitude: Double, uncertainty: Double?): Cancelable
/**
* Starts sharing live location in the room.
* @param timeoutMillis timeout of the live in milliseconds

View File

@ -142,15 +142,6 @@ interface SendService {
*/
fun resendMediaMessage(localEcho: TimelineEvent): Cancelable
/**
* Send a live location event to the room. beacon_info state event has to be sent before sending live location updates.
* @param beaconInfoEventId event id of the initial beacon info state event
* @param latitude required latitude of the location
* @param longitude required longitude of the location
* @param uncertainty Accuracy of the location in meters
*/
fun sendLiveLocation(beaconInfoEventId: String, latitude: Double, longitude: Double, uncertainty: Double?): Cancelable
/**
* Remove this failed message from the timeline.
* @param localEcho the unsent local echo

View File

@ -51,9 +51,11 @@ 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.DefaultSendLiveLocationTask
import org.matrix.android.sdk.internal.session.room.location.DefaultSendStaticLocationTask
import org.matrix.android.sdk.internal.session.room.location.DefaultStartLiveLocationShareTask
import org.matrix.android.sdk.internal.session.room.location.DefaultStopLiveLocationShareTask
import org.matrix.android.sdk.internal.session.room.location.SendLiveLocationTask
import org.matrix.android.sdk.internal.session.room.location.SendStaticLocationTask
import org.matrix.android.sdk.internal.session.room.location.StartLiveLocationShareTask
import org.matrix.android.sdk.internal.session.room.location.StopLiveLocationShareTask
@ -314,4 +316,7 @@ internal abstract class RoomModule {
@Binds
abstract fun bindSendStaticLocationTask(task: DefaultSendStaticLocationTask): SendStaticLocationTask
@Binds
abstract fun bindSendLiveLocationTask(task: DefaultSendLiveLocationTask): SendLiveLocationTask
}

View File

@ -34,6 +34,7 @@ internal class DefaultLocationSharingService @AssistedInject constructor(
@Assisted private val roomId: String,
@SessionDatabase private val monarchy: Monarchy,
private val sendStaticLocationTask: SendStaticLocationTask,
private val sendLiveLocationTask: SendLiveLocationTask,
private val startLiveLocationShareTask: StartLiveLocationShareTask,
private val stopLiveLocationShareTask: StopLiveLocationShareTask,
private val liveLocationShareAggregatedSummaryMapper: LiveLocationShareAggregatedSummaryMapper,
@ -50,11 +51,22 @@ internal class DefaultLocationSharingService @AssistedInject constructor(
latitude = latitude,
longitude = longitude,
uncertainty = uncertainty,
isUserLocation = isUserLocation
isUserLocation = isUserLocation,
)
return sendStaticLocationTask.execute(params)
}
override suspend fun sendLiveLocation(beaconInfoEventId: String, latitude: Double, longitude: Double, uncertainty: Double?): Cancelable {
val params = SendLiveLocationTask.Params(
beaconInfoEventId = beaconInfoEventId,
roomId = roomId,
latitude = latitude,
longitude = longitude,
uncertainty = uncertainty,
)
return sendLiveLocationTask.execute(params)
}
override suspend fun startLiveLocationShare(timeoutMillis: Long): String {
val params = StartLiveLocationShareTask.Params(
roomId = roomId,

View File

@ -0,0 +1,52 @@
/*
* 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.util.Cancelable
import org.matrix.android.sdk.internal.session.room.send.LocalEchoEventFactory
import org.matrix.android.sdk.internal.session.room.send.queue.EventSenderProcessor
import org.matrix.android.sdk.internal.task.Task
import javax.inject.Inject
internal interface SendLiveLocationTask : Task<SendLiveLocationTask.Params, Cancelable> {
data class Params(
val roomId: String,
val beaconInfoEventId: String,
val latitude: Double,
val longitude: Double,
val uncertainty: Double?,
)
}
// TODO add unit tests
internal class DefaultSendLiveLocationTask @Inject constructor(
private val localEchoEventFactory: LocalEchoEventFactory,
private val eventSenderProcessor: EventSenderProcessor,
) : SendLiveLocationTask {
override suspend fun execute(params: SendLiveLocationTask.Params): Cancelable {
val event = localEchoEventFactory.createLiveLocationEvent(
beaconInfoEventId = params.beaconInfoEventId,
roomId = params.roomId,
latitude = params.latitude,
longitude = params.longitude,
uncertainty = params.uncertainty,
)
localEchoEventFactory.createLocalEcho(event)
return eventSenderProcessor.postEvent(event)
}
}

View File

@ -129,12 +129,6 @@ internal class DefaultSendService @AssistedInject constructor(
.let { sendEvent(it) }
}
override fun sendLiveLocation(beaconInfoEventId: String, latitude: Double, longitude: Double, uncertainty: Double?): Cancelable {
return localEchoEventFactory.createLiveLocationEvent(beaconInfoEventId, roomId, latitude, longitude, uncertainty)
.also { createLocalEcho(it) }
.let { sendEvent(it) }
}
override fun redactEvent(event: Event, reason: String?): Cancelable {
// TODO manage media/attachements?
val redactionEcho = localEchoEventFactory.createRedactEvent(roomId, event.eventId!!, reason)

View File

@ -25,6 +25,7 @@ import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.services.VectorService
import im.vector.app.features.notifications.NotificationUtils
import im.vector.app.features.session.coroutineScope
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import kotlinx.parcelize.Parcelize
import org.matrix.android.sdk.api.session.Session
@ -79,13 +80,9 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
scheduleTimer(roomArgs.roomId, roomArgs.durationMillis)
// Send beacon info state event
activeSessionHolder
.getSafeActiveSession()
?.let { session ->
session.coroutineScope.launch(session.coroutineDispatchers.io) {
sendStartingLiveBeaconInfo(session, roomArgs)
}
}
launchInIO { session ->
sendStartingLiveBeaconInfo(session, roomArgs)
}
}
return START_STICKY
@ -143,15 +140,11 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
}
private fun sendStoppedBeaconInfo(roomId: String) {
activeSessionHolder
.getSafeActiveSession()
?.let { session ->
session.coroutineScope.launch(session.coroutineDispatchers.io) {
session.getRoom(roomId)
?.locationSharingService()
?.stopLiveLocationShare()
}
}
launchInIO { session ->
session.getRoom(roomId)
?.locationSharingService()
?.stopLiveLocationShare()
}
}
override fun onLocationUpdate(locationData: LocationData) {
@ -168,20 +161,16 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
beaconInfoEventId: String,
locationData: LocationData
) {
val session = activeSessionHolder.getSafeActiveSession()
val room = session?.getRoom(roomId)
val userId = session?.myUserId
if (room == null || userId == null) {
return
launchInIO { session ->
session.getRoom(roomId)
?.locationSharingService()
?.sendLiveLocation(
beaconInfoEventId = beaconInfoEventId,
latitude = locationData.latitude,
longitude = locationData.longitude,
uncertainty = locationData.uncertainty
)
}
room.sendService().sendLiveLocation(
beaconInfoEventId = beaconInfoEventId,
latitude = locationData.latitude,
longitude = locationData.longitude,
uncertainty = locationData.uncertainty
)
}
override fun onNoLocationProviderAvailable() {
@ -202,6 +191,16 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
destroyMe()
}
private fun launchInIO(block: suspend CoroutineScope.(Session) -> Unit) =
activeSessionHolder
.getSafeActiveSession()
?.let { session ->
session.coroutineScope.launch(
context = session.coroutineDispatchers.io,
block = { block(session) }
)
}
override fun onBind(intent: Intent?): IBinder {
return binder
}