From e54fb08fc92995928cbc10da8136c92df9636b6c Mon Sep 17 00:00:00 2001 From: Seb3thehacker Date: Sat, 24 Oct 2026 13:24:46 -0700 Subject: [PATCH] launcher: a POI or other non-media car app gets its own tile, not a Browse tile under Music RF Sentinel ships a POI car screen plus a media service for its sound, and only showed up as a music app. --- .../app/seb3thehacker/gearslip/car/CarLauncher.kt | 12 +++++++++--- .../app/seb3thehacker/gearslip/host/CarAppCatalog.kt | 3 +++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/gearslip/src/main/java/app/seb3thehacker/gearslip/car/CarLauncher.kt b/gearslip/src/main/java/app/seb3thehacker/gearslip/car/CarLauncher.kt index 217c212..ce149d1 100644 --- a/gearslip/src/main/java/app/seb3thehacker/gearslip/car/CarLauncher.kt +++ b/gearslip/src/main/java/app/seb3thehacker/gearslip/car/CarLauncher.kt @@ -125,7 +125,11 @@ internal object LauncherCache { // MediaBrowserService, which otherwise land as two identically-labeled tiles with no // way to tell them apart. They're genuinely different screens - browsing versus Now // Playing - so only the label needs disambiguating, not the tile itself. - val mediaPackages = mediaApps.map { it.component.packageName }.toSet() + // An app whose car screen is something else (RF Sentinel is a POI app) only uses its media + // service for sound: its car screen gets the tile, under its own name, and no player tile. + val otherScreens = navApps.filter { !it.isMediaScreen }.map { it.component.packageName }.toSet() + val allMedia = mediaApps.map { it.component.packageName }.toSet() + val mediaPackages = allMedia - otherScreens val messagingApps = MessagingCatalog.installed(context) // Google Messages ships its own car app, which won't start under Gearslip. Gearslip's @@ -142,10 +146,12 @@ internal object LauncherCache { val label = if (it.component.packageName in mediaPackages) "${it.label} ยท Browse" else it.label Entry(label, iconOf(it.component.packageName), template = it) } - val media = mediaApps.map { Entry(it.label, iconOf(it.component.packageName), media = it) } + val media = mediaApps + .filter { it.component.packageName !in otherScreens } + .map { Entry(it.label, iconOf(it.component.packageName), media = it) } // A messenger that is also a car media app keeps only its player tile. val messaging = messagingApps - .filter { it.packageName !in mediaPackages } + .filter { it.packageName !in allMedia } .map { Entry(it.label, iconOf(it.packageName), messaging = it) } return (nav + media + messaging).sortedBy { it.label.lowercase() }.also { flow.value = it } } diff --git a/gearslip/src/main/java/app/seb3thehacker/gearslip/host/CarAppCatalog.kt b/gearslip/src/main/java/app/seb3thehacker/gearslip/host/CarAppCatalog.kt index 31ad0db..b8b77d7 100644 --- a/gearslip/src/main/java/app/seb3thehacker/gearslip/host/CarAppCatalog.kt +++ b/gearslip/src/main/java/app/seb3thehacker/gearslip/host/CarAppCatalog.kt @@ -13,6 +13,9 @@ class TemplateApp( ) { val isNavigation: Boolean get() = CarAppService.CATEGORY_NAVIGATION_APP in categories + /** A media car screen, or one that names no category (older media apps). */ + val isMediaScreen: Boolean get() = kind == "media" || kind == "app" + /** "navigation", "media", ... - what the app told the system it is. */ val kind: String get() = categories.firstOrNull { it.startsWith(CATEGORY_PREFIX) }