audio pause when unplugged, theme tweak

This commit is contained in:
Seb3thehacker committed 2026-10-08 00:06:34 -07:00
1 parent c212c2e2d1
commit 40086e061b
3 files changed
+32 -1

No files matched your search

@@ -338,6 +338,8 @@ class GearslipActivity : ComponentActivity(), Projection {
}
override fun onProjectionStopped() {
// Before the car UI goes, while the media connection is still up.
app.seb3thehacker.gearslip.car.CarServices.pausePhoneMedia()
runOnUiThread {
PhoneMirror.requestStop()
app.seb3thehacker.gearslip.car.CarKeys.focusSink = null
@@ -200,6 +200,32 @@ object CarServices {
return playingPackages.firstNotNullOfOrNull { pkg -> catalog.firstOrNull { it.component.packageName == pkg } }
}
/**
* The car went away mid-song: pause it, as Android Auto does, so it doesn't carry on out of
* the phone's speaker. Unplugging a USB accessory isn't "audio becoming noisy" the way
* headphones are, so the apps won't pause themselves. Every playing session is paused, not
* just the one Gearslip opened: anything the car was playing was going through the car.
*/
fun pausePhoneMedia() {
val ctx = context ?: return
val manager = ctx.getSystemService(MediaSessionManager::class.java)
val listener = ComponentName(ctx, GearslipNotificationListener::class.java)
val playing = try {
manager.getActiveSessions(listener).filter { it.playbackState?.state == PlaybackState.STATE_PLAYING }
} catch (e: SecurityException) {
null
}
if (playing == null) {
// No notification access: the app Gearslip itself is driving is all it can reach.
mediaOrNull()?.let { if (it.now.value.playing) it.togglePlay() }
return
}
playing.forEach { runCatching { it.transportControls.pause() } }
if (playing.isNotEmpty()) {
app.seb3thehacker.gearslip.GearslipLog.i("media: paused ${playing.joinToString { it.packageName }} as the car left")
}
}
/** The car went away: nothing should keep running for a screen that no longer exists. */
fun shutdown() {
context?.let { app.seb3thehacker.gearslip.notify.CarMotion.stop(it) }
@@ -50,6 +50,8 @@ enum class HoldMarkerStyle {
* colour, so the peel's flap matches whatever it sits on. Round and pill-shaped controls get the
* dot whatever the theme says: a circle has no corner to peel.
*/
private const val SHOW_HOLD_DOT = false
@Composable
internal fun BoxScope.GsHoldMarker(style: HoldMarkerStyle, container: Color, shape: Shape, press: InteractionSource) {
if (style == HoldMarkerStyle.NONE) return
@@ -68,8 +70,9 @@ internal fun BoxScope.GsHoldMarker(style: HoldMarkerStyle, container: Color, sha
val side = min(size.width, size.height)
val r = (shape as? CornerBasedShape)?.topEnd?.toPx(size, this) ?: 0f
val round = r >= side * 0.4f
// The dot is off until it's redesigned: flat themes and round controls show nothing.
if (style == HoldMarkerStyle.DOT || round) {
drawHoldDot(r, side, ink)
if (SHOW_HOLD_DOT) drawHoldDot(r, side, ink)
} else {
// Drawn for the bottom-right corner, then flipped up to the top-right.
scale(1f, -1f, pivot = center) {