Merge pull request #88 from davideresigotti/honda-civic-capture-stop

Stop the audio capture and screen sharing when the car leaves
This commit is contained in:
Seb3thehacker authored and GitHub committed 2026-11-06 12:03:12 -08:00
commit 7719a5fff2
2 files changed
+30 -1

No files matched your search

@@ -175,6 +175,10 @@ class GearslipRunner(
reportDisconnect()
} finally {
running = false
// The car is gone, but nothing calls stop() when a wireless session drops: it waits
// for the next one. Close the music channel now, so the audio capture behind it,
// and the screen sharing Android shows for it, stop too (issue #43).
if (!stopped) audioLink?.close()
writer.shutdown()
if (drainWriterOnExit) writer.awaitTermination(2, TimeUnit.SECONDS)
writer.shutdownNow()
@@ -54,7 +54,21 @@ object CarAudio {
val sampleRate get() = link?.sampleRate ?: 48_000
val channels get() = link?.channels ?: 2
private val main by lazy { android.os.Handler(android.os.Looper.getMainLooper()) }
/**
* The car left and none came back: stop capturing, which ends the screen sharing Android
* shows for it and gives the phone its speaker back. Nothing else stopped it once the drive
* was over; with a wireless dongle Gearslip's screen stays open, so it ran on (issue #43).
*/
private val releaseWhenGone = Runnable {
if (link != null || _capture.value == Capture.OFF) return@Runnable
GearslipLog.i("audio: no car for ${CAR_GONE_MS / 1000}s - stopping the capture and screen sharing")
release()
}
fun attach(link: Link) {
main.removeCallbacks(releaseWhenGone)
this.link = link
GearslipLog.i("audio: the car offered a sink at ${link.sampleRate}Hz x${link.channels}")
when {
@@ -63,10 +77,20 @@ object CarAudio {
}
}
/**
* The car's music channel closed. A car that comes straight back (a cable that slips) keeps
* the capture it had, so the driver isn't asked again mid-drive.
*/
fun detach(link: Link) {
if (this.link === link) this.link = null
if (this.link !== link) return
this.link = null
main.removeCallbacks(releaseWhenGone)
main.postDelayed(releaseWhenGone, CAR_GONE_MS)
}
/** How long after the car leaves the capture waits for it to come back: a cable that slips. */
private const val CAR_GONE_MS = 3_000L
/**
* The car wants sound. Safe to call as often as the session likes: the consent dialog appears
* at most once, and only once there is a sink to play through - asking on the bench, where the
@@ -117,6 +141,7 @@ object CarAudio {
/** The car went away. Everything is torn down; the next connection asks again. */
fun release() {
main.removeCallbacks(releaseWhenGone)
wanted = false
toldBlocked = false
AudioCaptureService.stop()