mirror of
https://github.com/d4rken-org/capod.git
synced 2026-09-16 11:16:12 -04:00
Improve feature support for fake AirPods Pro
Remove microphone detection and add pod charging and ear detection.
This commit is contained in:
@@ -1,15 +1,14 @@
|
|||||||
package eu.darken.capod.pods.core.apple.misc
|
package eu.darken.capod.pods.core.apple.misc
|
||||||
|
|
||||||
|
import androidx.annotation.DrawableRes
|
||||||
|
import eu.darken.capod.common.R
|
||||||
import eu.darken.capod.common.bluetooth.BleScanResult
|
import eu.darken.capod.common.bluetooth.BleScanResult
|
||||||
import eu.darken.capod.common.debug.logging.log
|
import eu.darken.capod.common.debug.logging.log
|
||||||
import eu.darken.capod.common.debug.logging.logTag
|
import eu.darken.capod.common.debug.logging.logTag
|
||||||
import eu.darken.capod.common.isBitSet
|
import eu.darken.capod.common.isBitSet
|
||||||
import eu.darken.capod.common.lowerNibble
|
import eu.darken.capod.common.lowerNibble
|
||||||
import eu.darken.capod.common.upperNibble
|
import eu.darken.capod.common.upperNibble
|
||||||
import eu.darken.capod.pods.core.DualPodDevice
|
import eu.darken.capod.pods.core.*
|
||||||
import eu.darken.capod.pods.core.HasCase
|
|
||||||
import eu.darken.capod.pods.core.HasDualMicrophone
|
|
||||||
import eu.darken.capod.pods.core.PodDevice
|
|
||||||
import eu.darken.capod.pods.core.apple.ApplePods
|
import eu.darken.capod.pods.core.apple.ApplePods
|
||||||
import eu.darken.capod.pods.core.apple.ApplePodsFactory
|
import eu.darken.capod.pods.core.apple.ApplePodsFactory
|
||||||
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
||||||
@@ -31,10 +30,26 @@ data class FakeAirPodsPro constructor(
|
|||||||
override val confidence: Float = PodDevice.BASE_CONFIDENCE,
|
override val confidence: Float = PodDevice.BASE_CONFIDENCE,
|
||||||
private val rssiAverage: Int? = null,
|
private val rssiAverage: Int? = null,
|
||||||
private val cachedBatteryPercentage: Float? = null,
|
private val cachedBatteryPercentage: Float? = null,
|
||||||
) : ApplePods, DualPodDevice, HasDualMicrophone, HasCase {
|
) : ApplePods, DualPodDevice, HasChargeDetectionDual, HasEarDetectionDual, HasCase {
|
||||||
|
|
||||||
override val model: PodDevice.Model = PodDevice.Model.FAKE_AIRPODS_PRO
|
override val model: PodDevice.Model = PodDevice.Model.FAKE_AIRPODS_PRO
|
||||||
|
|
||||||
|
@get:DrawableRes
|
||||||
|
override val iconRes: Int
|
||||||
|
get() = R.drawable.devic_airpods_pro2_both
|
||||||
|
|
||||||
|
@get:DrawableRes
|
||||||
|
override val caseIcon: Int
|
||||||
|
get() = R.drawable.devic_airpods_pro2_case
|
||||||
|
|
||||||
|
@get:DrawableRes
|
||||||
|
override val leftPodIcon: Int
|
||||||
|
get() = R.drawable.devic_airpods_pro2_left
|
||||||
|
|
||||||
|
@get:DrawableRes
|
||||||
|
override val rightPodIcon: Int
|
||||||
|
get() = R.drawable.devic_airpods_pro2_right
|
||||||
|
|
||||||
override val rssi: Int
|
override val rssi: Int
|
||||||
get() = rssiAverage ?: super<ApplePods>.rssi
|
get() = rssiAverage ?: super<ApplePods>.rssi
|
||||||
|
|
||||||
@@ -79,22 +94,32 @@ data class FakeAirPodsPro constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val isThisPodInThecase: Boolean
|
override val isLeftPodCharging: Boolean
|
||||||
|
get() = when (areValuesFlipped) {
|
||||||
|
false -> rawFlags.isBitSet(0)
|
||||||
|
true -> rawFlags.isBitSet(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val isRightPodCharging: Boolean
|
||||||
|
get() = when (areValuesFlipped) {
|
||||||
|
false -> rawFlags.isBitSet(1)
|
||||||
|
true -> rawFlags.isBitSet(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val isThisPodInThecase: Boolean
|
||||||
get() = rawStatus.isBitSet(6)
|
get() = rawStatus.isBitSet(6)
|
||||||
|
|
||||||
/**
|
override val isLeftPodInEar: Boolean
|
||||||
* The data flip bit is set if the left pod is primary.
|
get() = when (areValuesFlipped xor isThisPodInThecase) {
|
||||||
* For the pod that is in the case, this is flipped again though.
|
true -> rawStatus.isBitSet(3)
|
||||||
*/
|
false -> rawStatus.isBitSet(1)
|
||||||
override val isLeftPodMicrophone: Boolean
|
}
|
||||||
get() = rawStatus.isBitSet(5) xor isThisPodInThecase
|
|
||||||
|
|
||||||
/**
|
override val isRightPodInEar: Boolean
|
||||||
* The data flip bit is UNset if the right pod is primary.
|
get() = when (areValuesFlipped xor isThisPodInThecase) {
|
||||||
* For the pod that is in the case, this is flipped again though.
|
true -> rawStatus.isBitSet(1)
|
||||||
*/
|
false -> rawStatus.isBitSet(3)
|
||||||
override val isRightPodMicrophone: Boolean
|
}
|
||||||
get() = !rawStatus.isBitSet(5) xor isThisPodInThecase
|
|
||||||
|
|
||||||
override val batteryCasePercent: Float?
|
override val batteryCasePercent: Float?
|
||||||
get() = when (val value = rawCaseBattery.toInt()) {
|
get() = when (val value = rawCaseBattery.toInt()) {
|
||||||
|
|||||||
@@ -24,6 +24,12 @@ class FakeAirPodsProTest : BaseAirPodsTest() {
|
|||||||
batteryLeftPodPercent shouldBe 1.0f
|
batteryLeftPodPercent shouldBe 1.0f
|
||||||
batteryRightPodPercent shouldBe 1.0f
|
batteryRightPodPercent shouldBe 1.0f
|
||||||
|
|
||||||
|
isLeftPodCharging shouldBe true
|
||||||
|
isRightPodCharging shouldBe true
|
||||||
|
|
||||||
|
isLeftPodInEar shouldBe false
|
||||||
|
isRightPodInEar shouldBe false
|
||||||
|
|
||||||
isCaseCharging shouldBe false
|
isCaseCharging shouldBe false
|
||||||
|
|
||||||
batteryCasePercent shouldBe 0.7f
|
batteryCasePercent shouldBe 0.7f
|
||||||
|
|||||||
Reference in New Issue
Block a user