mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-03-18 04:08:44 +03:00
Observing live status in DB from location sharing Android service
This commit is contained in:
parent
3cffedd353
commit
81e14c7c3b
7 changed files with 37 additions and 54 deletions
|
@ -16,6 +16,7 @@
|
|||
|
||||
package org.matrix.android.sdk.api.session.room.location
|
||||
|
||||
import androidx.annotation.MainThread
|
||||
import androidx.lifecycle.LiveData
|
||||
import org.matrix.android.sdk.api.session.room.model.livelocation.LiveLocationShareAggregatedSummary
|
||||
import org.matrix.android.sdk.api.util.Cancelable
|
||||
|
@ -60,11 +61,13 @@ interface LocationSharingService {
|
|||
/**
|
||||
* Returns a LiveData on the list of current running live location shares.
|
||||
*/
|
||||
@MainThread
|
||||
fun getRunningLiveLocationShareSummaries(): LiveData<List<LiveLocationShareAggregatedSummary>>
|
||||
|
||||
/**
|
||||
* Returns a LiveData on the live location share summary with the given eventId.
|
||||
* @param beaconInfoEventId event id of the initial beacon info state event
|
||||
*/
|
||||
@MainThread
|
||||
fun getLiveLocationShareSummary(beaconInfoEventId: String): LiveData<Optional<LiveLocationShareAggregatedSummary>>
|
||||
}
|
||||
|
|
|
@ -18,22 +18,27 @@ package im.vector.app.features.location
|
|||
|
||||
import android.content.Intent
|
||||
import android.os.Binder
|
||||
import android.os.Handler
|
||||
import android.os.IBinder
|
||||
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.features.location.live.GetLiveLocationShareSummaryUseCase
|
||||
import im.vector.app.features.notifications.NotificationUtils
|
||||
import im.vector.app.features.session.coroutineScope
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.distinctUntilChangedBy
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
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
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
|
@ -49,6 +54,7 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
|
|||
@Inject lateinit var notificationUtils: NotificationUtils
|
||||
@Inject lateinit var locationTracker: LocationTracker
|
||||
@Inject lateinit var activeSessionHolder: ActiveSessionHolder
|
||||
@Inject lateinit var getLiveLocationShareSummaryUseCase: GetLiveLocationShareSummaryUseCase
|
||||
|
||||
private val binder = LocalBinder()
|
||||
|
||||
|
@ -56,8 +62,9 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
|
|||
* Keep track of a map between beacon event Id starting the live and RoomArgs.
|
||||
*/
|
||||
private val roomArgsMap = mutableMapOf<String, RoomArgs>()
|
||||
private val timers = mutableListOf<Timer>()
|
||||
var callback: Callback? = null
|
||||
private val jobs = mutableListOf<Job>()
|
||||
private val mainHandler by lazy { Handler(mainLooper) }
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
|
@ -78,9 +85,6 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
|
|||
val notification = notificationUtils.buildLiveLocationSharingNotification()
|
||||
startForeground(roomArgs.roomId.hashCode(), notification)
|
||||
|
||||
// Schedule a timer to stop sharing
|
||||
scheduleTimer(roomArgs.roomId, roomArgs.durationMillis)
|
||||
|
||||
// Send beacon info state event
|
||||
launchInIO { session ->
|
||||
sendStartingLiveBeaconInfo(session, roomArgs)
|
||||
|
@ -101,6 +105,7 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
|
|||
when (result) {
|
||||
is UpdateLiveLocationShareResult.Success -> {
|
||||
addRoomArgs(result.beaconEventId, roomArgs)
|
||||
listenForLiveSummaryChanges(roomArgs.roomId, result.beaconEventId)
|
||||
locationTracker.requestLastKnownLocation()
|
||||
}
|
||||
is UpdateLiveLocationShareResult.Failure -> {
|
||||
|
@ -115,22 +120,7 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
|
|||
}
|
||||
}
|
||||
|
||||
private fun scheduleTimer(roomId: String, durationMillis: Long) {
|
||||
Timer()
|
||||
.apply {
|
||||
schedule(object : TimerTask() {
|
||||
override fun run() {
|
||||
stopSharingLocation(roomId)
|
||||
timers.remove(this@apply)
|
||||
}
|
||||
}, durationMillis)
|
||||
}
|
||||
.also {
|
||||
timers.add(it)
|
||||
}
|
||||
}
|
||||
|
||||
fun stopSharingLocation(roomId: String) {
|
||||
private fun stopSharingLocation(roomId: String) {
|
||||
Timber.i("### LocationSharingService.stopSharingLocation for $roomId")
|
||||
removeRoomArgs(roomId)
|
||||
tryToDestroyMe()
|
||||
|
@ -177,9 +167,9 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
|
|||
}
|
||||
|
||||
private fun destroyMe() {
|
||||
jobs.forEach { it.cancel() }
|
||||
jobs.clear()
|
||||
locationTracker.removeCallback(this)
|
||||
timers.forEach { it.cancel() }
|
||||
timers.clear()
|
||||
stopSelf()
|
||||
}
|
||||
|
||||
|
@ -202,6 +192,21 @@ class LocationSharingService : VectorService(), LocationTracker.Callback {
|
|||
beaconIds.forEach { roomArgsMap.remove(it) }
|
||||
}
|
||||
|
||||
private fun listenForLiveSummaryChanges(roomId: String, eventId: String) {
|
||||
activeSessionHolder
|
||||
.getSafeActiveSession()
|
||||
?.let { session ->
|
||||
mainHandler.post {
|
||||
val job = getLiveLocationShareSummaryUseCase.execute(roomId, eventId)
|
||||
.distinctUntilChangedBy { it.isActive }
|
||||
.filter { it.isActive == false }
|
||||
.onEach { stopSharingLocation(roomId) }
|
||||
.launchIn(session.coroutineScope)
|
||||
jobs.add(job)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun launchInIO(block: suspend CoroutineScope.(Session) -> Unit) =
|
||||
activeSessionHolder
|
||||
.getSafeActiveSession()
|
||||
|
|
|
@ -55,10 +55,6 @@ class LocationSharingServiceConnection @Inject constructor(
|
|||
removeCallback(callback)
|
||||
}
|
||||
|
||||
fun stopLiveLocationSharing(roomId: String) {
|
||||
locationSharingService?.stopSharingLocation(roomId)
|
||||
}
|
||||
|
||||
override fun onServiceConnected(className: ComponentName, binder: IBinder) {
|
||||
locationSharingService = (binder as LocationSharingService.LocalBinder).getService().also {
|
||||
it.callback = this
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package im.vector.app.features.location.live
|
||||
|
||||
import androidx.annotation.MainThread
|
||||
import androidx.lifecycle.asFlow
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.emptyFlow
|
||||
|
@ -23,13 +24,16 @@ import kotlinx.coroutines.flow.mapNotNull
|
|||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.getRoom
|
||||
import org.matrix.android.sdk.api.session.room.model.livelocation.LiveLocationShareAggregatedSummary
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
class GetLiveLocationShareSummaryUseCase @Inject constructor(
|
||||
private val session: Session,
|
||||
) {
|
||||
|
||||
@MainThread
|
||||
fun execute(roomId: String, eventId: String): Flow<LiveLocationShareAggregatedSummary> {
|
||||
Timber.d("getting flow for roomId=$roomId and eventId=$eventId")
|
||||
return session.getRoom(roomId)
|
||||
?.locationSharingService()
|
||||
?.getLiveLocationShareSummary(eventId)
|
||||
|
|
|
@ -16,24 +16,17 @@
|
|||
|
||||
package im.vector.app.features.location.live
|
||||
|
||||
import im.vector.app.features.location.LocationSharingServiceConnection
|
||||
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 javax.inject.Inject
|
||||
|
||||
class StopLiveLocationShareUseCase @Inject constructor(
|
||||
private val locationSharingServiceConnection: LocationSharingServiceConnection,
|
||||
private val session: Session
|
||||
) {
|
||||
|
||||
suspend fun execute(roomId: String): UpdateLiveLocationShareResult? {
|
||||
val result = sendStoppedBeaconInfo(session, roomId)
|
||||
when (result) {
|
||||
is UpdateLiveLocationShareResult.Success -> locationSharingServiceConnection.stopLiveLocationSharing(roomId)
|
||||
else -> Unit
|
||||
}
|
||||
return result
|
||||
return sendStoppedBeaconInfo(session, roomId)
|
||||
}
|
||||
|
||||
private suspend fun sendStoppedBeaconInfo(session: Session, roomId: String): UpdateLiveLocationShareResult? {
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
package im.vector.app.features.location.live
|
||||
|
||||
import im.vector.app.test.fakes.FakeLocationSharingServiceConnection
|
||||
import im.vector.app.test.fakes.FakeSession
|
||||
import io.mockk.unmockkAll
|
||||
import kotlinx.coroutines.test.runTest
|
||||
|
@ -30,11 +29,9 @@ private const val AN_EVENT_ID = "event_id"
|
|||
|
||||
class StopLiveLocationShareUseCaseTest {
|
||||
|
||||
private val fakeLocationSharingServiceConnection = FakeLocationSharingServiceConnection()
|
||||
private val fakeSession = FakeSession()
|
||||
|
||||
private val stopLiveLocationShareUseCase = StopLiveLocationShareUseCase(
|
||||
locationSharingServiceConnection = fakeLocationSharingServiceConnection.instance,
|
||||
session = fakeSession
|
||||
)
|
||||
|
||||
|
@ -45,7 +42,6 @@ class StopLiveLocationShareUseCaseTest {
|
|||
|
||||
@Test
|
||||
fun `given a room id when calling use case then the current live is stopped with success`() = runTest {
|
||||
fakeLocationSharingServiceConnection.givenStopLiveLocationSharing()
|
||||
val updateLiveResult = UpdateLiveLocationShareResult.Success(AN_EVENT_ID)
|
||||
fakeSession.roomService()
|
||||
.getRoom(A_ROOM_ID)
|
||||
|
@ -55,7 +51,6 @@ class StopLiveLocationShareUseCaseTest {
|
|||
val result = stopLiveLocationShareUseCase.execute(A_ROOM_ID)
|
||||
|
||||
result shouldBeEqualTo updateLiveResult
|
||||
fakeLocationSharingServiceConnection.verifyStopLiveLocationSharing(A_ROOM_ID)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -70,6 +65,5 @@ class StopLiveLocationShareUseCaseTest {
|
|||
val result = stopLiveLocationShareUseCase.execute(A_ROOM_ID)
|
||||
|
||||
result shouldBeEqualTo updateLiveResult
|
||||
fakeLocationSharingServiceConnection.verifyStopLiveLocationSharingNotCalled(A_ROOM_ID)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,16 +34,4 @@ class FakeLocationSharingServiceConnection {
|
|||
fun verifyBind(callback: LocationSharingServiceConnection.Callback) {
|
||||
verify { instance.bind(callback) }
|
||||
}
|
||||
|
||||
fun givenStopLiveLocationSharing() {
|
||||
every { instance.stopLiveLocationSharing(any()) } just runs
|
||||
}
|
||||
|
||||
fun verifyStopLiveLocationSharing(roomId: String) {
|
||||
verify { instance.stopLiveLocationSharing(roomId) }
|
||||
}
|
||||
|
||||
fun verifyStopLiveLocationSharingNotCalled(roomId: String) {
|
||||
verify(inverse = true) { instance.stopLiveLocationSharing(roomId) }
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue