Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3dbb2571 authored by Ellen Poe's avatar Ellen Poe
Browse files

Merge branch 'ellenhp/ferrostar_fused_location_fix' into 'main'

Force ferrostar to use GPS location when available

See merge request e/os/cardinal!38
parents d1b6edb8 333c867f
Loading
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@ class LocationRepository @Inject constructor(
    private companion object {
        private const val LOCATION_REQUEST_INTERVAL_MS = 15000L // 15 seconds
        private const val LOCATION_REQUEST_TIMEOUT_MS = 5000L // 5 seconds
        private const val CONTINUOUS_LOCATION_UPDATE_INTERVAL_MS = 5000L // 5 seconds
        private const val CONTINUOUS_LOCATION_UPDATE_INTERVAL_MS = 1000L // 1 second
        private const val CONTINUOUS_LOCATION_UPDATE_DISTANCE_M = 5f // 5 meters
        private const val GPS_PROVIDER_TIMEOUT_MS =
            10_000L // 10 seconds - discard fused locations if fused has updated within this timeout
@@ -130,6 +130,10 @@ class LocationRepository @Inject constructor(
        }
    }

    fun getLastLocation(): Location? {
        return lastRequestedLocation
    }

    fun fromNameAndLatLng(name: String?, latLng: LatLng): Place {
        return Place(
            name = name ?: context.getString(R.string.unnamed_location),
+57 −2
Original line number Diff line number Diff line
@@ -20,25 +20,40 @@ package earth.maps.cardinal.routing

import android.content.Context
import com.stadiamaps.ferrostar.composeui.notification.DefaultForegroundNotificationBuilder
import com.stadiamaps.ferrostar.core.AndroidSystemLocationProvider
import com.stadiamaps.ferrostar.core.AndroidTtsObserver
import com.stadiamaps.ferrostar.core.FerrostarCore
import com.stadiamaps.ferrostar.core.LocationProvider
import com.stadiamaps.ferrostar.core.LocationUpdateListener
import com.stadiamaps.ferrostar.core.http.OkHttpClientProvider
import com.stadiamaps.ferrostar.core.service.FerrostarForegroundServiceManager
import com.stadiamaps.ferrostar.core.service.ForegroundServiceManager
import com.stadiamaps.ferrostar.core.toUserLocation
import earth.maps.cardinal.data.LocationRepository
import earth.maps.cardinal.data.OrientationRepository
import earth.maps.cardinal.data.RoutingMode
import earth.maps.cardinal.data.room.RoutingProfileRepository
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import okhttp3.OkHttpClient
import uniffi.ferrostar.CourseFiltering
import uniffi.ferrostar.Heading
import uniffi.ferrostar.NavigationControllerConfig
import uniffi.ferrostar.RouteAdapter
import uniffi.ferrostar.RouteDeviationTracking
import uniffi.ferrostar.UserLocation
import uniffi.ferrostar.WaypointAdvanceMode
import uniffi.ferrostar.stepAdvanceDistanceEntryAndExit
import uniffi.ferrostar.stepAdvanceDistanceToEndOfStep
import java.util.concurrent.Executor
import kotlin.time.Clock
import kotlin.time.ExperimentalTime
import kotlin.time.toJavaInstant

class FerrostarWrapper(
    context: Context,
    private val locationRepository: LocationRepository,
    private val orientationRepository: OrientationRepository,
    private val mode: RoutingMode,
    private val localValhallaEndpoint: String,
    private val androidTtsObserver: AndroidTtsObserver,
@@ -46,12 +61,52 @@ class FerrostarWrapper(
    routingOptions: RoutingOptions? = null
) {

    private val coroutineScope = CoroutineScope(Dispatchers.Main)

    private val foregroundServiceManager: ForegroundServiceManager =
        FerrostarForegroundServiceManager(
            context = context,
            DefaultForegroundNotificationBuilder(context)
        )
    private val locationProvider = AndroidSystemLocationProvider(context = context)
    @OptIn(ExperimentalTime::class)
    private val locationProvider = object: LocationProvider {
        private val listeners = mutableListOf<LocationUpdateListener>()

        override val lastLocation: UserLocation?
            get() = locationRepository.getLastLocation()?.toUserLocation()
        override val lastHeading: Heading?
            get() {
                val heading = ((orientationRepository.azimuth.value.toInt() + 360) % 360).toUShort()
                return Heading(
                    heading,
                    0u,
                    Clock.System.now().toJavaInstant()
                )
            }

        init {
            coroutineScope.launch {
                locationRepository.locationFlow.collect { location ->
                    listeners.forEach { listener ->
                        location?.toUserLocation()?.let { userLocation ->
                            listener.onLocationUpdated(userLocation)
                        }
                    }
                }
            }
        }

        override fun addListener(
            listener: LocationUpdateListener,
            executor: Executor
        ) {
            listeners.add(listener)
        }

        override fun removeListener(listener: LocationUpdateListener) {
            listeners.remove(listener)
        }
    }
    private var previousRouteOptions: RoutingOptions? = null

    var core =
+16 −0
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@ package earth.maps.cardinal.routing
import android.content.Context
import com.stadiamaps.ferrostar.core.AndroidTtsObserver
import dagger.hilt.android.qualifiers.ApplicationContext
import earth.maps.cardinal.data.LocationRepository
import earth.maps.cardinal.data.OrientationRepository
import earth.maps.cardinal.data.RoutingMode
import earth.maps.cardinal.data.room.RoutingProfileRepository
import javax.inject.Inject
@@ -30,6 +32,8 @@ import javax.inject.Singleton
class FerrostarWrapperRepository @Inject constructor(
    @param:ApplicationContext
    private val context: Context,
    private val locationRepository: LocationRepository,
    private val orientationRepository: OrientationRepository,
    private val routingProfileRepository: RoutingProfileRepository
) {
    lateinit var walking: FerrostarWrapper
@@ -44,6 +48,8 @@ class FerrostarWrapperRepository @Inject constructor(
    fun setValhallaEndpoint(endpoint: String) {
        walking = FerrostarWrapper(
            context,
            locationRepository,
            orientationRepository,
            RoutingMode.PEDESTRIAN,
            endpoint,
            androidTtsObserver,
@@ -51,6 +57,8 @@ class FerrostarWrapperRepository @Inject constructor(
        )
        cycling = FerrostarWrapper(
            context,
            locationRepository,
            orientationRepository,
            RoutingMode.BICYCLE,
            endpoint,
            androidTtsObserver,
@@ -58,6 +66,8 @@ class FerrostarWrapperRepository @Inject constructor(
        )
        driving = FerrostarWrapper(
            context,
            locationRepository,
            orientationRepository,
            RoutingMode.AUTO,
            endpoint,
            androidTtsObserver,
@@ -65,6 +75,8 @@ class FerrostarWrapperRepository @Inject constructor(
        )
        truck = FerrostarWrapper(
            context,
            locationRepository,
            orientationRepository,
            RoutingMode.TRUCK,
            endpoint,
            androidTtsObserver,
@@ -72,6 +84,8 @@ class FerrostarWrapperRepository @Inject constructor(
        )
        motorScooter = FerrostarWrapper(
            context,
            locationRepository,
            orientationRepository,
            RoutingMode.MOTOR_SCOOTER,
            endpoint,
            androidTtsObserver,
@@ -79,6 +93,8 @@ class FerrostarWrapperRepository @Inject constructor(
        )
        motorcycle = FerrostarWrapper(
            context,
            locationRepository,
            orientationRepository,
            RoutingMode.MOTORCYCLE,
            endpoint,
            androidTtsObserver,