diff --git a/gearslip/src/main/java/app/seb3thehacker/gearslip/GearslipRunner.kt b/gearslip/src/main/java/app/seb3thehacker/gearslip/GearslipRunner.kt index f80a860..9f15b3a 100644 --- a/gearslip/src/main/java/app/seb3thehacker/gearslip/GearslipRunner.kt +++ b/gearslip/src/main/java/app/seb3thehacker/gearslip/GearslipRunner.kt @@ -45,7 +45,10 @@ class GearslipRunner( private lateinit var identityTask: FutureTask /** Sends every message, in order, so no other thread ever blocks on the USB link. See [send]. */ - private val writer = java.util.concurrent.Executors.newSingleThreadExecutor { Thread(it, "gearslip-writer") } + private val writer = java.util.concurrent.Executors.newSingleThreadExecutor { + // Sound goes out through here too, so it gets audio's priority: late writes are skips. + Thread({ android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_AUDIO); it.run() }, "gearslip-writer") + } /** Waits for the certificate only when TLS is first needed; see [run]. */ private val tls: PhoneTls by lazy { identityTask.get() } @@ -88,6 +91,8 @@ class GearslipRunner( @Volatile private var lastKeyframeSentAt = 0L fun run() { + // This thread reads the car's acks; audio waits on them, so it can't be left at the back. + android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_AUDIO) SessionReport.begin() log.i("--- session starting ---") SessionStatus.connecting("Connected to the head unit") diff --git a/gearslip/src/main/java/app/seb3thehacker/gearslip/audio/AudioCaptureService.kt b/gearslip/src/main/java/app/seb3thehacker/gearslip/audio/AudioCaptureService.kt index cbdb536..6948015 100644 --- a/gearslip/src/main/java/app/seb3thehacker/gearslip/audio/AudioCaptureService.kt +++ b/gearslip/src/main/java/app/seb3thehacker/gearslip/audio/AudioCaptureService.kt @@ -16,6 +16,7 @@ import android.media.AudioRecord import android.media.projection.MediaProjection import android.media.projection.MediaProjectionManager import android.os.IBinder +import android.os.Process import app.seb3thehacker.gearslip.GearslipLog import kotlin.math.abs @@ -147,6 +148,9 @@ class AudioCaptureService : Service() { reading = true thread = Thread({ + // A busy phone (a map app drawing, the video encoder) would otherwise starve this + // loop, and the car hears every late read as a skip. + Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_AUDIO) val buffer = ByteArray(CHUNK_BYTES) var peak = 0 var heardAt = System.currentTimeMillis()