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 Original line Diff line number Diff line
@@ -54,7 +54,7 @@ class LocationRepository @Inject constructor(
    private companion object {
    private companion object {
        private const val LOCATION_REQUEST_INTERVAL_MS = 15000L // 15 seconds
        private const val LOCATION_REQUEST_INTERVAL_MS = 15000L // 15 seconds
        private const val LOCATION_REQUEST_TIMEOUT_MS = 5000L // 5 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 CONTINUOUS_LOCATION_UPDATE_DISTANCE_M = 5f // 5 meters
        private const val GPS_PROVIDER_TIMEOUT_MS =
        private const val GPS_PROVIDER_TIMEOUT_MS =
            10_000L // 10 seconds - discard fused locations if fused has updated within this timeout
            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 {
    fun fromNameAndLatLng(name: String?, latLng: LatLng): Place {
        return Place(
        return Place(
            name = name ?: context.getString(R.string.unnamed_location),
            name = name ?: context.getString(R.string.unnamed_location),
+57 −2
Original line number Original line Diff line number Diff line
@@ -20,25 +20,40 @@ package earth.maps.cardinal.routing


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


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


    private val coroutineScope = CoroutineScope(Dispatchers.Main)

    private val foregroundServiceManager: ForegroundServiceManager =
    private val foregroundServiceManager: ForegroundServiceManager =
        FerrostarForegroundServiceManager(
        FerrostarForegroundServiceManager(
            context = context,
            context = context,
            DefaultForegroundNotificationBuilder(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
    private var previousRouteOptions: RoutingOptions? = null


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