mirror of
https://github.com/d4rken-org/capod.git
synced 2026-09-15 02:36:12 -04:00
fix: Hide charging indicator for disconnected devices
This commit is contained in:
@@ -183,18 +183,23 @@ data class PodDevice(
|
||||
).minOrNull()
|
||||
}
|
||||
|
||||
// Charging — AAP preferred, BLE fallback, then cached
|
||||
// Charging — AAP preferred, BLE fallback, then cached. The cached fallback only applies while
|
||||
// the device is live (connected): charging is a real-time claim ("power is flowing now") that
|
||||
// we can't stand behind once the device is out of range, so we suppress it after full
|
||||
// disconnect rather than showing a frozen charging state on the dimmed "cached N ago" card.
|
||||
// The raw charging bits are still persisted in `cached` for callers that want the last-known
|
||||
// value directly (device.cached?.is…Charging).
|
||||
val isLeftPodCharging: Boolean?
|
||||
get() = aap?.isLeftCharging ?: (ble as? HasChargeDetectionDual)?.isLeftPodCharging ?: cached?.isLeftCharging
|
||||
get() = aap?.isLeftCharging ?: (ble as? HasChargeDetectionDual)?.isLeftPodCharging ?: cached?.isLeftCharging?.takeIf { isLive }
|
||||
|
||||
val isRightPodCharging: Boolean?
|
||||
get() = aap?.isRightCharging ?: (ble as? HasChargeDetectionDual)?.isRightPodCharging ?: cached?.isRightCharging
|
||||
get() = aap?.isRightCharging ?: (ble as? HasChargeDetectionDual)?.isRightPodCharging ?: cached?.isRightCharging?.takeIf { isLive }
|
||||
|
||||
val isCaseCharging: Boolean?
|
||||
get() = aap?.isCaseCharging ?: (ble as? HasCase)?.isCaseCharging ?: cached?.isCaseCharging
|
||||
get() = aap?.isCaseCharging ?: (ble as? HasCase)?.isCaseCharging ?: cached?.isCaseCharging?.takeIf { isLive }
|
||||
|
||||
val isHeadsetBeingCharged: Boolean?
|
||||
get() = aap?.isHeadsetCharging ?: (ble as? HasChargeDetection)?.isHeadsetBeingCharged ?: cached?.isHeadsetCharging
|
||||
get() = aap?.isHeadsetCharging ?: (ble as? HasChargeDetection)?.isHeadsetBeingCharged ?: cached?.isHeadsetCharging?.takeIf { isLive }
|
||||
|
||||
// Full per-slot charging state — AAP only (BLE + cache don't carry CHARGING_OPTIMIZED).
|
||||
// Null means "no live AAP reading", which lets callers avoid showing a stale Optimized chip
|
||||
|
||||
@@ -71,12 +71,10 @@ class MonitorNotificationViewFactory @Inject constructor(
|
||||
if (device.hasEarDetection) {
|
||||
setViewVisibility(R.id.headphones_worn, if (device.isBeingWorn == true) View.VISIBLE else View.GONE)
|
||||
}
|
||||
if (device.isHeadsetBeingCharged != null) {
|
||||
setViewVisibility(
|
||||
R.id.headphones_charging,
|
||||
if (device.isHeadsetBeingCharged == true) View.VISIBLE else View.GONE
|
||||
)
|
||||
}
|
||||
setViewVisibility(
|
||||
R.id.headphones_charging,
|
||||
if (device.isHeadsetBeingCharged == true) View.VISIBLE else View.GONE
|
||||
)
|
||||
}
|
||||
|
||||
private fun createUnknownDevice(device: PodDevice): RemoteViews = RemoteViews(
|
||||
@@ -151,12 +149,10 @@ class MonitorNotificationViewFactory @Inject constructor(
|
||||
if (device.hasEarDetection) {
|
||||
setViewVisibility(R.id.headphones_worn, if (device.isBeingWorn == true) View.VISIBLE else View.GONE)
|
||||
}
|
||||
if (device.isHeadsetBeingCharged != null) {
|
||||
setViewVisibility(
|
||||
R.id.headphones_charging,
|
||||
if (device.isHeadsetBeingCharged == true) View.VISIBLE else View.GONE
|
||||
)
|
||||
}
|
||||
setViewVisibility(
|
||||
R.id.headphones_charging,
|
||||
if (device.isHeadsetBeingCharged == true) View.VISIBLE else View.GONE
|
||||
)
|
||||
}
|
||||
|
||||
private fun createUnknownDeviceBig(device: PodDevice): RemoteViews = RemoteViews(
|
||||
|
||||
@@ -91,10 +91,37 @@ class PodDeviceCacheTest : BaseTest() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `charging falls back to cache`() {
|
||||
val device = PodDevice(profileId = "test-profile", ble = null, aap = null, cached = cachedState)
|
||||
device.isLeftPodCharging shouldBe false
|
||||
device.isCaseCharging shouldBe true
|
||||
fun `charging is suppressed when not live even if cached`() {
|
||||
// Charging is a real-time claim we can't stand behind once the device is out of range.
|
||||
// A cached-only (non-live) device must report null for every charging slot, so the
|
||||
// dimmed "cached N ago" card shows no charging chip. Uses a cache with all four slots
|
||||
// populated to prove each getter suppresses independently.
|
||||
val fullChargingCache = cachedState.copy(
|
||||
isLeftCharging = true,
|
||||
isRightCharging = true,
|
||||
isCaseCharging = true,
|
||||
isHeadsetCharging = true,
|
||||
)
|
||||
val device = PodDevice(profileId = "test-profile", ble = null, aap = null, cached = fullChargingCache)
|
||||
device.isLive shouldBe false
|
||||
device.isLeftPodCharging.shouldBeNull()
|
||||
device.isRightPodCharging.shouldBeNull()
|
||||
device.isCaseCharging.shouldBeNull()
|
||||
device.isHeadsetBeingCharged.shouldBeNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `charging still uses cache fallback while live`() {
|
||||
// While a device is connected (here: an AAP session that is READY but hasn't sent a
|
||||
// per-slot charging reading yet) the cached charging value is still shown, since the
|
||||
// device is present and a fresh reading will correct it momentarily.
|
||||
val aap = AapPodState(
|
||||
connectionState = AapPodState.ConnectionState.READY,
|
||||
lastMessageAt = fiveMinAgo,
|
||||
)
|
||||
val device = PodDevice(profileId = "test-profile", ble = null, aap = aap, cached = cachedState)
|
||||
device.isLive shouldBe true
|
||||
device.isCaseCharging shouldBe true // AAP has no case charging -> cache fallback (live)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user