Fix send of the first location after start

This commit is contained in:
Maxime NATUREL 2022-05-04 16:02:23 +02:00
parent 0a21bd4b78
commit 6622651a90
2 changed files with 51 additions and 29 deletions

View File

@ -55,7 +55,10 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
private val binder = LocalBinder()
private var roomArgsList = mutableListOf<RoomArgs>()
/**
* Keep track of a map between beacon event Id starting the live and RoomArgs.
*/
private var roomArgsMap = mutableMapOf<String, RoomArgs>()
private var timers = mutableListOf<Timer>()
override fun onCreate() {
@ -73,8 +76,6 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
Timber.i("### LocationSharingService.onStartCommand. sessionId - roomId ${roomArgs?.sessionId} - ${roomArgs?.roomId}")
if (roomArgs != null) {
roomArgsList.add(roomArgs)
// Show a sticky notification
val notification = notificationUtils.buildLiveLocationSharingNotification()
startForeground(roomArgs.roomId.hashCode(), notification)
@ -87,7 +88,7 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
.getSafeActiveSession()
?.let { session ->
session.coroutineScope.launch(session.coroutineDispatchers.io) {
sendLiveBeaconInfo(session, roomArgs)
sendStartingLiveBeaconInfo(session, roomArgs)
}
}
}
@ -95,7 +96,7 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
return START_STICKY
}
private suspend fun sendLiveBeaconInfo(session: Session, roomArgs: RoomArgs) {
private suspend fun sendStartingLiveBeaconInfo(session: Session, roomArgs: RoomArgs) {
val beaconContent = MessageBeaconInfoContent(
timeout = roomArgs.durationMillis,
isLive = true,
@ -103,7 +104,7 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
).toContent()
val stateKey = session.myUserId
session
val beaconEventId = session
.getRoom(roomArgs.roomId)
?.stateService()
?.sendStateEvent(
@ -111,6 +112,16 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
stateKey = stateKey,
body = beaconContent
)
beaconEventId
?.takeUnless { it.isEmpty() }
?.let {
roomArgsMap[it] = roomArgs
locationTracker.requestLastKnownLocation()
}
?: run {
Timber.w("### LocationSharingService.sendStartingLiveBeaconInfo error, no received beacon info id")
}
}
private fun scheduleTimer(roomId: String, durationMillis: Long) {
@ -134,9 +145,13 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
// Send a new beacon info state by setting live field as false
sendStoppedBeaconInfo(roomId)
synchronized(roomArgsList) {
roomArgsList.removeAll { it.roomId == roomId }
if (roomArgsList.isEmpty()) {
synchronized(roomArgsMap) {
val beaconIds = roomArgsMap
.filter { it.value.roomId == roomId }
.map { it.key }
beaconIds.forEach { roomArgsMap.remove(it) }
if (roomArgsMap.isEmpty()) {
Timber.i("### LocationSharingService. Destroying self, time is up for all rooms")
destroyMe()
}
@ -156,16 +171,17 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
override fun onLocationUpdate(locationData: LocationData) {
Timber.i("### LocationSharingService.onLocationUpdate. Uncertainty: ${locationData.uncertainty}")
val session = activeSessionHolder.getSafeActiveSession()
// Emit location update to all rooms in which live location sharing is active
session?.coroutineScope?.launch(session.coroutineDispatchers.io) {
roomArgsList.toList().forEach { roomArg ->
sendLiveLocation(roomArg.roomId, locationData)
}
roomArgsMap.toMap().forEach { item ->
sendLiveLocation(item.value.roomId, item.key, locationData)
}
}
private suspend fun sendLiveLocation(roomId: String, locationData: LocationData) {
private fun sendLiveLocation(
roomId: String,
beaconInfoEventId: String,
locationData: LocationData
) {
val session = activeSessionHolder.getSafeActiveSession()
val room = session?.getRoom(roomId)
val userId = session?.myUserId
@ -174,19 +190,13 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
return
}
room
.stateService()
.getLiveLocationBeaconInfo(userId, true)
?.eventId
?.let {
room.sendService().sendLiveLocation(
beaconInfoEventId = it,
beaconInfoEventId = beaconInfoEventId,
latitude = locationData.latitude,
longitude = locationData.longitude,
uncertainty = locationData.uncertainty
)
}
}
override fun onLocationProviderIsNotAvailable() {
stopForeground(true)

View File

@ -40,10 +40,12 @@ class LocationTracker @Inject constructor(
fun onLocationProviderIsNotAvailable()
}
private var callbacks = mutableListOf<Callback>()
private val callbacks = mutableListOf<Callback>()
private var hasGpsProviderLiveLocation = false
private var lastLocation: LocationData? = null
@RequiresPermission(anyOf = [Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION])
fun start() {
Timber.d("## LocationTracker. start()")
@ -92,6 +94,14 @@ class LocationTracker @Inject constructor(
callbacks.clear()
}
/**
* Request the last known location. It will be given async through Callback.
* Please ensure adding a callback to receive the value.
*/
fun requestLastKnownLocation() {
lastLocation?.let { location -> callbacks.forEach { it.onLocationUpdate(location) } }
}
fun addCallback(callback: Callback) {
if (!callbacks.contains(callback)) {
callbacks.add(callback)
@ -127,7 +137,9 @@ class LocationTracker @Inject constructor(
}
}
}
callbacks.forEach { it.onLocationUpdate(location.toLocationData()) }
val locationData = location.toLocationData()
lastLocation = locationData
callbacks.forEach { it.onLocationUpdate(locationData) }
}
override fun onProviderDisabled(provider: String) {