mirror of
https://github.com/twinksoftware/Gearslip.git
synced 2026-11-11 08:12:26 +01:00
voice: a new destination mid-route ends the old route first instead of being ignored; switching or closing map apps ends the old app's route
This commit is contained in:
1 parent
9f982875fe
commit
7ffa203221
2 files changed
+46
-1
No files matched your search
@@ -88,15 +88,22 @@ object CarServices {
|
|||||||
if (destination != null && nav.connectedComponent == app.component) {
|
if (destination != null && nav.connectedComponent == app.component) {
|
||||||
nav.navigateTo(destination)
|
nav.navigateTo(destination)
|
||||||
} else {
|
} else {
|
||||||
|
// Another map app taking over ends the old one's route, or it keeps guiding unseen.
|
||||||
|
if (nav.connectedComponent != app.component) endRoute()
|
||||||
nav.connect(app, frame.width, frame.height, frame.densityDpi, destination)
|
nav.connect(app, frame.width, frame.height, frame.densityDpi, destination)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stopNav() {
|
fun stopNav() {
|
||||||
navStopped = true
|
navStopped = true
|
||||||
|
endRoute()
|
||||||
nav.disconnect()
|
nav.disconnect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun endRoute() {
|
||||||
|
if (nav.navigating) nav.stopNavigating()
|
||||||
|
}
|
||||||
|
|
||||||
/** Undoes [stopNav]'s hold so the last map app comes back, same as it would after a restart. */
|
/** Undoes [stopNav]'s hold so the last map app comes back, same as it would after a restart. */
|
||||||
suspend fun reconnectNav(frame: CarEnvironment.Frame) {
|
suspend fun reconnectNav(frame: CarEnvironment.Frame) {
|
||||||
navStopped = false
|
navStopped = false
|
||||||
|
|||||||
@@ -240,6 +240,9 @@ class CarAppConnection(private val context: Context) {
|
|||||||
this.carApp = null
|
this.carApp = null
|
||||||
appManager = null
|
appManager = null
|
||||||
navigationManager = null
|
navigationManager = null
|
||||||
|
navigating = false
|
||||||
|
main.removeCallbacks(sendReroute)
|
||||||
|
reroute = null
|
||||||
_panMode.value = false
|
_panMode.value = false
|
||||||
surfaceCallback = null
|
surfaceCallback = null
|
||||||
component = null
|
component = null
|
||||||
@@ -313,14 +316,41 @@ class CarAppConnection(private val context: Context) {
|
|||||||
/**
|
/**
|
||||||
* Sends a fresh destination to an app that's already running, instead of tearing it down
|
* Sends a fresh destination to an app that's already running, instead of tearing it down
|
||||||
* and rebuilding the whole session - see [app.seb3thehacker.gearslip.car.CarServices.connectNav].
|
* and rebuilding the whole session - see [app.seb3thehacker.gearslip.car.CarServices.connectNav].
|
||||||
|
*
|
||||||
|
* An app already on a route ends it first: Organic Maps ignored a new destination mid-route
|
||||||
|
* and kept the old directions. The new one goes once the app says the route ended, or after
|
||||||
|
* [REROUTE_WAIT_MS] if it never does.
|
||||||
*/
|
*/
|
||||||
fun navigateTo(destination: String) {
|
fun navigateTo(destination: String) {
|
||||||
|
if (carApp == null) return
|
||||||
|
main.removeCallbacks(sendReroute)
|
||||||
|
if (!navigating) {
|
||||||
|
reroute = null
|
||||||
|
sendDestination(destination)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
reroute = destination
|
||||||
|
stopNavigating()
|
||||||
|
main.postDelayed(sendReroute, REROUTE_WAIT_MS)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun sendDestination(destination: String) {
|
||||||
val app = carApp ?: return
|
val app = carApp ?: return
|
||||||
call("onNewIntent", onValue = {}) {
|
call("onNewIntent", onValue = {}) {
|
||||||
app.onNewIntent(navigateIntent(destination), it)
|
app.onNewIntent(navigateIntent(destination), it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A destination waiting for the current route to end; see [navigateTo]. */
|
||||||
|
private var reroute: String? = null
|
||||||
|
private val sendReroute = Runnable {
|
||||||
|
reroute?.let { reroute = null; sendDestination(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Whether the app has said it's on a route, between navigationStarted and navigationEnded. */
|
||||||
|
@Volatile var navigating = false
|
||||||
|
private set
|
||||||
|
|
||||||
private fun onCreated() {
|
private fun onCreated() {
|
||||||
val app = carApp ?: return
|
val app = carApp ?: return
|
||||||
GearslipLog.i("host: created; starting")
|
GearslipLog.i("host: created; starting")
|
||||||
@@ -609,10 +639,15 @@ class CarAppConnection(private val context: Context) {
|
|||||||
val trip: StateFlow<androidx.car.app.navigation.model.Trip?> = _trip.asStateFlow()
|
val trip: StateFlow<androidx.car.app.navigation.model.Trip?> = _trip.asStateFlow()
|
||||||
|
|
||||||
private val navigationHost = object : INavigationHost.Stub() {
|
private val navigationHost = object : INavigationHost.Stub() {
|
||||||
override fun navigationStarted() = GearslipLog.i("host: navigation started")
|
override fun navigationStarted() {
|
||||||
|
GearslipLog.i("host: navigation started")
|
||||||
|
navigating = true
|
||||||
|
}
|
||||||
override fun navigationEnded() {
|
override fun navigationEnded() {
|
||||||
GearslipLog.i("host: navigation ended")
|
GearslipLog.i("host: navigation ended")
|
||||||
|
navigating = false
|
||||||
_trip.value = null
|
_trip.value = null
|
||||||
|
main.post { if (reroute != null) { main.removeCallbacks(sendReroute); sendReroute.run() } }
|
||||||
}
|
}
|
||||||
override fun updateTrip(trip: Bundleable?) {
|
override fun updateTrip(trip: Bundleable?) {
|
||||||
_trip.value = runCatching { trip?.get() as? androidx.car.app.navigation.model.Trip }.getOrNull()
|
_trip.value = runCatching { trip?.get() as? androidx.car.app.navigation.model.Trip }.getOrNull()
|
||||||
@@ -791,6 +826,9 @@ class CarAppConnection(private val context: Context) {
|
|||||||
/** The newest template API this host claims to understand. */
|
/** The newest template API this host claims to understand. */
|
||||||
const val HOST_API_LEVEL = CarAppApiLevels.LEVEL_8
|
const val HOST_API_LEVEL = CarAppApiLevels.LEVEL_8
|
||||||
|
|
||||||
|
/** How long a new destination waits for the old route to end; see [navigateTo]. */
|
||||||
|
const val REROUTE_WAIT_MS = 1_500L
|
||||||
|
|
||||||
/** Context.BIND_FOREGROUND_SERVICE; the constant itself is hidden from the SDK. */
|
/** Context.BIND_FOREGROUND_SERVICE; the constant itself is hidden from the SDK. */
|
||||||
const val BIND_FOREGROUND_SERVICE = 0x04000000
|
const val BIND_FOREGROUND_SERVICE = 0x04000000
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user