From ffe8a5874628d0de4956ead766959692f95fa31f Mon Sep 17 00:00:00 2001 From: darken Date: Thu, 5 Jun 2025 18:41:32 +0200 Subject: [PATCH] Introduce `ApplePods.Flags` and UI for key status This commit introduces a new `Flags` data class within `ApplePods` to store boolean flags related to the device, specifically `isIRKMatch`. This flag is now passed during the creation of `ApplePods` instances in all `ApplePodsFactory` implementations and the central `AppleFactory`. The UI has been updated to display a key icon in the overview cards (`DualPodsCardVH` and `SinglePodsCardVH`): - The icon is only visible if `flags.isIRKMatch` is true. - The icon changes to a filled key (`ic_key_24`) if `payload.private` is not null (indicating successful decryption), otherwise an outline key (`ic_key_outline_24`) is shown. - Minor layout adjustments were made in `overview_pods_single_item.xml` and `overview_pods_dual_item.xml` to accommodate the new key icon. --- .../capod/pods/core/apple/AppleFactory.kt | 48 ++++++++++--------- .../darken/capod/pods/core/apple/ApplePods.kt | 5 ++ .../capod/pods/core/apple/ApplePodsFactory.kt | 2 +- .../pods/core/apple/airpods/AirPodsGen1.kt | 10 +++- .../pods/core/apple/airpods/AirPodsGen2.kt | 10 +++- .../pods/core/apple/airpods/AirPodsGen3.kt | 6 ++- .../pods/core/apple/airpods/AirPodsGen4.kt | 6 ++- .../pods/core/apple/airpods/AirPodsGen4Anc.kt | 6 ++- .../pods/core/apple/airpods/AirPodsMax.kt | 6 ++- .../pods/core/apple/airpods/AirPodsMaxUsbc.kt | 6 ++- .../pods/core/apple/airpods/AirPodsPro.kt | 5 +- .../pods/core/apple/airpods/AirPodsPro2.kt | 6 ++- .../core/apple/airpods/AirPodsPro2Usbc.kt | 6 ++- .../pods/core/apple/beats/BeatsFitPro.kt | 6 ++- .../capod/pods/core/apple/beats/BeatsFlex.kt | 6 ++- .../capod/pods/core/apple/beats/BeatsSolo3.kt | 6 ++- .../pods/core/apple/beats/BeatsStudio3.kt | 6 ++- .../capod/pods/core/apple/beats/BeatsX.kt | 6 ++- .../pods/core/apple/beats/PowerBeats3.kt | 6 ++- .../pods/core/apple/beats/PowerBeats4.kt | 6 ++- .../pods/core/apple/beats/PowerBeatsPro.kt | 6 ++- .../pods/core/apple/misc/FakeAirPodsGen1.kt | 6 ++- .../pods/core/apple/misc/FakeAirPodsGen2.kt | 6 ++- .../pods/core/apple/misc/FakeAirPodsGen3.kt | 6 ++- .../pods/core/apple/misc/FakeAirPodsPro.kt | 6 ++- .../pods/core/apple/misc/FakeAirPodsPro2.kt | 6 ++- .../core/apple/misc/UnknownAppleDevice.kt | 4 +- .../ui/overview/cards/pods/DualPodsCardVH.kt | 13 +++++ .../overview/cards/pods/SinglePodsCardVH.kt | 20 +++++++- .../res/layout/overview_pods_dual_item.xml | 22 ++++++--- .../res/layout/overview_pods_single_item.xml | 23 ++++++--- 31 files changed, 198 insertions(+), 84 deletions(-) diff --git a/app-common/src/main/java/eu/darken/capod/pods/core/apple/AppleFactory.kt b/app-common/src/main/java/eu/darken/capod/pods/core/apple/AppleFactory.kt index cac4b2be..32676590 100644 --- a/app-common/src/main/java/eu/darken/capod/pods/core/apple/AppleFactory.kt +++ b/app-common/src/main/java/eu/darken/capod/pods/core/apple/AppleFactory.kt @@ -58,38 +58,40 @@ class AppleFactory @Inject constructor( suspend fun create(scanResult: BleScanResult): PodDevice? = lock.withLock { val proximityMessage = getMessage(scanResult) ?: return@withLock null - val payload = getPayload(scanResult, proximityMessage) + + val isIrkMatch = generalSettings.mainDeviceIdentityKey.value + ?.let { rpaChecker.verify(scanResult.address, it) } + ?: false + + val payload = ProximityPayload( + public = ProximityPayload.Public( + proximityMessage.data.take(16).toUByteArray() + ), + private = run { + if (!isIrkMatch) return@run null + + val encKey = generalSettings.mainDeviceEncryptionKey.value + if (encKey == null) return@run null + + val encrypted = proximityMessage.data.takeLast(16).toUByteArray().toByteArray() + proximityMessageDecrypter.decrypt(encrypted, encKey)?.let { + ProximityPayload.Private(data = it) + } + }, + ) val factory = podFactories.firstOrNull { it.isResponsible(proximityMessage) } + return@withLock (factory ?: unknownAppleFactory).create( scanResult = scanResult, payload = payload, + flags = ApplePods.Flags( + isIRKMatch = true, + ), ) } - private fun getPayload( - scanResult: BleScanResult, - proximityMessage: ProximityMessage - ) = ProximityPayload( - public = ProximityPayload.Public( - proximityMessage.data.take(16).toUByteArray() - ), - private = run { - val irkKey = generalSettings.mainDeviceIdentityKey.value - if (irkKey == null) return@run null - val encKey = generalSettings.mainDeviceEncryptionKey.value - if (encKey == null) return@run null - - if (!rpaChecker.verify(scanResult.address, irkKey)) return@run null - - val encrypted = proximityMessage.data.takeLast(16).toUByteArray().toByteArray() - proximityMessageDecrypter.decrypt(encrypted, encKey)?.let { - ProximityPayload.Private(data = it) - } - }, - ) - companion object { private val TAG = logTag("Pod", "Apple", "Factory") } diff --git a/app-common/src/main/java/eu/darken/capod/pods/core/apple/ApplePods.kt b/app-common/src/main/java/eu/darken/capod/pods/core/apple/ApplePods.kt index a64b5ff3..1dea1e48 100644 --- a/app-common/src/main/java/eu/darken/capod/pods/core/apple/ApplePods.kt +++ b/app-common/src/main/java/eu/darken/capod/pods/core/apple/ApplePods.kt @@ -8,6 +8,7 @@ import eu.darken.capod.pods.core.apple.protocol.ProximityPayload interface ApplePods : PodDevice { val payload: ProximityPayload + val flags: Flags // We start counting at the airpods prefix byte val pubPrefix: UByte @@ -54,4 +55,8 @@ interface ApplePods : PodDevice { level = level ) } + + data class Flags( + val isIRKMatch: Boolean, + ) } \ No newline at end of file diff --git a/app-common/src/main/java/eu/darken/capod/pods/core/apple/ApplePodsFactory.kt b/app-common/src/main/java/eu/darken/capod/pods/core/apple/ApplePodsFactory.kt index 12da4bbc..0b93539d 100644 --- a/app-common/src/main/java/eu/darken/capod/pods/core/apple/ApplePodsFactory.kt +++ b/app-common/src/main/java/eu/darken/capod/pods/core/apple/ApplePodsFactory.kt @@ -7,7 +7,7 @@ import eu.darken.capod.pods.core.apple.protocol.ProximityPayload interface ApplePodsFactory { fun isResponsible(message: ProximityMessage): Boolean - fun create(scanResult: BleScanResult, payload: ProximityPayload): ApplePods + fun create(scanResult: BleScanResult, payload: ProximityPayload, flags: ApplePods.Flags): ApplePods data class ModelInfo( val full: UShort, diff --git a/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsGen1.kt b/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsGen1.kt index fa5c1653..10cd96af 100644 --- a/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsGen1.kt +++ b/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsGen1.kt @@ -20,6 +20,7 @@ data class AirPodsGen1( override val seenCounter: Int = 1, override val scanResult: BleScanResult, override val payload: ProximityPayload, + override val flags: ApplePods.Flags, override val reliability: Float = PodDevice.BASE_CONFIDENCE, private val rssiAverage: Int? = null, private val cachedBatteryPercentage: Float? = null, @@ -47,9 +48,14 @@ data class AirPodsGen1( override fun create( scanResult: BleScanResult, - payload: ProximityPayload + payload: ProximityPayload, + flags: ApplePods.Flags ): ApplePods { - var basic = AirPodsGen1(scanResult = scanResult, payload = payload) + var basic = AirPodsGen1( + scanResult = scanResult, + payload = payload, + flags = flags, + ) val result = repo.search(basic) if (result != null) basic = basic.copy(identifier = result.id) diff --git a/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsGen2.kt b/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsGen2.kt index 1f6650ca..a3bb3a47 100644 --- a/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsGen2.kt +++ b/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsGen2.kt @@ -20,6 +20,7 @@ data class AirPodsGen2( override val seenCounter: Int = 1, override val scanResult: BleScanResult, override val payload: ProximityPayload, + override val flags: ApplePods.Flags, override val reliability: Float = PodDevice.BASE_CONFIDENCE, private val rssiAverage: Int? = null, private val cachedBatteryPercentage: Float? = null, @@ -47,9 +48,14 @@ data class AirPodsGen2( override fun create( scanResult: BleScanResult, - payload: ProximityPayload + payload: ProximityPayload, + flags: ApplePods.Flags ): ApplePods { - var basic = AirPodsGen2(scanResult = scanResult, payload = payload) + var basic = AirPodsGen2( + scanResult = scanResult, + payload = payload, + flags = flags, + ) val result = repo.search(basic) if (result != null) basic = basic.copy(identifier = result.id) diff --git a/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsGen3.kt b/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsGen3.kt index 68f7b978..e655cfbb 100644 --- a/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsGen3.kt +++ b/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsGen3.kt @@ -20,6 +20,7 @@ data class AirPodsGen3( override val seenCounter: Int = 1, override val scanResult: BleScanResult, override val payload: ProximityPayload, + override val flags: ApplePods.Flags, override val reliability: Float = PodDevice.BASE_CONFIDENCE, private val rssiAverage: Int? = null, private val cachedBatteryPercentage: Float? = null, @@ -47,9 +48,10 @@ data class AirPodsGen3( override fun create( scanResult: BleScanResult, - payload: ProximityPayload + payload: ProximityPayload, + flags: ApplePods.Flags ): ApplePods { - var basic = AirPodsGen3(scanResult = scanResult, payload = payload) + var basic = AirPodsGen3(scanResult = scanResult, payload = payload, flags = flags) val result = repo.search(basic) if (result != null) basic = basic.copy(identifier = result.id) diff --git a/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsGen4.kt b/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsGen4.kt index 3513917c..17a78c47 100644 --- a/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsGen4.kt +++ b/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsGen4.kt @@ -20,6 +20,7 @@ data class AirPodsGen4( override val seenCounter: Int = 1, override val scanResult: BleScanResult, override val payload: ProximityPayload, + override val flags: ApplePods.Flags, override val reliability: Float = PodDevice.BASE_CONFIDENCE, private val rssiAverage: Int? = null, private val cachedBatteryPercentage: Float? = null, @@ -47,9 +48,10 @@ data class AirPodsGen4( override fun create( scanResult: BleScanResult, - payload: ProximityPayload + payload: ProximityPayload, + flags: ApplePods.Flags ): ApplePods { - var basic = AirPodsGen4(scanResult = scanResult, payload = payload) + var basic = AirPodsGen4(scanResult = scanResult, payload = payload, flags = flags) val result = repo.search(basic) if (result != null) basic = basic.copy(identifier = result.id) diff --git a/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsGen4Anc.kt b/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsGen4Anc.kt index 75445db4..9bc82619 100644 --- a/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsGen4Anc.kt +++ b/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsGen4Anc.kt @@ -20,6 +20,7 @@ data class AirPodsGen4Anc( override val seenCounter: Int = 1, override val scanResult: BleScanResult, override val payload: ProximityPayload, + override val flags: ApplePods.Flags, override val reliability: Float = PodDevice.BASE_CONFIDENCE, private val rssiAverage: Int? = null, private val cachedBatteryPercentage: Float? = null, @@ -47,9 +48,10 @@ data class AirPodsGen4Anc( override fun create( scanResult: BleScanResult, - payload: ProximityPayload + payload: ProximityPayload, + flags: ApplePods.Flags ): ApplePods { - var basic = AirPodsGen4Anc(scanResult = scanResult, payload = payload) + var basic = AirPodsGen4Anc(scanResult = scanResult, payload = payload, flags = flags) val result = repo.search(basic) if (result != null) basic = basic.copy(identifier = result.id) diff --git a/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsMax.kt b/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsMax.kt index 0e8efd39..122360d3 100644 --- a/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsMax.kt +++ b/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsMax.kt @@ -24,6 +24,7 @@ data class AirPodsMax( override val seenCounter: Int = 1, override val scanResult: BleScanResult, override val payload: ProximityPayload, + override val flags: ApplePods.Flags, override val reliability: Float = PodDevice.BASE_CONFIDENCE, private val rssiAverage: Int? = null, ) : SingleApplePods, HasEarDetection, HasChargeDetection, HasAppleColor { @@ -49,9 +50,10 @@ data class AirPodsMax( override fun create( scanResult: BleScanResult, - payload: ProximityPayload + payload: ProximityPayload, + flags: ApplePods.Flags ): ApplePods { - var basic = AirPodsMax(scanResult = scanResult, payload = payload) + var basic = AirPodsMax(scanResult = scanResult, payload = payload, flags = flags) val result = repo.search(basic) if (result != null) basic = basic.copy(identifier = result.id) diff --git a/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsMaxUsbc.kt b/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsMaxUsbc.kt index 927f9903..e6ef5cbf 100644 --- a/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsMaxUsbc.kt +++ b/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsMaxUsbc.kt @@ -24,6 +24,7 @@ data class AirPodsMaxUsbc( override val seenCounter: Int = 1, override val scanResult: BleScanResult, override val payload: ProximityPayload, + override val flags: ApplePods.Flags, override val reliability: Float = PodDevice.BASE_CONFIDENCE, private val rssiAverage: Int? = null, ) : SingleApplePods, HasEarDetection, HasChargeDetection, HasAppleColor { @@ -49,9 +50,10 @@ data class AirPodsMaxUsbc( override fun create( scanResult: BleScanResult, - payload: ProximityPayload + payload: ProximityPayload, + flags: ApplePods.Flags ): ApplePods { - var basic = AirPodsMaxUsbc(scanResult = scanResult, payload = payload) + var basic = AirPodsMaxUsbc(scanResult = scanResult, payload = payload, flags = flags) val result = repo.search(basic) if (result != null) basic = basic.copy(identifier = result.id) diff --git a/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsPro.kt b/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsPro.kt index d38ef4e2..cdb2f3d5 100644 --- a/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsPro.kt +++ b/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsPro.kt @@ -23,6 +23,7 @@ data class AirPodsPro( override val seenCounter: Int = 1, override val scanResult: BleScanResult, override val payload: ProximityPayload, + override val flags: ApplePods.Flags, override val reliability: Float = PodDevice.BASE_CONFIDENCE, private val rssiAverage: Int? = null, private val cachedBatteryPercentage: Float? = null, @@ -66,11 +67,13 @@ data class AirPodsPro( override fun create( scanResult: BleScanResult, - payload: ProximityPayload + payload: ProximityPayload, + flags: ApplePods.Flags ): ApplePods { var basic = AirPodsPro( scanResult = scanResult, payload = payload, + flags = flags, ) val result = repo.search(basic) diff --git a/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsPro2.kt b/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsPro2.kt index 1aaef713..4d33be90 100644 --- a/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsPro2.kt +++ b/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsPro2.kt @@ -23,6 +23,7 @@ data class AirPodsPro2( override val seenCounter: Int = 1, override val scanResult: BleScanResult, override val payload: ProximityPayload, + override val flags: ApplePods.Flags, override val reliability: Float = PodDevice.BASE_CONFIDENCE, private val rssiAverage: Int? = null, private val cachedBatteryPercentage: Float? = null, @@ -66,9 +67,10 @@ data class AirPodsPro2( override fun create( scanResult: BleScanResult, - payload: ProximityPayload + payload: ProximityPayload, + flags: ApplePods.Flags ): ApplePods { - var basic = AirPodsPro2(scanResult = scanResult, payload = payload) + var basic = AirPodsPro2(scanResult = scanResult, payload = payload, flags = flags) val result = repo.search(basic) if (result != null) basic = basic.copy(identifier = result.id) diff --git a/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsPro2Usbc.kt b/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsPro2Usbc.kt index 4fb85594..910373ae 100644 --- a/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsPro2Usbc.kt +++ b/app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsPro2Usbc.kt @@ -23,6 +23,7 @@ data class AirPodsPro2Usbc( override val seenCounter: Int = 1, override val scanResult: BleScanResult, override val payload: ProximityPayload, + override val flags: ApplePods.Flags, override val reliability: Float = PodDevice.BASE_CONFIDENCE, private val rssiAverage: Int? = null, private val cachedBatteryPercentage: Float? = null, @@ -66,9 +67,10 @@ data class AirPodsPro2Usbc( override fun create( scanResult: BleScanResult, - payload: ProximityPayload + payload: ProximityPayload, + flags: ApplePods.Flags ): ApplePods { - var basic = AirPodsPro2Usbc(scanResult = scanResult, payload = payload) + var basic = AirPodsPro2Usbc(scanResult = scanResult, payload = payload, flags = flags) val result = repo.search(basic) if (result != null) basic = basic.copy(identifier = result.id) diff --git a/app-common/src/main/java/eu/darken/capod/pods/core/apple/beats/BeatsFitPro.kt b/app-common/src/main/java/eu/darken/capod/pods/core/apple/beats/BeatsFitPro.kt index 654ffca7..7e730e79 100644 --- a/app-common/src/main/java/eu/darken/capod/pods/core/apple/beats/BeatsFitPro.kt +++ b/app-common/src/main/java/eu/darken/capod/pods/core/apple/beats/BeatsFitPro.kt @@ -20,6 +20,7 @@ data class BeatsFitPro( override val seenCounter: Int = 1, override val scanResult: BleScanResult, override val payload: ProximityPayload, + override val flags: ApplePods.Flags, override val reliability: Float = PodDevice.BASE_CONFIDENCE, private val rssiAverage: Int? = null, private val cachedBatteryPercentage: Float? = null, @@ -47,9 +48,10 @@ data class BeatsFitPro( override fun create( scanResult: BleScanResult, - payload: ProximityPayload + payload: ProximityPayload, + flags: ApplePods.Flags ): ApplePods { - var basic = BeatsFitPro(scanResult = scanResult, payload = payload) + var basic = BeatsFitPro(scanResult = scanResult, payload = payload, flags = flags) val result = repo.search(basic) if (result != null) basic = basic.copy(identifier = result.id) diff --git a/app-common/src/main/java/eu/darken/capod/pods/core/apple/beats/BeatsFlex.kt b/app-common/src/main/java/eu/darken/capod/pods/core/apple/beats/BeatsFlex.kt index 06ed7352..9e0d5710 100644 --- a/app-common/src/main/java/eu/darken/capod/pods/core/apple/beats/BeatsFlex.kt +++ b/app-common/src/main/java/eu/darken/capod/pods/core/apple/beats/BeatsFlex.kt @@ -20,6 +20,7 @@ data class BeatsFlex( override val seenCounter: Int = 1, override val scanResult: BleScanResult, override val payload: ProximityPayload, + override val flags: ApplePods.Flags, override val reliability: Float = PodDevice.BASE_CONFIDENCE, private val rssiAverage: Int? = null, ) : SingleApplePods { @@ -39,9 +40,10 @@ data class BeatsFlex( override fun create( scanResult: BleScanResult, - payload: ProximityPayload + payload: ProximityPayload, + flags: ApplePods.Flags ): ApplePods { - var basic = BeatsFlex(scanResult = scanResult, payload = payload) + var basic = BeatsFlex(scanResult = scanResult, payload = payload, flags = flags) val result = repo.search(basic) if (result != null) basic = basic.copy(identifier = result.id) diff --git a/app-common/src/main/java/eu/darken/capod/pods/core/apple/beats/BeatsSolo3.kt b/app-common/src/main/java/eu/darken/capod/pods/core/apple/beats/BeatsSolo3.kt index 7c0734ad..5e4a68c0 100644 --- a/app-common/src/main/java/eu/darken/capod/pods/core/apple/beats/BeatsSolo3.kt +++ b/app-common/src/main/java/eu/darken/capod/pods/core/apple/beats/BeatsSolo3.kt @@ -20,6 +20,7 @@ data class BeatsSolo3( override val seenCounter: Int = 1, override val scanResult: BleScanResult, override val payload: ProximityPayload, + override val flags: ApplePods.Flags, override val reliability: Float = PodDevice.BASE_CONFIDENCE, private val rssiAverage: Int? = null, ) : SingleApplePods { @@ -38,9 +39,10 @@ data class BeatsSolo3( override fun create( scanResult: BleScanResult, - payload: ProximityPayload + payload: ProximityPayload, + flags: ApplePods.Flags ): ApplePods { - var basic = BeatsSolo3(scanResult = scanResult, payload = payload) + var basic = BeatsSolo3(scanResult = scanResult, payload = payload, flags = flags) val result = repo.search(basic) if (result != null) basic = basic.copy(identifier = result.id) diff --git a/app-common/src/main/java/eu/darken/capod/pods/core/apple/beats/BeatsStudio3.kt b/app-common/src/main/java/eu/darken/capod/pods/core/apple/beats/BeatsStudio3.kt index 9914ec1a..83094423 100644 --- a/app-common/src/main/java/eu/darken/capod/pods/core/apple/beats/BeatsStudio3.kt +++ b/app-common/src/main/java/eu/darken/capod/pods/core/apple/beats/BeatsStudio3.kt @@ -20,6 +20,7 @@ data class BeatsStudio3( override val seenCounter: Int = 1, override val scanResult: BleScanResult, override val payload: ProximityPayload, + override val flags: ApplePods.Flags, override val reliability: Float = PodDevice.BASE_CONFIDENCE, private val rssiAverage: Int? = null, ) : SingleApplePods { @@ -36,9 +37,10 @@ data class BeatsStudio3( override fun create( scanResult: BleScanResult, - payload: ProximityPayload + payload: ProximityPayload, + flags: ApplePods.Flags ): ApplePods { - var basic = BeatsStudio3(scanResult = scanResult, payload = payload) + var basic = BeatsStudio3(scanResult = scanResult, payload = payload, flags = flags) val result = repo.search(basic) if (result != null) basic = basic.copy(identifier = result.id) diff --git a/app-common/src/main/java/eu/darken/capod/pods/core/apple/beats/BeatsX.kt b/app-common/src/main/java/eu/darken/capod/pods/core/apple/beats/BeatsX.kt index 21936969..943ef318 100644 --- a/app-common/src/main/java/eu/darken/capod/pods/core/apple/beats/BeatsX.kt +++ b/app-common/src/main/java/eu/darken/capod/pods/core/apple/beats/BeatsX.kt @@ -20,6 +20,7 @@ data class BeatsX( override val seenCounter: Int = 1, override val scanResult: BleScanResult, override val payload: ProximityPayload, + override val flags: ApplePods.Flags, override val reliability: Float = PodDevice.BASE_CONFIDENCE, private val rssiAverage: Int? = null, ) : SingleApplePods { @@ -39,9 +40,10 @@ data class BeatsX( override fun create( scanResult: BleScanResult, - payload: ProximityPayload + payload: ProximityPayload, + flags: ApplePods.Flags ): ApplePods { - var basic = BeatsX(scanResult = scanResult, payload = payload) + var basic = BeatsX(scanResult = scanResult, payload = payload, flags = flags) val result = repo.search(basic) if (result != null) basic = basic.copy(identifier = result.id) diff --git a/app-common/src/main/java/eu/darken/capod/pods/core/apple/beats/PowerBeats3.kt b/app-common/src/main/java/eu/darken/capod/pods/core/apple/beats/PowerBeats3.kt index fe210ad2..ce28d58e 100644 --- a/app-common/src/main/java/eu/darken/capod/pods/core/apple/beats/PowerBeats3.kt +++ b/app-common/src/main/java/eu/darken/capod/pods/core/apple/beats/PowerBeats3.kt @@ -20,6 +20,7 @@ data class PowerBeats3( override val seenCounter: Int = 1, override val scanResult: BleScanResult, override val payload: ProximityPayload, + override val flags: ApplePods.Flags, override val reliability: Float = PodDevice.BASE_CONFIDENCE, private val rssiAverage: Int? = null, ) : SingleApplePods { @@ -39,9 +40,10 @@ data class PowerBeats3( override fun create( scanResult: BleScanResult, - payload: ProximityPayload + payload: ProximityPayload, + flags: ApplePods.Flags ): ApplePods { - var basic = PowerBeats3(scanResult = scanResult, payload = payload) + var basic = PowerBeats3(scanResult = scanResult, payload = payload, flags = flags) val result = repo.search(basic) if (result != null) basic = basic.copy(identifier = result.id) diff --git a/app-common/src/main/java/eu/darken/capod/pods/core/apple/beats/PowerBeats4.kt b/app-common/src/main/java/eu/darken/capod/pods/core/apple/beats/PowerBeats4.kt index 62ae4b36..07147950 100644 --- a/app-common/src/main/java/eu/darken/capod/pods/core/apple/beats/PowerBeats4.kt +++ b/app-common/src/main/java/eu/darken/capod/pods/core/apple/beats/PowerBeats4.kt @@ -21,6 +21,7 @@ data class PowerBeats4( override val seenCounter: Int = 1, override val scanResult: BleScanResult, override val payload: ProximityPayload, + override val flags: ApplePods.Flags, override val reliability: Float = PodDevice.BASE_CONFIDENCE, private val rssiAverage: Int? = null, ) : SingleApplePods, HasStateDetectionAirPods { @@ -40,9 +41,10 @@ data class PowerBeats4( override fun create( scanResult: BleScanResult, - payload: ProximityPayload + payload: ProximityPayload, + flags: ApplePods.Flags ): ApplePods { - var basic = PowerBeats4(scanResult = scanResult, payload = payload) + var basic = PowerBeats4(scanResult = scanResult, payload = payload, flags = flags) val result = repo.search(basic) if (result != null) basic = basic.copy(identifier = result.id) diff --git a/app-common/src/main/java/eu/darken/capod/pods/core/apple/beats/PowerBeatsPro.kt b/app-common/src/main/java/eu/darken/capod/pods/core/apple/beats/PowerBeatsPro.kt index 0fcf0287..e6844cc0 100644 --- a/app-common/src/main/java/eu/darken/capod/pods/core/apple/beats/PowerBeatsPro.kt +++ b/app-common/src/main/java/eu/darken/capod/pods/core/apple/beats/PowerBeatsPro.kt @@ -20,6 +20,7 @@ data class PowerBeatsPro( override val seenCounter: Int = 1, override val scanResult: BleScanResult, override val payload: ProximityPayload, + override val flags: ApplePods.Flags, override val reliability: Float = PodDevice.BASE_CONFIDENCE, private val rssiAverage: Int? = null, private val cachedBatteryPercentage: Float? = null, @@ -47,9 +48,10 @@ data class PowerBeatsPro( override fun create( scanResult: BleScanResult, - payload: ProximityPayload + payload: ProximityPayload, + flags: ApplePods.Flags ): ApplePods { - var basic = PowerBeatsPro(scanResult = scanResult, payload = payload) + var basic = PowerBeatsPro(scanResult = scanResult, payload = payload, flags = flags) val result = repo.search(basic) if (result != null) basic = basic.copy(identifier = result.id) diff --git a/app-common/src/main/java/eu/darken/capod/pods/core/apple/misc/FakeAirPodsGen1.kt b/app-common/src/main/java/eu/darken/capod/pods/core/apple/misc/FakeAirPodsGen1.kt index 62b85ad0..0b64f3d3 100644 --- a/app-common/src/main/java/eu/darken/capod/pods/core/apple/misc/FakeAirPodsGen1.kt +++ b/app-common/src/main/java/eu/darken/capod/pods/core/apple/misc/FakeAirPodsGen1.kt @@ -27,6 +27,7 @@ data class FakeAirPodsGen1( override val seenCounter: Int = 1, override val scanResult: BleScanResult, override val payload: ProximityPayload, + override val flags: ApplePods.Flags, override val reliability: Float = PodDevice.BASE_CONFIDENCE, private val rssiAverage: Int? = null, private val cachedBatteryPercentage: Float? = null, @@ -51,9 +52,10 @@ data class FakeAirPodsGen1( override fun create( scanResult: BleScanResult, - payload: ProximityPayload + payload: ProximityPayload, + flags: ApplePods.Flags ): ApplePods { - var basic = FakeAirPodsGen1(scanResult = scanResult, payload = payload) + var basic = FakeAirPodsGen1(scanResult = scanResult, payload = payload, flags = flags) val result = repo.search(basic) if (result != null) basic = basic.copy(identifier = result.id) diff --git a/app-common/src/main/java/eu/darken/capod/pods/core/apple/misc/FakeAirPodsGen2.kt b/app-common/src/main/java/eu/darken/capod/pods/core/apple/misc/FakeAirPodsGen2.kt index 0c73f368..58fa4219 100644 --- a/app-common/src/main/java/eu/darken/capod/pods/core/apple/misc/FakeAirPodsGen2.kt +++ b/app-common/src/main/java/eu/darken/capod/pods/core/apple/misc/FakeAirPodsGen2.kt @@ -25,6 +25,7 @@ data class FakeAirPodsGen2( override val seenCounter: Int = 1, override val scanResult: BleScanResult, override val payload: ProximityPayload, + override val flags: ApplePods.Flags, override val reliability: Float = PodDevice.BASE_CONFIDENCE, private val rssiAverage: Int? = null, private val cachedBatteryPercentage: Float? = null, @@ -49,9 +50,10 @@ data class FakeAirPodsGen2( override fun create( scanResult: BleScanResult, - payload: ProximityPayload + payload: ProximityPayload, + flags: ApplePods.Flags ): ApplePods { - var basic = FakeAirPodsGen2(scanResult = scanResult, payload = payload) + var basic = FakeAirPodsGen2(scanResult = scanResult, payload = payload, flags = flags) val result = repo.search(basic) if (result != null) basic = basic.copy(identifier = result.id) diff --git a/app-common/src/main/java/eu/darken/capod/pods/core/apple/misc/FakeAirPodsGen3.kt b/app-common/src/main/java/eu/darken/capod/pods/core/apple/misc/FakeAirPodsGen3.kt index 0ce21dc8..cb751d21 100644 --- a/app-common/src/main/java/eu/darken/capod/pods/core/apple/misc/FakeAirPodsGen3.kt +++ b/app-common/src/main/java/eu/darken/capod/pods/core/apple/misc/FakeAirPodsGen3.kt @@ -27,6 +27,7 @@ data class FakeAirPodsGen3( override val seenCounter: Int = 1, override val scanResult: BleScanResult, override val payload: ProximityPayload, + override val flags: ApplePods.Flags, override val reliability: Float = PodDevice.BASE_CONFIDENCE, private val rssiAverage: Int? = null, private val cachedBatteryPercentage: Float? = null, @@ -51,9 +52,10 @@ data class FakeAirPodsGen3( override fun create( scanResult: BleScanResult, - payload: ProximityPayload + payload: ProximityPayload, + flags: ApplePods.Flags ): ApplePods { - var basic = FakeAirPodsGen3(scanResult = scanResult, payload = payload) + var basic = FakeAirPodsGen3(scanResult = scanResult, payload = payload, flags = flags) val result = repo.search(basic) if (result != null) basic = basic.copy(identifier = result.id) diff --git a/app-common/src/main/java/eu/darken/capod/pods/core/apple/misc/FakeAirPodsPro.kt b/app-common/src/main/java/eu/darken/capod/pods/core/apple/misc/FakeAirPodsPro.kt index 1ef50214..4fbf8d55 100644 --- a/app-common/src/main/java/eu/darken/capod/pods/core/apple/misc/FakeAirPodsPro.kt +++ b/app-common/src/main/java/eu/darken/capod/pods/core/apple/misc/FakeAirPodsPro.kt @@ -29,6 +29,7 @@ data class FakeAirPodsPro( override val seenCounter: Int = 1, override val scanResult: BleScanResult, override val payload: ProximityPayload, + override val flags: ApplePods.Flags, override val reliability: Float = PodDevice.BASE_CONFIDENCE, private val rssiAverage: Int? = null, private val cachedBatteryPercentage: Float? = null, @@ -69,9 +70,10 @@ data class FakeAirPodsPro( override fun create( scanResult: BleScanResult, - payload: ProximityPayload + payload: ProximityPayload, + flags: ApplePods.Flags ): ApplePods { - var basic = FakeAirPodsPro(scanResult = scanResult, payload = payload) + var basic = FakeAirPodsPro(scanResult = scanResult, payload = payload, flags = flags) val result = repo.search(basic) if (result != null) basic = basic.copy(identifier = result.id) diff --git a/app-common/src/main/java/eu/darken/capod/pods/core/apple/misc/FakeAirPodsPro2.kt b/app-common/src/main/java/eu/darken/capod/pods/core/apple/misc/FakeAirPodsPro2.kt index ea699139..e229eff0 100644 --- a/app-common/src/main/java/eu/darken/capod/pods/core/apple/misc/FakeAirPodsPro2.kt +++ b/app-common/src/main/java/eu/darken/capod/pods/core/apple/misc/FakeAirPodsPro2.kt @@ -30,6 +30,7 @@ data class FakeAirPodsPro2( override val seenCounter: Int = 1, override val scanResult: BleScanResult, override val payload: ProximityPayload, + override val flags: ApplePods.Flags, override val reliability: Float = PodDevice.BASE_CONFIDENCE, private val rssiAverage: Int? = null, private val cachedBatteryPercentage: Float? = null, @@ -73,9 +74,10 @@ data class FakeAirPodsPro2( override fun create( scanResult: BleScanResult, - payload: ProximityPayload + payload: ProximityPayload, + flags: ApplePods.Flags ): ApplePods { - var basic = FakeAirPodsPro2(scanResult = scanResult, payload = payload) + var basic = FakeAirPodsPro2(scanResult = scanResult, payload = payload, flags = flags) val result = repo.search(basic) if (result != null) basic = basic.copy(identifier = result.id) diff --git a/app-common/src/main/java/eu/darken/capod/pods/core/apple/misc/UnknownAppleDevice.kt b/app-common/src/main/java/eu/darken/capod/pods/core/apple/misc/UnknownAppleDevice.kt index 6fabf9f0..b4a26ea0 100644 --- a/app-common/src/main/java/eu/darken/capod/pods/core/apple/misc/UnknownAppleDevice.kt +++ b/app-common/src/main/java/eu/darken/capod/pods/core/apple/misc/UnknownAppleDevice.kt @@ -20,6 +20,7 @@ data class UnknownAppleDevice( override val seenCounter: Int = 1, override val scanResult: BleScanResult, override val payload: ProximityPayload, + override val flags: ApplePods.Flags, override val reliability: Float = 0f, private val rssiAverage: Int? = null, ) : ApplePods { @@ -39,8 +40,9 @@ data class UnknownAppleDevice( override fun create( scanResult: BleScanResult, payload: ProximityPayload, + flags: ApplePods.Flags, ): ApplePods { - var basic = UnknownAppleDevice(scanResult = scanResult, payload = payload) + var basic = UnknownAppleDevice(scanResult = scanResult, payload = payload, flags = flags) val result = repo.search(basic) if (result != null) basic = basic.copy(identifier = result.id) diff --git a/app/src/main/java/eu/darken/capod/main/ui/overview/cards/pods/DualPodsCardVH.kt b/app/src/main/java/eu/darken/capod/main/ui/overview/cards/pods/DualPodsCardVH.kt index 7ee3d1d8..94299655 100644 --- a/app/src/main/java/eu/darken/capod/main/ui/overview/cards/pods/DualPodsCardVH.kt +++ b/app/src/main/java/eu/darken/capod/main/ui/overview/cards/pods/DualPodsCardVH.kt @@ -4,6 +4,7 @@ import android.graphics.Typeface import android.view.ViewGroup import androidx.core.view.isGone import androidx.core.view.isInvisible +import androidx.core.view.isVisible import eu.darken.capod.R import eu.darken.capod.common.lists.binding import eu.darken.capod.databinding.OverviewPodsDualItemBinding @@ -14,6 +15,7 @@ import eu.darken.capod.pods.core.HasDualMicrophone import eu.darken.capod.pods.core.HasEarDetectionDual import eu.darken.capod.pods.core.HasPodStyle import eu.darken.capod.pods.core.HasStateDetection +import eu.darken.capod.pods.core.apple.ApplePods import eu.darken.capod.pods.core.apple.DualApplePods import eu.darken.capod.pods.core.apple.DualApplePods.LidState import eu.darken.capod.pods.core.firstSeenFormatted @@ -62,6 +64,17 @@ class DualPodsCardVH(parent: ViewGroup) : reception.text = item.getReceptionText() + keyIcon.apply { + isVisible = device is ApplePods && device.flags.isIRKMatch + if (device !is ApplePods) return@apply + setImageResource( + when { + device.payload.private != null -> R.drawable.ic_key_24 + else -> R.drawable.ic_key_outline_24 + } + ) + } + // Pods battery state device.apply { podLeftBatteryIcon.setImageResource(getBatteryDrawable(batteryLeftPodPercent)) diff --git a/app/src/main/java/eu/darken/capod/main/ui/overview/cards/pods/SinglePodsCardVH.kt b/app/src/main/java/eu/darken/capod/main/ui/overview/cards/pods/SinglePodsCardVH.kt index c13c71e9..191e3a86 100644 --- a/app/src/main/java/eu/darken/capod/main/ui/overview/cards/pods/SinglePodsCardVH.kt +++ b/app/src/main/java/eu/darken/capod/main/ui/overview/cards/pods/SinglePodsCardVH.kt @@ -4,10 +4,17 @@ import android.graphics.Typeface import android.view.ViewGroup import androidx.core.view.isGone import androidx.core.view.isInvisible +import androidx.core.view.isVisible import eu.darken.capod.R import eu.darken.capod.common.lists.binding import eu.darken.capod.databinding.OverviewPodsSingleItemBinding -import eu.darken.capod.pods.core.* +import eu.darken.capod.pods.core.HasChargeDetection +import eu.darken.capod.pods.core.HasEarDetection +import eu.darken.capod.pods.core.SinglePodDevice +import eu.darken.capod.pods.core.apple.ApplePods +import eu.darken.capod.pods.core.getBatteryDrawable +import eu.darken.capod.pods.core.getBatteryLevelHeadset +import eu.darken.capod.pods.core.lastSeenFormatted import java.time.Instant class SinglePodsCardVH(parent: ViewGroup) : @@ -33,6 +40,17 @@ class SinglePodsCardVH(parent: ViewGroup) : reception.text = item.getReceptionText() + keyIcon.apply { + isVisible = device is ApplePods && device.flags.isIRKMatch + if (device !is ApplePods) return@apply + setImageResource( + when { + device.payload.private != null -> R.drawable.ic_key_24 + else -> R.drawable.ic_key_outline_24 + } + ) + } + // Battery level device.apply { batteryLabel.text = getBatteryLevelHeadset(context) diff --git a/app/src/main/res/layout/overview_pods_dual_item.xml b/app/src/main/res/layout/overview_pods_dual_item.xml index 9add02d0..7e7e3752 100644 --- a/app/src/main/res/layout/overview_pods_dual_item.xml +++ b/app/src/main/res/layout/overview_pods_dual_item.xml @@ -17,10 +17,10 @@ + + + +