From 8f609ca989e18e5f971adeab9e1727155affdce7 Mon Sep 17 00:00:00 2001 From: darken Date: Tue, 25 Jan 2022 22:54:53 +0100 Subject: [PATCH] Handle ear detection and microphone detection for dual pods better. --- .../capod/common/ByteArrayExtensions.kt | 16 ++-- .../cards/pods/DualApplePodsCardVH.kt | 12 +-- .../capod/pods/core/apple/AppleFactory.kt | 11 +++ .../darken/capod/pods/core/apple/ApplePods.kt | 16 +++- .../capod/pods/core/apple/DualApplePods.kt | 73 +++++++++++++------ .../capod/pods/core/apple/SingleApplePods.kt | 3 +- .../core/apple/protocol/ProximityPairing.kt | 6 +- .../core/apple/BasicSingleApplePodsTest.kt | 3 +- .../pods/core/apple/DualApplePodsTest.kt | 10 ++- .../pods/core/apple/SingleApplePodsTest.kt | 3 +- .../core/apple/airpods/AirPodsGen1Test.kt | 3 +- .../core/apple/airpods/AirPodsGen2Test.kt | 3 +- .../core/apple/airpods/AirPodsGen3Test.kt | 3 +- .../pods/core/apple/airpods/AirPodsMaxTest.kt | 6 +- .../pods/core/apple/airpods/AirPodsProTest.kt | 10 ++- .../pods/core/apple/beats/BeatsFlexText.kt | 3 +- .../pods/core/apple/beats/BeatsSolo3Test.kt | 3 +- .../pods/core/apple/beats/BeatsStudio3Test.kt | 3 +- .../capod/pods/core/apple/beats/BeatsXTest.kt | 3 +- .../pods/core/apple/beats/PowerBeats3Test.kt | 3 +- .../core/apple/beats/PowerBeatsProTest.kt | 7 +- 21 files changed, 140 insertions(+), 60 deletions(-) diff --git a/app/src/main/java/eu/darken/capod/common/ByteArrayExtensions.kt b/app/src/main/java/eu/darken/capod/common/ByteArrayExtensions.kt index 6e64ab87..98e65e7a 100644 --- a/app/src/main/java/eu/darken/capod/common/ByteArrayExtensions.kt +++ b/app/src/main/java/eu/darken/capod/common/ByteArrayExtensions.kt @@ -5,10 +5,16 @@ import java.util.* fun Byte.toHex(): String = String.format("%02X", this) fun UByte.toHex(): String = this.toByte().toHex() -val Byte.upperNibble get() = (this.toInt() shr 4 and 0b1111).toByte() -val Byte.lowerNibble get() = (this.toInt() and 0b1111).toByte() -val UByte.upperNibble get() = (this.toInt() shr 4 and 0b1111).toUByte() -val UByte.lowerNibble get() = (this.toInt() and 0b1111).toUByte() +val Byte.upperNibble get() = (this.toInt() shr 4 and 0b1111).toShort() +val Byte.lowerNibble get() = (this.toInt() and 0b1111).toShort() +val UByte.upperNibble get() = (this.toInt() shr 4 and 0b1111).toUShort() +val UByte.lowerNibble get() = (this.toInt() and 0b1111).toUShort() fun Byte.isBitSet(pos: Int): Boolean = BitSet.valueOf(arrayOf(this).toByteArray()).get(pos) -fun UByte.isBitSet(pos: Int): Boolean = this.toByte().isBitSet(pos) \ No newline at end of file +fun UByte.isBitSet(pos: Int): Boolean = this.toByte().isBitSet(pos) + +fun Short.isBitSet(pos: Int): Boolean = this.toByte().isBitSet(pos) +fun UShort.isBitSet(pos: Int): Boolean = this.toShort().isBitSet(pos) + +fun UShort.toBinaryString(): String = Integer.toBinaryString(this.toInt()).padStart(4, '0') +fun UByte.toBinaryString(): String = Integer.toBinaryString(this.toInt()).padStart(8, '0') diff --git a/app/src/main/java/eu/darken/capod/main/ui/overview/cards/pods/DualApplePodsCardVH.kt b/app/src/main/java/eu/darken/capod/main/ui/overview/cards/pods/DualApplePodsCardVH.kt index c193e379..704940a1 100644 --- a/app/src/main/java/eu/darken/capod/main/ui/overview/cards/pods/DualApplePodsCardVH.kt +++ b/app/src/main/java/eu/darken/capod/main/ui/overview/cards/pods/DualApplePodsCardVH.kt @@ -7,7 +7,6 @@ import eu.darken.capod.R import eu.darken.capod.common.lists.binding import eu.darken.capod.databinding.OverviewPodsAppleDualItemBinding import eu.darken.capod.pods.core.* -import eu.darken.capod.pods.core.HasDualPods.Pod import eu.darken.capod.pods.core.apple.DualApplePods import eu.darken.capod.pods.core.apple.DualApplePods.DeviceColor import eu.darken.capod.pods.core.apple.DualApplePods.LidState @@ -31,6 +30,9 @@ class DualApplePodsCardVH(parent: ViewGroup) : text = sb if (item.isMainPod) setTypeface(typeface, Typeface.BOLD) else setTypeface(typeface, Typeface.NORMAL) + if (item.showDebug) { + append(" [${device.primaryPod.name}]") + } } deviceIcon.setImageResource(device.iconRes) @@ -49,8 +51,8 @@ class DualApplePodsCardVH(parent: ViewGroup) : podLeftChargingIcon.isInvisible = !isLeftPodCharging podLeftChargingLabel.isInvisible = !isLeftPodCharging - podLeftMicrophoneIcon.isInvisible = microPhonePod != Pod.LEFT - podLeftMicrophoneLabel.isInvisible = microPhonePod != Pod.LEFT + podLeftMicrophoneIcon.isInvisible = !isLeftPodMicrophone + podLeftMicrophoneLabel.isInvisible = !isLeftPodMicrophone podLeftWearIcon.isInvisible = !isLeftPodInEar podLeftWearLabel.isInvisible = !isLeftPodInEar @@ -64,8 +66,8 @@ class DualApplePodsCardVH(parent: ViewGroup) : podRightChargingIcon.isInvisible = !isRightPodCharging podRightChargingLabel.isInvisible = !isRightPodCharging - podRightMicrophoneIcon.isInvisible = microPhonePod != Pod.RIGHT - podRightMicrophoneLabel.isInvisible = microPhonePod != Pod.RIGHT + podRightMicrophoneIcon.isInvisible = !isRightPodMicrophone + podRightMicrophoneLabel.isInvisible = !isRightPodMicrophone podRightWearIcon.isInvisible = !isRightPodInEar podRightWearLabel.isInvisible = !isRightPodInEar diff --git a/app/src/main/java/eu/darken/capod/pods/core/apple/AppleFactory.kt b/app/src/main/java/eu/darken/capod/pods/core/apple/AppleFactory.kt index da157924..b0c1d1e5 100644 --- a/app/src/main/java/eu/darken/capod/pods/core/apple/AppleFactory.kt +++ b/app/src/main/java/eu/darken/capod/pods/core/apple/AppleFactory.kt @@ -6,6 +6,9 @@ import eu.darken.capod.common.debug.logging.Logging.Priority.* import eu.darken.capod.common.debug.logging.asLog import eu.darken.capod.common.debug.logging.log import eu.darken.capod.common.debug.logging.logTag +import eu.darken.capod.common.lowerNibble +import eu.darken.capod.common.toBinaryString +import eu.darken.capod.common.upperNibble import eu.darken.capod.pods.core.PodDevice import eu.darken.capod.pods.core.apple.airpods.* import eu.darken.capod.pods.core.apple.beats.* @@ -63,6 +66,14 @@ class AppleFactory @Inject constructor( scanResult = scanResult, proximityMessage = pm, ) + if (device is DualApplePods) { + device.apply { + log( + TAG, + WARN + ) { "${rssi} ${scanResult.address} ${rawStatus.upperNibble.toBinaryString()} ${rawStatus.lowerNibble.toBinaryString()} primary=$primaryPod isCasePod=$isThisPodInThecase" } + } + } if (factory == null && !SILENCED_PMS.contains(device.rawDeviceModel) && scanResult.address != "6E:9E:D1:49:D2:6D") { SILENCED_PMS.add(device.rawDeviceModel) diff --git a/app/src/main/java/eu/darken/capod/pods/core/apple/ApplePods.kt b/app/src/main/java/eu/darken/capod/pods/core/apple/ApplePods.kt index 1e711f8c..a85dc981 100644 --- a/app/src/main/java/eu/darken/capod/pods/core/apple/ApplePods.kt +++ b/app/src/main/java/eu/darken/capod/pods/core/apple/ApplePods.kt @@ -5,6 +5,9 @@ import eu.darken.capod.common.bluetooth.BleScanResult import eu.darken.capod.common.debug.logging.Logging.Priority.DEBUG import eu.darken.capod.common.debug.logging.Logging.Priority.VERBOSE import eu.darken.capod.common.debug.logging.log +import eu.darken.capod.common.lowerNibble +import eu.darken.capod.common.toHex +import eu.darken.capod.common.upperNibble import eu.darken.capod.pods.core.PodDevice import eu.darken.capod.pods.core.apple.protocol.ContinuityProtocol import eu.darken.capod.pods.core.apple.protocol.ProximityPairing @@ -27,11 +30,20 @@ interface ApplePods : PodDevice { val rawStatus: UByte get() = proximityMessage.data[3] + val rawStatusHex: String + get() = rawStatus.toHex() + val rawPodsBattery: UByte get() = proximityMessage.data[4] - val rawCaseBattery: UByte - get() = proximityMessage.data[5] + val rawPodsBatteryHex: String + get() = rawPodsBattery.toHex() + + val rawFlags: UShort + get() = proximityMessage.data[5].upperNibble + + val rawCaseBattery: UShort + get() = proximityMessage.data[5].lowerNibble val rawCaseLidState: UByte get() = proximityMessage.data[6] diff --git a/app/src/main/java/eu/darken/capod/pods/core/apple/DualApplePods.kt b/app/src/main/java/eu/darken/capod/pods/core/apple/DualApplePods.kt index 8f93d8a7..cfc161b7 100644 --- a/app/src/main/java/eu/darken/capod/pods/core/apple/DualApplePods.kt +++ b/app/src/main/java/eu/darken/capod/pods/core/apple/DualApplePods.kt @@ -14,17 +14,24 @@ import eu.darken.capod.pods.core.HasDualPods.Pod interface DualApplePods : ApplePods, HasDualPods, HasDualEarDetection, HasCase { - val microPhonePod: Pod + val primaryPod: Pod get() = when (rawStatus.isBitSet(5)) { true -> Pod.LEFT false -> Pod.RIGHT } + /** + * Normally values for the left pod are in the lower nibbles, if the left pod is primary (microphone) + * If the right pod is the primary, the values are flipped. + */ + val areValuesFlipped: Boolean + get() = !rawStatus.isBitSet(5) + override val batteryLeftPodPercent: Float? get() { - val value = when (microPhonePod) { - Pod.LEFT -> rawPodsBattery.lowerNibble.toInt() - Pod.RIGHT -> rawPodsBattery.upperNibble.toInt() + val value = when (areValuesFlipped) { + true -> rawPodsBattery.upperNibble.toInt() + false -> rawPodsBattery.lowerNibble.toInt() } return when (value) { 15 -> null @@ -39,9 +46,9 @@ interface DualApplePods : ApplePods, HasDualPods, HasDualEarDetection, HasCase { override val batteryRightPodPercent: Float? get() { - val value = when (microPhonePod) { - Pod.LEFT -> rawPodsBattery.upperNibble.toInt() - Pod.RIGHT -> rawPodsBattery.lowerNibble.toInt() + val value = when (areValuesFlipped) { + true -> rawPodsBattery.lowerNibble.toInt() + false -> rawPodsBattery.upperNibble.toInt() } return when (value) { 15 -> null @@ -53,32 +60,56 @@ interface DualApplePods : ApplePods, HasDualPods, HasDualEarDetection, HasCase { } } } + + val isThisPodInThecase: Boolean + get() = rawStatus.isBitSet(6) + + val isOnePodInCase: Boolean + get() = rawStatus.isBitSet(4) + + val areBothPodsInCase: Boolean + get() = rawStatus.isBitSet(2) + override val isLeftPodInEar: Boolean - get() = when (microPhonePod) { - Pod.LEFT -> rawStatus.isBitSet(1) - Pod.RIGHT -> rawStatus.isBitSet(3) + get() = when (areValuesFlipped xor isThisPodInThecase) { + true -> rawStatus.isBitSet(3) + false -> rawStatus.isBitSet(1) } override val isRightPodInEar: Boolean - get() = when (microPhonePod) { - Pod.LEFT -> rawStatus.isBitSet(3) - Pod.RIGHT -> rawStatus.isBitSet(1) + get() = when (areValuesFlipped xor isThisPodInThecase) { + true -> rawStatus.isBitSet(1) + false -> rawStatus.isBitSet(3) } + /** + * The data flip bit is set if the left pod is primary. + * For the pod that is in the case, this is flipped again though. + */ + val isLeftPodMicrophone: Boolean + get() = rawStatus.isBitSet(5) xor isThisPodInThecase + + /** + * The data flip bit is UNset if the right pod is primary. + * For the pod that is in the case, this is flipped again though. + */ + val isRightPodMicrophone: Boolean + get() = !rawStatus.isBitSet(5) xor isThisPodInThecase + val isLeftPodCharging: Boolean - get() = when (microPhonePod) { - Pod.LEFT -> rawCaseBattery.upperNibble.isBitSet(0) - Pod.RIGHT -> rawCaseBattery.upperNibble.isBitSet(1) + get() = when (areValuesFlipped) { + false -> rawFlags.isBitSet(0) + true -> rawFlags.isBitSet(1) } val isRightPodCharging: Boolean - get() = when (microPhonePod) { - Pod.LEFT -> rawCaseBattery.upperNibble.isBitSet(1) - Pod.RIGHT -> rawCaseBattery.upperNibble.isBitSet(0) + get() = when (areValuesFlipped) { + false -> rawFlags.isBitSet(1) + true -> rawFlags.isBitSet(0) } override val batteryCasePercent: Float? - get() = when (val value = rawCaseBattery.lowerNibble.toInt()) { + get() = when (val value = rawCaseBattery.toInt()) { 15 -> null else -> if (value > 10) { log { "Case: Above 100% battery: $value" } @@ -89,7 +120,7 @@ interface DualApplePods : ApplePods, HasDualPods, HasDualEarDetection, HasCase { } override val isCaseCharging: Boolean - get() = rawCaseBattery.upperNibble.isBitSet(2) + get() = rawFlags.isBitSet(2) val caseLidState: LidState get() { diff --git a/app/src/main/java/eu/darken/capod/pods/core/apple/SingleApplePods.kt b/app/src/main/java/eu/darken/capod/pods/core/apple/SingleApplePods.kt index 7ddb43bf..6d325b3d 100644 --- a/app/src/main/java/eu/darken/capod/pods/core/apple/SingleApplePods.kt +++ b/app/src/main/java/eu/darken/capod/pods/core/apple/SingleApplePods.kt @@ -1,7 +1,6 @@ package eu.darken.capod.pods.core.apple import eu.darken.capod.common.isBitSet -import eu.darken.capod.common.upperNibble import eu.darken.capod.pods.core.HasEarDetection import eu.darken.capod.pods.core.HasSinglePod @@ -11,7 +10,7 @@ interface SingleApplePods : BasicSingleApplePods, HasEarDetection, HasSinglePod get() = rawStatus.isBitSet(1) val isHeadsetBeingCharged: Boolean - get() = rawCaseBattery.upperNibble.isBitSet(0) + get() = rawFlags.isBitSet(0) override val isBeingWorn: Boolean get() = isHeadphonesBeingWorn diff --git a/app/src/main/java/eu/darken/capod/pods/core/apple/protocol/ProximityPairing.kt b/app/src/main/java/eu/darken/capod/pods/core/apple/protocol/ProximityPairing.kt index d8eeb8e9..961703c4 100644 --- a/app/src/main/java/eu/darken/capod/pods/core/apple/protocol/ProximityPairing.kt +++ b/app/src/main/java/eu/darken/capod/pods/core/apple/protocol/ProximityPairing.kt @@ -19,7 +19,8 @@ object ProximityPairing { val vendor: UByte, val length: UByte, val device: UShort, - val batteryData: Set, + val podBatteryData: Set, + val caseBatteryData: UShort, val deviceColor: UByte, ) @@ -28,7 +29,8 @@ object ProximityPairing { length = PROXIMITY_PAIRING_MESSAGE_LENGTH.toUByte(), device = (((data[1].toInt() and 255) shl 8) or (data[2].toInt() and 255)).toUShort(), // Make comparison order independent - batteryData = setOf(data[4].upperNibble, data[4].lowerNibble), + podBatteryData = setOf(data[4].upperNibble, data[4].lowerNibble), + caseBatteryData = data[5].lowerNibble, deviceColor = data[7] ) diff --git a/app/src/test/java/eu/darken/capod/pods/core/apple/BasicSingleApplePodsTest.kt b/app/src/test/java/eu/darken/capod/pods/core/apple/BasicSingleApplePodsTest.kt index 0cb2ae83..4df26400 100644 --- a/app/src/test/java/eu/darken/capod/pods/core/apple/BasicSingleApplePodsTest.kt +++ b/app/src/test/java/eu/darken/capod/pods/core/apple/BasicSingleApplePodsTest.kt @@ -13,7 +13,8 @@ class BasicSingleApplePodsTest : BaseAirPodsTest() { rawDeviceModel shouldBe 0x0520.toUShort() rawStatus shouldBe 0x00.toUByte() rawPodsBattery shouldBe 0xF5.toUByte() - rawCaseBattery shouldBe 0x0F.toUByte() + rawFlags shouldBe 0x0.toUShort() + rawCaseBattery shouldBe 0xF.toUShort() rawCaseLidState shouldBe 0x01.toUByte() rawDeviceColor shouldBe 0x01.toUByte() rawSuffix shouldBe 0x00.toUByte() diff --git a/app/src/test/java/eu/darken/capod/pods/core/apple/DualApplePodsTest.kt b/app/src/test/java/eu/darken/capod/pods/core/apple/DualApplePodsTest.kt index 7bb7716b..a414ad0e 100644 --- a/app/src/test/java/eu/darken/capod/pods/core/apple/DualApplePodsTest.kt +++ b/app/src/test/java/eu/darken/capod/pods/core/apple/DualApplePodsTest.kt @@ -1,6 +1,5 @@ package eu.darken.capod.pods.core.apple -import eu.darken.capod.pods.core.HasDualPods import io.kotest.matchers.shouldBe import kotlinx.coroutines.test.runBlockingTest import org.junit.jupiter.api.Test @@ -15,7 +14,8 @@ class DualApplePodsTest : BaseAirPodsTest() { rawDeviceModel shouldBe 0x0e20.toUShort() rawStatus shouldBe 0x54.toUByte() rawPodsBattery shouldBe 0xAA.toUByte() - rawCaseBattery shouldBe 0xB5.toUByte() + rawFlags shouldBe 0xB.toUShort() + rawCaseBattery shouldBe 0x5.toUShort() rawCaseLidState shouldBe 0x31.toUByte() rawDeviceColor shouldBe 0x00.toUByte() rawSuffix shouldBe 0x00.toUByte() @@ -27,12 +27,14 @@ class DualApplePodsTest : BaseAirPodsTest() { create("07 19 01 0E 20 >2B< AA B5 31 00 00 E0 0C A7 8A 60 4B D3 7D F4 60 4F 2C 73 E9 A7 F4") { // 00101011 // --^----- - microPhonePod shouldBe HasDualPods.Pod.LEFT + isLeftPodMicrophone shouldBe true + isRightPodMicrophone shouldBe false } create("07 19 01 0E 20 >0B< AA B5 31 00 00 E0 0C A7 8A 60 4B D3 7D F4 60 4F 2C 73 E9 A7 F4") { // 00001011 // --^----- - microPhonePod shouldBe HasDualPods.Pod.RIGHT + isLeftPodMicrophone shouldBe false + isRightPodMicrophone shouldBe true } } diff --git a/app/src/test/java/eu/darken/capod/pods/core/apple/SingleApplePodsTest.kt b/app/src/test/java/eu/darken/capod/pods/core/apple/SingleApplePodsTest.kt index e60bc0e2..658e18b4 100644 --- a/app/src/test/java/eu/darken/capod/pods/core/apple/SingleApplePodsTest.kt +++ b/app/src/test/java/eu/darken/capod/pods/core/apple/SingleApplePodsTest.kt @@ -14,7 +14,8 @@ class SingleApplePodsTest : BaseAirPodsTest() { rawDeviceModel shouldBe 0x0A20.toUShort() rawStatus shouldBe 0x62.toUByte() rawPodsBattery shouldBe 0x04.toUByte() - rawCaseBattery shouldBe 0x80.toUByte() + rawFlags shouldBe 0x8.toUShort() + rawCaseBattery shouldBe 0x0.toUShort() rawCaseLidState shouldBe 0x01.toUByte() rawDeviceColor shouldBe 0x0F.toUByte() rawSuffix shouldBe 0x40.toUByte() diff --git a/app/src/test/java/eu/darken/capod/pods/core/apple/airpods/AirPodsGen1Test.kt b/app/src/test/java/eu/darken/capod/pods/core/apple/airpods/AirPodsGen1Test.kt index 13ae1aaa..897c02b1 100644 --- a/app/src/test/java/eu/darken/capod/pods/core/apple/airpods/AirPodsGen1Test.kt +++ b/app/src/test/java/eu/darken/capod/pods/core/apple/airpods/AirPodsGen1Test.kt @@ -16,7 +16,8 @@ class AirPodsGen1Test : BaseAirPodsTest() { rawDeviceModel shouldBe 0x0220.toUShort() rawStatus shouldBe 0x55.toUByte() rawPodsBattery shouldBe 0xAF.toUByte() - rawCaseBattery shouldBe 0x56.toUByte() + rawFlags shouldBe 0x5.toUShort() + rawCaseBattery shouldBe 0x6.toUShort() rawCaseLidState shouldBe 0x31.toUByte() rawDeviceColor shouldBe 0x00.toUByte() rawSuffix shouldBe 0x00.toUByte() diff --git a/app/src/test/java/eu/darken/capod/pods/core/apple/airpods/AirPodsGen2Test.kt b/app/src/test/java/eu/darken/capod/pods/core/apple/airpods/AirPodsGen2Test.kt index 7ba41dce..e3dd1964 100644 --- a/app/src/test/java/eu/darken/capod/pods/core/apple/airpods/AirPodsGen2Test.kt +++ b/app/src/test/java/eu/darken/capod/pods/core/apple/airpods/AirPodsGen2Test.kt @@ -15,7 +15,8 @@ class AirPodsGen2Test : BaseAirPodsTest() { rawDeviceModel shouldBe 0x0F20.toUShort() rawStatus shouldBe 0x02.toUByte() rawPodsBattery shouldBe 0xF9.toUByte() - rawCaseBattery shouldBe 0x8F.toUByte() + rawFlags shouldBe 0x8.toUShort() + rawCaseBattery shouldBe 0xF.toUShort() rawCaseLidState shouldBe 0x01.toUByte() rawDeviceColor shouldBe 0x00.toUByte() rawSuffix shouldBe 0x05.toUByte() diff --git a/app/src/test/java/eu/darken/capod/pods/core/apple/airpods/AirPodsGen3Test.kt b/app/src/test/java/eu/darken/capod/pods/core/apple/airpods/AirPodsGen3Test.kt index 942eec53..3c60347c 100644 --- a/app/src/test/java/eu/darken/capod/pods/core/apple/airpods/AirPodsGen3Test.kt +++ b/app/src/test/java/eu/darken/capod/pods/core/apple/airpods/AirPodsGen3Test.kt @@ -15,7 +15,8 @@ class AirPodsGen3Test : BaseAirPodsTest() { rawDeviceModel shouldBe 0x1320.toUShort() rawStatus shouldBe 0x75.toUByte() rawPodsBattery shouldBe 0xAA.toUByte() - rawCaseBattery shouldBe 0xB9.toUByte() + rawFlags shouldBe 0xB.toUShort() + rawCaseBattery shouldBe 0x9.toUShort() rawCaseLidState shouldBe 0x31.toUByte() rawDeviceColor shouldBe 0x00.toUByte() rawSuffix shouldBe 0x04.toUByte() diff --git a/app/src/test/java/eu/darken/capod/pods/core/apple/airpods/AirPodsMaxTest.kt b/app/src/test/java/eu/darken/capod/pods/core/apple/airpods/AirPodsMaxTest.kt index a49cfe8f..89e8f750 100644 --- a/app/src/test/java/eu/darken/capod/pods/core/apple/airpods/AirPodsMaxTest.kt +++ b/app/src/test/java/eu/darken/capod/pods/core/apple/airpods/AirPodsMaxTest.kt @@ -15,7 +15,8 @@ class AirPodsMaxTest : BaseAirPodsTest() { rawDeviceModel shouldBe 0x0A20.toUShort() rawStatus shouldBe 0x62.toUByte() rawPodsBattery shouldBe 0x04.toUByte() - rawCaseBattery shouldBe 0x80.toUByte() + rawFlags shouldBe 0x8.toUShort() + rawCaseBattery shouldBe 0x0.toUShort() rawCaseLidState shouldBe 0x01.toUByte() rawDeviceColor shouldBe 0x0F.toUByte() rawSuffix shouldBe 0x40.toUByte() @@ -36,7 +37,8 @@ class AirPodsMaxTest : BaseAirPodsTest() { rawDeviceModel shouldBe 0x0A20.toUShort() rawStatus shouldBe 0x02.toUByte() rawPodsBattery shouldBe 0x05.toUByte() - rawCaseBattery shouldBe 0x80.toUByte() + rawFlags shouldBe 0x8.toUShort() + rawCaseBattery shouldBe 0x0.toUShort() rawCaseLidState shouldBe 0x04.toUByte() rawDeviceColor shouldBe 0x0F.toUByte() rawSuffix shouldBe 0x44.toUByte() diff --git a/app/src/test/java/eu/darken/capod/pods/core/apple/airpods/AirPodsProTest.kt b/app/src/test/java/eu/darken/capod/pods/core/apple/airpods/AirPodsProTest.kt index be599755..0191baeb 100644 --- a/app/src/test/java/eu/darken/capod/pods/core/apple/airpods/AirPodsProTest.kt +++ b/app/src/test/java/eu/darken/capod/pods/core/apple/airpods/AirPodsProTest.kt @@ -1,6 +1,5 @@ package eu.darken.capod.pods.core.apple.airpods -import eu.darken.capod.pods.core.HasDualPods import eu.darken.capod.pods.core.apple.BaseAirPodsTest import eu.darken.capod.pods.core.apple.DualApplePods import io.kotest.matchers.shouldBe @@ -17,12 +16,14 @@ class AirPodsProTest : BaseAirPodsTest() { rawDeviceModel shouldBe 0x0e20.toUShort() rawStatus shouldBe 0x54.toUByte() rawPodsBattery shouldBe 0xAA.toUByte() - rawCaseBattery shouldBe 0xB5.toUByte() + rawFlags shouldBe 0xB.toUShort() + rawCaseBattery shouldBe 0x5.toUShort() rawCaseLidState shouldBe 0x31.toUByte() rawDeviceColor shouldBe 0x00.toUByte() rawSuffix shouldBe 0x00.toUByte() - microPhonePod shouldBe HasDualPods.Pod.RIGHT + isLeftPodMicrophone shouldBe true + isRightPodMicrophone shouldBe false batteryLeftPodPercent shouldBe 1.0f batteryRightPodPercent shouldBe 1.0f @@ -39,7 +40,8 @@ class AirPodsProTest : BaseAirPodsTest() { @Test fun `test AirPods from my downstairs neighbour`() = runBlockingTest { create("07 19 01 0E 20 00 F3 8F 02 00 04 79 C6 3F F9 C3 15 D9 11 A1 3C B1 58 66 B9 8B 67") { - microPhonePod shouldBe HasDualPods.Pod.RIGHT + isLeftPodMicrophone shouldBe false + isRightPodMicrophone shouldBe true batteryLeftPodPercent shouldBe null batteryRightPodPercent shouldBe 0.3f diff --git a/app/src/test/java/eu/darken/capod/pods/core/apple/beats/BeatsFlexText.kt b/app/src/test/java/eu/darken/capod/pods/core/apple/beats/BeatsFlexText.kt index d744b56c..58675616 100644 --- a/app/src/test/java/eu/darken/capod/pods/core/apple/beats/BeatsFlexText.kt +++ b/app/src/test/java/eu/darken/capod/pods/core/apple/beats/BeatsFlexText.kt @@ -15,7 +15,8 @@ class BeatsFlexText : BaseAirPodsTest() { rawDeviceModel shouldBe 0x1020.toUShort() rawStatus shouldBe 0x0A.toUByte() rawPodsBattery shouldBe 0xF4.toUByte() - rawCaseBattery shouldBe 0x8F.toUByte() + rawFlags shouldBe 0x8.toUShort() + rawCaseBattery shouldBe 0xF.toUShort() rawCaseLidState shouldBe 0x00.toUByte() rawDeviceColor shouldBe 0x01.toUByte() rawSuffix shouldBe 0x00.toUByte() diff --git a/app/src/test/java/eu/darken/capod/pods/core/apple/beats/BeatsSolo3Test.kt b/app/src/test/java/eu/darken/capod/pods/core/apple/beats/BeatsSolo3Test.kt index 180ab3af..ed682554 100644 --- a/app/src/test/java/eu/darken/capod/pods/core/apple/beats/BeatsSolo3Test.kt +++ b/app/src/test/java/eu/darken/capod/pods/core/apple/beats/BeatsSolo3Test.kt @@ -15,7 +15,8 @@ class BeatsSolo3Test : BaseAirPodsTest() { rawDeviceModel shouldBe 0x0620.toUShort() rawStatus shouldBe 0x62.toUByte() rawPodsBattery shouldBe 0x04.toUByte() - rawCaseBattery shouldBe 0x80.toUByte() + rawFlags shouldBe 0x8.toUShort() + rawCaseBattery shouldBe 0x0.toUShort() rawCaseLidState shouldBe 0x01.toUByte() rawDeviceColor shouldBe 0x0F.toUByte() rawSuffix shouldBe 0x40.toUByte() diff --git a/app/src/test/java/eu/darken/capod/pods/core/apple/beats/BeatsStudio3Test.kt b/app/src/test/java/eu/darken/capod/pods/core/apple/beats/BeatsStudio3Test.kt index f6c1354b..ac434ce1 100644 --- a/app/src/test/java/eu/darken/capod/pods/core/apple/beats/BeatsStudio3Test.kt +++ b/app/src/test/java/eu/darken/capod/pods/core/apple/beats/BeatsStudio3Test.kt @@ -15,7 +15,8 @@ class BeatsStudio3Test : BaseAirPodsTest() { rawDeviceModel shouldBe 0x0920.toUShort() rawStatus shouldBe 0x62.toUByte() rawPodsBattery shouldBe 0x04.toUByte() - rawCaseBattery shouldBe 0x80.toUByte() + rawFlags shouldBe 0x8.toUShort() + rawCaseBattery shouldBe 0x0.toUShort() rawCaseLidState shouldBe 0x01.toUByte() rawDeviceColor shouldBe 0x0F.toUByte() rawSuffix shouldBe 0x40.toUByte() diff --git a/app/src/test/java/eu/darken/capod/pods/core/apple/beats/BeatsXTest.kt b/app/src/test/java/eu/darken/capod/pods/core/apple/beats/BeatsXTest.kt index 27514e0f..db617da2 100644 --- a/app/src/test/java/eu/darken/capod/pods/core/apple/beats/BeatsXTest.kt +++ b/app/src/test/java/eu/darken/capod/pods/core/apple/beats/BeatsXTest.kt @@ -15,7 +15,8 @@ class BeatsXTest : BaseAirPodsTest() { rawDeviceModel shouldBe 0x0520.toUShort() rawStatus shouldBe 0x00.toUByte() rawPodsBattery shouldBe 0xF5.toUByte() - rawCaseBattery shouldBe 0x0F.toUByte() + rawFlags shouldBe 0x0.toUShort() + rawCaseBattery shouldBe 0xF.toUShort() rawCaseLidState shouldBe 0x01.toUByte() rawDeviceColor shouldBe 0x01.toUByte() rawSuffix shouldBe 0x00.toUByte() diff --git a/app/src/test/java/eu/darken/capod/pods/core/apple/beats/PowerBeats3Test.kt b/app/src/test/java/eu/darken/capod/pods/core/apple/beats/PowerBeats3Test.kt index 9419c0cb..7a0e58cd 100644 --- a/app/src/test/java/eu/darken/capod/pods/core/apple/beats/PowerBeats3Test.kt +++ b/app/src/test/java/eu/darken/capod/pods/core/apple/beats/PowerBeats3Test.kt @@ -15,7 +15,8 @@ class PowerBeats3Test : BaseAirPodsTest() { rawDeviceModel shouldBe 0x0320.toUShort() rawStatus shouldBe 0x62.toUByte() rawPodsBattery shouldBe 0x04.toUByte() - rawCaseBattery shouldBe 0x80.toUByte() + rawFlags shouldBe 0x8.toUShort() + rawCaseBattery shouldBe 0x0.toUShort() rawCaseLidState shouldBe 0x01.toUByte() rawDeviceColor shouldBe 0x0F.toUByte() rawSuffix shouldBe 0x40.toUByte() diff --git a/app/src/test/java/eu/darken/capod/pods/core/apple/beats/PowerBeatsProTest.kt b/app/src/test/java/eu/darken/capod/pods/core/apple/beats/PowerBeatsProTest.kt index e10eda8a..36378b37 100644 --- a/app/src/test/java/eu/darken/capod/pods/core/apple/beats/PowerBeatsProTest.kt +++ b/app/src/test/java/eu/darken/capod/pods/core/apple/beats/PowerBeatsProTest.kt @@ -1,6 +1,5 @@ package eu.darken.capod.pods.core.apple.beats -import eu.darken.capod.pods.core.HasDualPods import eu.darken.capod.pods.core.apple.BaseAirPodsTest import eu.darken.capod.pods.core.apple.DualApplePods import io.kotest.matchers.shouldBe @@ -17,12 +16,14 @@ class PowerBeatsProTest : BaseAirPodsTest() { rawDeviceModel shouldBe 0x0B20.toUShort() rawStatus shouldBe 0x54.toUByte() rawPodsBattery shouldBe 0xAA.toUByte() - rawCaseBattery shouldBe 0xB5.toUByte() + rawFlags shouldBe 0xB.toUShort() + rawCaseBattery shouldBe 0x5.toUShort() rawCaseLidState shouldBe 0x31.toUByte() rawDeviceColor shouldBe 0x00.toUByte() rawSuffix shouldBe 0x00.toUByte() - microPhonePod shouldBe HasDualPods.Pod.RIGHT + isLeftPodMicrophone shouldBe true + isRightPodMicrophone shouldBe false batteryLeftPodPercent shouldBe 1.0f batteryRightPodPercent shouldBe 1.0f