mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-03 06:55:41 +00:00
Handle unrecoverable location errors and stop sharing
This commit is contained in:
-1
@@ -58,7 +58,6 @@ class PlatformLocationProvider(
|
|||||||
) {
|
) {
|
||||||
throw PermissionException()
|
throw PermissionException()
|
||||||
}
|
}
|
||||||
|
|
||||||
val locationManager = context.getSystemService(LocationManager::class.java)
|
val locationManager = context.getSystemService(LocationManager::class.java)
|
||||||
val provider = PROVIDERS_BY_PRIORITY.firstOrNull { LocationManagerCompat.hasProvider(locationManager, it) }
|
val provider = PROVIDERS_BY_PRIORITY.firstOrNull { LocationManagerCompat.hasProvider(locationManager, it) }
|
||||||
val locationFlow = if (provider != null) {
|
val locationFlow = if (provider != null) {
|
||||||
|
|||||||
+5
@@ -133,6 +133,11 @@ class DefaultActiveLiveLocationShareManager(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun onUnrecoverableError() {
|
||||||
|
Timber.d("ActiveLiveLocationShareManager unrecoverable error, stopping all shares")
|
||||||
|
localSharingRoomIds.value.toList().forEach { stopShare(it) }
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun onLocationUpdate(location: Location) {
|
override suspend fun onLocationUpdate(location: Location) {
|
||||||
val activeSharesCount = localSharingRoomIds.value.size
|
val activeSharesCount = localSharingRoomIds.value.size
|
||||||
Timber.d("ActiveLiveLocationShareManager received location update for $activeSharesCount active share(s)")
|
Timber.d("ActiveLiveLocationShareManager received location update for $activeSharesCount active share(s)")
|
||||||
|
|||||||
+2
-1
@@ -9,6 +9,7 @@ package io.element.android.features.location.impl.live.service
|
|||||||
|
|
||||||
import io.element.android.features.location.api.Location
|
import io.element.android.features.location.api.Location
|
||||||
|
|
||||||
fun interface LiveLocationReceiver {
|
interface LiveLocationReceiver {
|
||||||
suspend fun onLocationUpdate(location: Location)
|
suspend fun onLocationUpdate(location: Location)
|
||||||
|
suspend fun onUnrecoverableError() {}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
@@ -77,6 +77,17 @@ class LiveLocationSharingCoordinator internal constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun dispatchUnrecoverableError() {
|
||||||
|
Timber.d("LiveLocationSharingCoordinator dispatching unrecoverable error")
|
||||||
|
receivers.forEach { (sessionId, receiver) ->
|
||||||
|
runCatchingExceptions {
|
||||||
|
receiver.onUnrecoverableError()
|
||||||
|
}.onFailure {
|
||||||
|
Timber.e(it, "Failed to dispatch unrecoverable error for session $sessionId")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun dispatch(location: Location) {
|
suspend fun dispatch(location: Location) {
|
||||||
val currentTimeMillis = nowMillis()
|
val currentTimeMillis = nowMillis()
|
||||||
val millisSincePrevious = currentTimeMillis - lastDispatchMillis.load()
|
val millisSincePrevious = currentTimeMillis - lastDispatchMillis.load()
|
||||||
|
|||||||
+18
-10
@@ -30,12 +30,15 @@ import kotlinx.coroutines.Dispatchers
|
|||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.FlowPreview
|
import kotlinx.coroutines.FlowPreview
|
||||||
import kotlinx.coroutines.cancel
|
import kotlinx.coroutines.cancel
|
||||||
|
import kotlinx.coroutines.flow.emptyFlow
|
||||||
import kotlinx.coroutines.flow.filterNotNull
|
import kotlinx.coroutines.flow.filterNotNull
|
||||||
import kotlinx.coroutines.flow.flatMapLatest
|
import kotlinx.coroutines.flow.flatMapLatest
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import org.maplibre.compose.location.DesiredAccuracy
|
import org.maplibre.compose.location.DesiredAccuracy
|
||||||
|
import org.maplibre.compose.location.PermissionException
|
||||||
import org.maplibre.spatialk.units.extensions.inMeters
|
import org.maplibre.spatialk.units.extensions.inMeters
|
||||||
import org.maplibre.spatialk.units.extensions.meters
|
import org.maplibre.spatialk.units.extensions.meters
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
@@ -48,7 +51,6 @@ class LiveLocationSharingService : Service() {
|
|||||||
@Inject lateinit var coordinator: LiveLocationSharingCoordinator
|
@Inject lateinit var coordinator: LiveLocationSharingCoordinator
|
||||||
@Inject lateinit var notificationCreator: LiveLocationSharingNotificationCreator
|
@Inject lateinit var notificationCreator: LiveLocationSharingNotificationCreator
|
||||||
@Inject lateinit var appPreferencesStore: AppPreferencesStore
|
@Inject lateinit var appPreferencesStore: AppPreferencesStore
|
||||||
|
|
||||||
@Inject lateinit var appForegroundStateService: AppForegroundStateService
|
@Inject lateinit var appForegroundStateService: AppForegroundStateService
|
||||||
|
|
||||||
@AppCoroutineScope
|
@AppCoroutineScope
|
||||||
@@ -62,8 +64,8 @@ class LiveLocationSharingService : Service() {
|
|||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
Timber.d("LiveLocationSharingService onCreate")
|
Timber.d("LiveLocationSharingService onCreate")
|
||||||
|
bindings<LocationBindings>().inject(this)
|
||||||
runCatchingExceptions {
|
runCatchingExceptions {
|
||||||
bindings<LocationBindings>().inject(this)
|
|
||||||
appForegroundStateService.updateIsSharingLiveLocation(true)
|
appForegroundStateService.updateIsSharingLiveLocation(true)
|
||||||
coroutineScope = appCoroutineScope.childScope(Dispatchers.Default, "LiveLocationSharingService")
|
coroutineScope = appCoroutineScope.childScope(Dispatchers.Default, "LiveLocationSharingService")
|
||||||
val notificationId = NotificationIdProvider.getForegroundServiceNotificationId(ForegroundServiceType.LIVE_LOCATION)
|
val notificationId = NotificationIdProvider.getForegroundServiceNotificationId(ForegroundServiceType.LIVE_LOCATION)
|
||||||
@@ -81,6 +83,7 @@ class LiveLocationSharingService : Service() {
|
|||||||
startLocationUpdatesListener()
|
startLocationUpdatesListener()
|
||||||
}.onFailure {
|
}.onFailure {
|
||||||
Timber.e(it, "Failed to start live location sharing service")
|
Timber.e(it, "Failed to start live location sharing service")
|
||||||
|
appCoroutineScope.launch { coordinator.dispatchUnrecoverableError() }
|
||||||
stopSelf()
|
stopSelf()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -90,14 +93,19 @@ class LiveLocationSharingService : Service() {
|
|||||||
Timber.d("LiveLocationSharingService listening to location updates")
|
Timber.d("LiveLocationSharingService listening to location updates")
|
||||||
appPreferencesStore.getLiveLocationMinimumDistanceInMetersUpdateFlow()
|
appPreferencesStore.getLiveLocationMinimumDistanceInMetersUpdateFlow()
|
||||||
.flatMapLatest { minDistanceMeters ->
|
.flatMapLatest { minDistanceMeters ->
|
||||||
val locationProvider = PlatformLocationProvider(
|
try {
|
||||||
context = applicationContext,
|
PlatformLocationProvider(
|
||||||
updateInterval = UPDATE_INTERVAL_IN_SECOND.seconds,
|
context = applicationContext,
|
||||||
minDistance = minDistanceMeters.meters,
|
updateInterval = UPDATE_INTERVAL_IN_SECOND.seconds,
|
||||||
desiredAccuracy = DesiredAccuracy.Balanced,
|
minDistance = minDistanceMeters.meters,
|
||||||
coroutineScope = coroutineScope
|
desiredAccuracy = DesiredAccuracy.Balanced,
|
||||||
)
|
coroutineScope = coroutineScope
|
||||||
locationProvider.location
|
).location
|
||||||
|
} catch (exception: PermissionException) {
|
||||||
|
Timber.e(exception, "Failed to create PlatformLocationProvider")
|
||||||
|
coordinator.dispatchUnrecoverableError()
|
||||||
|
emptyFlow()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.filterNotNull()
|
.filterNotNull()
|
||||||
.map { location ->
|
.map { location ->
|
||||||
|
|||||||
Reference in New Issue
Block a user