mirror of
https://github.com/d4rken-org/capod.git
synced 2026-09-16 11:16:12 -04:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
51f9c5c7d8 | ||
|
|
15141c8528 | ||
|
|
0cdac10fd4 |
@@ -34,6 +34,7 @@ Currently supported models:
|
|||||||
* Beats Studio 3
|
* Beats Studio 3
|
||||||
* Beats X
|
* Beats X
|
||||||
* Beats Flex
|
* Beats Flex
|
||||||
|
* Beats Fit Pro
|
||||||
* Fake AirPods 1. Generation 🎭
|
* Fake AirPods 1. Generation 🎭
|
||||||
* Fake AirPods 2. Generation 🎭
|
* Fake AirPods 2. Generation 🎭
|
||||||
* Fake AirPods 3. Generation 🎭
|
* Fake AirPods 3. Generation 🎭
|
||||||
|
|||||||
@@ -79,13 +79,13 @@ abstract class ApplePodsFactory<PodType : ApplePods>(private val tag: String) {
|
|||||||
.mapNotNull { it.batteryCasePercent }
|
.mapNotNull { it.batteryCasePercent }
|
||||||
.lastOrNull()
|
.lastOrNull()
|
||||||
|
|
||||||
fun KnownDevice.getLatestCaseLidState(basic: DualAirPods): DualAirPods.LidState? {
|
fun KnownDevice.getLatestCaseLidState(basic: DualApplePods): DualApplePods.LidState? {
|
||||||
val definitive = setOf(DualAirPods.LidState.OPEN, DualAirPods.LidState.CLOSED)
|
val definitive = setOf(DualApplePods.LidState.OPEN, DualApplePods.LidState.CLOSED)
|
||||||
if (definitive.contains(basic.caseLidState)) return null
|
if (definitive.contains(basic.caseLidState)) return null
|
||||||
|
|
||||||
return history
|
return history
|
||||||
.filterIsInstance<AirPodsPro>() // TODO why is this AirPodsPro specific here?
|
.filterIsInstance<AirPodsPro>() // TODO why is this AirPodsPro specific here?
|
||||||
.lastOrNull { it.caseLidState != DualAirPods.LidState.NOT_IN_CASE }
|
.lastOrNull { it.caseLidState != DualApplePods.LidState.NOT_IN_CASE }
|
||||||
?.caseLidState
|
?.caseLidState
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-22
@@ -1,8 +1,5 @@
|
|||||||
package eu.darken.capod.pods.core.apple
|
package eu.darken.capod.pods.core.apple
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import androidx.annotation.StringRes
|
|
||||||
import eu.darken.capod.common.R
|
|
||||||
import eu.darken.capod.common.debug.logging.log
|
import eu.darken.capod.common.debug.logging.log
|
||||||
import eu.darken.capod.common.isBitSet
|
import eu.darken.capod.common.isBitSet
|
||||||
import eu.darken.capod.common.lowerNibble
|
import eu.darken.capod.common.lowerNibble
|
||||||
@@ -10,8 +7,8 @@ import eu.darken.capod.common.upperNibble
|
|||||||
import eu.darken.capod.pods.core.*
|
import eu.darken.capod.pods.core.*
|
||||||
import eu.darken.capod.pods.core.DualPodDevice.Pod
|
import eu.darken.capod.pods.core.DualPodDevice.Pod
|
||||||
|
|
||||||
interface DualAirPods : ApplePods, HasChargeDetectionDual, DualPodDevice, HasEarDetectionDual, HasCase,
|
interface DualApplePods : ApplePods, HasChargeDetectionDual, DualPodDevice, HasEarDetectionDual, HasCase,
|
||||||
HasStateDetection, HasDualMicrophone, HasAppleColor {
|
HasDualMicrophone, HasAppleColor {
|
||||||
|
|
||||||
val primaryPod: Pod
|
val primaryPod: Pod
|
||||||
get() = when (rawStatus.isBitSet(5)) {
|
get() = when (rawStatus.isBitSet(5)) {
|
||||||
@@ -142,21 +139,4 @@ interface DualAirPods : ApplePods, HasChargeDetectionDual, DualPodDevice, HasEar
|
|||||||
UNKNOWN(0xFF..0xFF);
|
UNKNOWN(0xFF..0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
override val state: ConnectionState
|
|
||||||
get() = ConnectionState.values().firstOrNull { rawSuffix == it.raw } ?: ConnectionState.UNKNOWN
|
|
||||||
|
|
||||||
enum class ConnectionState(val raw: UByte?, @StringRes val labelRes: Int) : HasStateDetection.State {
|
|
||||||
DISCONNECTED(0x00, R.string.pods_connection_state_disconnected_label),
|
|
||||||
IDLE(0x04, R.string.pods_connection_state_idle_label),
|
|
||||||
MUSIC(0x05, R.string.pods_connection_state_music_label),
|
|
||||||
CALL(0x06, R.string.pods_connection_state_call_label),
|
|
||||||
RINGING(0x07, R.string.pods_connection_state_ringing_label),
|
|
||||||
HANGING_UP(0x09, R.string.pods_connection_state_hanging_up_label),
|
|
||||||
UNKNOWN(null, R.string.pods_connection_state_unknown_label);
|
|
||||||
|
|
||||||
override fun getLabel(context: Context): String = context.getString(labelRes)
|
|
||||||
|
|
||||||
constructor(raw: Int, @StringRes labelRes: Int) : this(raw.toUByte(), labelRes)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -4,9 +4,9 @@ import eu.darken.capod.common.debug.logging.Logging.Priority.DEBUG
|
|||||||
import eu.darken.capod.common.debug.logging.log
|
import eu.darken.capod.common.debug.logging.log
|
||||||
import eu.darken.capod.pods.core.PodDevice
|
import eu.darken.capod.pods.core.PodDevice
|
||||||
|
|
||||||
abstract class DualApplePodsFactory(private val tag: String) : ApplePodsFactory<DualAirPods>(tag) {
|
abstract class DualApplePodsFactory(private val tag: String) : ApplePodsFactory<DualApplePods>(tag) {
|
||||||
|
|
||||||
fun DualAirPods.getCaseMatchMarkings() = SplitPodsMarkings(
|
fun DualApplePods.getCaseMatchMarkings() = SplitPodsMarkings(
|
||||||
leftPodBattery = batteryLeftPodPercent,
|
leftPodBattery = batteryLeftPodPercent,
|
||||||
rightPodBattery = batteryRightPodPercent,
|
rightPodBattery = batteryRightPodPercent,
|
||||||
microPhoneLeft = isLeftPodMicrophone,
|
microPhoneLeft = isLeftPodMicrophone,
|
||||||
@@ -31,17 +31,17 @@ abstract class DualApplePodsFactory(private val tag: String) : ApplePodsFactory<
|
|||||||
val model: PodDevice.Model,
|
val model: PodDevice.Model,
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun Collection<KnownDevice>.findSplitPodsMatch(device: DualAirPods): Collection<KnownDevice> {
|
private fun Collection<KnownDevice>.findSplitPodsMatch(device: DualApplePods): Collection<KnownDevice> {
|
||||||
val target = device.getCaseMatchMarkings()
|
val target = device.getCaseMatchMarkings()
|
||||||
|
|
||||||
return filter { known ->
|
return filter { known ->
|
||||||
known.history
|
known.history
|
||||||
.filterIsInstance<DualAirPods>()
|
.filterIsInstance<DualApplePods>()
|
||||||
.any { it.getCaseMatchMarkings() == target }
|
.any { it.getCaseMatchMarkings() == target }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun searchHistory(current: DualAirPods): KnownDevice? {
|
override fun searchHistory(current: DualApplePods): KnownDevice? {
|
||||||
val basicResult = super.searchHistory(current)
|
val basicResult = super.searchHistory(current)
|
||||||
|
|
||||||
val caseIgnored = knownDevices.values.findSplitPodsMatch(current)
|
val caseIgnored = knownDevices.values.findSplitPodsMatch(current)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import eu.darken.capod.common.bluetooth.BleScanResult
|
|||||||
import eu.darken.capod.common.debug.logging.logTag
|
import eu.darken.capod.common.debug.logging.logTag
|
||||||
import eu.darken.capod.pods.core.PodDevice
|
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.DualAirPods
|
import eu.darken.capod.pods.core.apple.DualApplePods
|
||||||
import eu.darken.capod.pods.core.apple.DualApplePodsFactory
|
import eu.darken.capod.pods.core.apple.DualApplePodsFactory
|
||||||
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
@@ -20,15 +20,15 @@ data class AirPodsGen1 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,
|
||||||
private val cachedCaseState: DualAirPods.LidState? = null
|
private val cachedCaseState: DualApplePods.LidState? = null
|
||||||
) : DualAirPods {
|
) : DualApplePods {
|
||||||
|
|
||||||
override val model: PodDevice.Model = PodDevice.Model.AIRPODS_GEN1
|
override val model: PodDevice.Model = PodDevice.Model.AIRPODS_GEN1
|
||||||
|
|
||||||
override val batteryCasePercent: Float?
|
override val batteryCasePercent: Float?
|
||||||
get() = super.batteryCasePercent ?: cachedBatteryPercentage
|
get() = super.batteryCasePercent ?: cachedBatteryPercentage
|
||||||
|
|
||||||
override val caseLidState: DualAirPods.LidState
|
override val caseLidState: DualApplePods.LidState
|
||||||
get() = cachedCaseState ?: super.caseLidState
|
get() = cachedCaseState ?: super.caseLidState
|
||||||
|
|
||||||
override val rssi: Int
|
override val rssi: Int
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import eu.darken.capod.common.bluetooth.BleScanResult
|
|||||||
import eu.darken.capod.common.debug.logging.logTag
|
import eu.darken.capod.common.debug.logging.logTag
|
||||||
import eu.darken.capod.pods.core.PodDevice
|
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.DualAirPods
|
import eu.darken.capod.pods.core.apple.DualApplePods
|
||||||
import eu.darken.capod.pods.core.apple.DualApplePodsFactory
|
import eu.darken.capod.pods.core.apple.DualApplePodsFactory
|
||||||
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
@@ -20,19 +20,19 @@ data class AirPodsGen2 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,
|
||||||
private val cachedCaseState: DualAirPods.LidState? = null
|
private val cachedCaseState: DualApplePods.LidState? = null
|
||||||
) : DualAirPods {
|
) : DualApplePods, HasStateDetectionAirPods {
|
||||||
|
|
||||||
override val model: PodDevice.Model = PodDevice.Model.AIRPODS_GEN2
|
override val model: PodDevice.Model = PodDevice.Model.AIRPODS_GEN2
|
||||||
|
|
||||||
override val batteryCasePercent: Float?
|
override val batteryCasePercent: Float?
|
||||||
get() = super.batteryCasePercent ?: cachedBatteryPercentage
|
get() = super.batteryCasePercent ?: cachedBatteryPercentage
|
||||||
|
|
||||||
override val caseLidState: DualAirPods.LidState
|
override val caseLidState: DualApplePods.LidState
|
||||||
get() = cachedCaseState ?: super.caseLidState
|
get() = cachedCaseState ?: super.caseLidState
|
||||||
|
|
||||||
override val rssi: Int
|
override val rssi: Int
|
||||||
get() = rssiAverage ?: super.rssi
|
get() = rssiAverage ?: super<DualApplePods>.rssi
|
||||||
|
|
||||||
class Factory @Inject constructor() : DualApplePodsFactory(TAG) {
|
class Factory @Inject constructor() : DualApplePodsFactory(TAG) {
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import eu.darken.capod.common.bluetooth.BleScanResult
|
|||||||
import eu.darken.capod.common.debug.logging.logTag
|
import eu.darken.capod.common.debug.logging.logTag
|
||||||
import eu.darken.capod.pods.core.PodDevice
|
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.DualAirPods
|
import eu.darken.capod.pods.core.apple.DualApplePods
|
||||||
import eu.darken.capod.pods.core.apple.DualApplePodsFactory
|
import eu.darken.capod.pods.core.apple.DualApplePodsFactory
|
||||||
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
@@ -20,18 +20,19 @@ data class AirPodsGen3 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,
|
||||||
private val cachedCaseState: DualAirPods.LidState? = null
|
private val cachedCaseState: DualApplePods.LidState? = null
|
||||||
) : DualAirPods {
|
) : DualApplePods, HasStateDetectionAirPods {
|
||||||
|
|
||||||
override val model: PodDevice.Model = PodDevice.Model.AIRPODS_GEN3
|
override val model: PodDevice.Model = PodDevice.Model.AIRPODS_GEN3
|
||||||
|
|
||||||
override val batteryCasePercent: Float?
|
override val batteryCasePercent: Float?
|
||||||
get() = super.batteryCasePercent ?: cachedBatteryPercentage
|
get() = super.batteryCasePercent ?: cachedBatteryPercentage
|
||||||
|
|
||||||
override val caseLidState: DualAirPods.LidState
|
override val caseLidState: DualApplePods.LidState
|
||||||
get() = cachedCaseState ?: super.caseLidState
|
get() = cachedCaseState ?: super.caseLidState
|
||||||
|
|
||||||
override val rssi: Int
|
override val rssi: Int
|
||||||
get() = rssiAverage ?: super.rssi
|
get() = rssiAverage ?: super<DualApplePods>.rssi
|
||||||
|
|
||||||
class Factory @Inject constructor() : DualApplePodsFactory(TAG) {
|
class Factory @Inject constructor() : DualApplePodsFactory(TAG) {
|
||||||
|
|
||||||
|
|||||||
@@ -21,12 +21,12 @@ data class AirPodsMax(
|
|||||||
override val proximityMessage: ProximityPairing.Message,
|
override val proximityMessage: ProximityPairing.Message,
|
||||||
override val confidence: Float = PodDevice.BASE_CONFIDENCE,
|
override val confidence: Float = PodDevice.BASE_CONFIDENCE,
|
||||||
private val rssiAverage: Int? = null,
|
private val rssiAverage: Int? = null,
|
||||||
) : SingleApplePods, HasEarDetection {
|
) : SingleApplePods, HasEarDetection, HasStateDetectionAirPods {
|
||||||
|
|
||||||
override val model: PodDevice.Model = PodDevice.Model.AIRPODS_MAX
|
override val model: PodDevice.Model = PodDevice.Model.AIRPODS_MAX
|
||||||
|
|
||||||
override val rssi: Int
|
override val rssi: Int
|
||||||
get() = rssiAverage ?: super.rssi
|
get() = rssiAverage ?: super<SingleApplePods>.rssi
|
||||||
|
|
||||||
val isHeadphonesBeingWorn: Boolean
|
val isHeadphonesBeingWorn: Boolean
|
||||||
get() = rawStatus.isBitSet(1)
|
get() = rawStatus.isBitSet(1)
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import eu.darken.capod.common.bluetooth.BleScanResult
|
|||||||
import eu.darken.capod.common.debug.logging.logTag
|
import eu.darken.capod.common.debug.logging.logTag
|
||||||
import eu.darken.capod.pods.core.PodDevice
|
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.DualAirPods
|
import eu.darken.capod.pods.core.apple.DualApplePods
|
||||||
import eu.darken.capod.pods.core.apple.DualAirPods.LidState
|
import eu.darken.capod.pods.core.apple.DualApplePods.LidState
|
||||||
import eu.darken.capod.pods.core.apple.DualApplePodsFactory
|
import eu.darken.capod.pods.core.apple.DualApplePodsFactory
|
||||||
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
@@ -24,7 +24,7 @@ data class AirPodsPro(
|
|||||||
private val rssiAverage: Int? = null,
|
private val rssiAverage: Int? = null,
|
||||||
private val cachedBatteryPercentage: Float? = null,
|
private val cachedBatteryPercentage: Float? = null,
|
||||||
private val cachedCaseState: LidState? = null
|
private val cachedCaseState: LidState? = null
|
||||||
) : DualAirPods {
|
) : DualApplePods, HasStateDetectionAirPods {
|
||||||
|
|
||||||
override val model: PodDevice.Model = PodDevice.Model.AIRPODS_PRO
|
override val model: PodDevice.Model = PodDevice.Model.AIRPODS_PRO
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ data class AirPodsPro(
|
|||||||
get() = cachedCaseState ?: super.caseLidState
|
get() = cachedCaseState ?: super.caseLidState
|
||||||
|
|
||||||
override val rssi: Int
|
override val rssi: Int
|
||||||
get() = rssiAverage ?: super.rssi
|
get() = rssiAverage ?: super<DualApplePods>.rssi
|
||||||
|
|
||||||
class Factory @Inject constructor() : DualApplePodsFactory(TAG) {
|
class Factory @Inject constructor() : DualApplePodsFactory(TAG) {
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import eu.darken.capod.common.bluetooth.BleScanResult
|
|||||||
import eu.darken.capod.common.debug.logging.logTag
|
import eu.darken.capod.common.debug.logging.logTag
|
||||||
import eu.darken.capod.pods.core.PodDevice
|
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.DualAirPods
|
import eu.darken.capod.pods.core.apple.DualApplePods
|
||||||
import eu.darken.capod.pods.core.apple.DualAirPods.LidState
|
import eu.darken.capod.pods.core.apple.DualApplePods.LidState
|
||||||
import eu.darken.capod.pods.core.apple.DualApplePodsFactory
|
import eu.darken.capod.pods.core.apple.DualApplePodsFactory
|
||||||
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
@@ -24,7 +24,7 @@ data class AirPodsPro2(
|
|||||||
private val rssiAverage: Int? = null,
|
private val rssiAverage: Int? = null,
|
||||||
private val cachedBatteryPercentage: Float? = null,
|
private val cachedBatteryPercentage: Float? = null,
|
||||||
private val cachedCaseState: LidState? = null
|
private val cachedCaseState: LidState? = null
|
||||||
) : DualAirPods {
|
) : DualApplePods, HasStateDetectionAirPods {
|
||||||
|
|
||||||
override val model: PodDevice.Model = PodDevice.Model.AIRPODS_PRO2
|
override val model: PodDevice.Model = PodDevice.Model.AIRPODS_PRO2
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ data class AirPodsPro2(
|
|||||||
get() = cachedCaseState ?: super.caseLidState
|
get() = cachedCaseState ?: super.caseLidState
|
||||||
|
|
||||||
override val rssi: Int
|
override val rssi: Int
|
||||||
get() = rssiAverage ?: super.rssi
|
get() = rssiAverage ?: super<HasStateDetectionAirPods>.rssi
|
||||||
|
|
||||||
class Factory @Inject constructor() : DualApplePodsFactory(TAG) {
|
class Factory @Inject constructor() : DualApplePodsFactory(TAG) {
|
||||||
|
|
||||||
|
|||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
package eu.darken.capod.pods.core.apple.airpods
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.annotation.StringRes
|
||||||
|
import eu.darken.capod.common.R
|
||||||
|
import eu.darken.capod.pods.core.HasStateDetection
|
||||||
|
import eu.darken.capod.pods.core.apple.ApplePods
|
||||||
|
|
||||||
|
interface HasStateDetectionAirPods : HasStateDetection, ApplePods {
|
||||||
|
|
||||||
|
override val state: ConnectionState
|
||||||
|
get() = ConnectionState.values().firstOrNull { rawSuffix == it.raw } ?: ConnectionState.UNKNOWN
|
||||||
|
|
||||||
|
enum class ConnectionState(val raw: UByte?, @StringRes val labelRes: Int) : HasStateDetection.State {
|
||||||
|
DISCONNECTED(0x00, R.string.pods_connection_state_disconnected_label),
|
||||||
|
IDLE(0x04, R.string.pods_connection_state_idle_label),
|
||||||
|
MUSIC(0x05, R.string.pods_connection_state_music_label),
|
||||||
|
CALL(0x06, R.string.pods_connection_state_call_label),
|
||||||
|
RINGING(0x07, R.string.pods_connection_state_ringing_label),
|
||||||
|
HANGING_UP(0x09, R.string.pods_connection_state_hanging_up_label),
|
||||||
|
UNKNOWN(null, R.string.pods_connection_state_unknown_label);
|
||||||
|
|
||||||
|
override fun getLabel(context: Context): String = context.getString(labelRes)
|
||||||
|
|
||||||
|
constructor(raw: Int, @StringRes labelRes: Int) : this(raw.toUByte(), labelRes)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@ import eu.darken.capod.common.bluetooth.BleScanResult
|
|||||||
import eu.darken.capod.common.debug.logging.logTag
|
import eu.darken.capod.common.debug.logging.logTag
|
||||||
import eu.darken.capod.pods.core.PodDevice
|
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.DualAirPods
|
import eu.darken.capod.pods.core.apple.DualApplePods
|
||||||
import eu.darken.capod.pods.core.apple.DualApplePodsFactory
|
import eu.darken.capod.pods.core.apple.DualApplePodsFactory
|
||||||
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
@@ -20,15 +20,15 @@ data class BeatsFitPro(
|
|||||||
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,
|
||||||
private val cachedCaseState: DualAirPods.LidState? = null
|
private val cachedCaseState: DualApplePods.LidState? = null
|
||||||
) : DualAirPods {
|
) : DualApplePods {
|
||||||
|
|
||||||
override val model: PodDevice.Model = PodDevice.Model.BEATS_FIT_PRO
|
override val model: PodDevice.Model = PodDevice.Model.BEATS_FIT_PRO
|
||||||
|
|
||||||
override val batteryCasePercent: Float?
|
override val batteryCasePercent: Float?
|
||||||
get() = super.batteryCasePercent ?: cachedBatteryPercentage
|
get() = super.batteryCasePercent ?: cachedBatteryPercentage
|
||||||
|
|
||||||
override val caseLidState: DualAirPods.LidState
|
override val caseLidState: DualApplePods.LidState
|
||||||
get() = cachedCaseState ?: super.caseLidState
|
get() = cachedCaseState ?: super.caseLidState
|
||||||
|
|
||||||
override val rssi: Int
|
override val rssi: Int
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import eu.darken.capod.common.bluetooth.BleScanResult
|
|||||||
import eu.darken.capod.common.debug.logging.logTag
|
import eu.darken.capod.common.debug.logging.logTag
|
||||||
import eu.darken.capod.pods.core.PodDevice
|
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.DualAirPods
|
import eu.darken.capod.pods.core.apple.DualApplePods
|
||||||
import eu.darken.capod.pods.core.apple.DualApplePodsFactory
|
import eu.darken.capod.pods.core.apple.DualApplePodsFactory
|
||||||
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
@@ -20,15 +20,15 @@ data class PowerBeatsPro(
|
|||||||
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,
|
||||||
private val cachedCaseState: DualAirPods.LidState? = null
|
private val cachedCaseState: DualApplePods.LidState? = null
|
||||||
) : DualAirPods {
|
) : DualApplePods {
|
||||||
|
|
||||||
override val model: PodDevice.Model = PodDevice.Model.POWERBEATS_PRO
|
override val model: PodDevice.Model = PodDevice.Model.POWERBEATS_PRO
|
||||||
|
|
||||||
override val batteryCasePercent: Float?
|
override val batteryCasePercent: Float?
|
||||||
get() = super.batteryCasePercent ?: cachedBatteryPercentage
|
get() = super.batteryCasePercent ?: cachedBatteryPercentage
|
||||||
|
|
||||||
override val caseLidState: DualAirPods.LidState
|
override val caseLidState: DualApplePods.LidState
|
||||||
get() = cachedCaseState ?: super.caseLidState
|
get() = cachedCaseState ?: super.caseLidState
|
||||||
|
|
||||||
override val rssi: Int
|
override val rssi: Int
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import eu.darken.capod.common.upperNibble
|
|||||||
import eu.darken.capod.pods.core.*
|
import eu.darken.capod.pods.core.*
|
||||||
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.DualAirPods
|
import eu.darken.capod.pods.core.apple.DualApplePods
|
||||||
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -30,7 +30,7 @@ data class FakeAirPodsPro2 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,
|
||||||
private val cachedCaseState: DualAirPods.LidState? = null,
|
private val cachedCaseState: DualApplePods.LidState? = null,
|
||||||
) : ApplePods, HasChargeDetectionDual, DualPodDevice, HasEarDetectionDual, HasCase {
|
) : ApplePods, HasChargeDetectionDual, DualPodDevice, HasEarDetectionDual, HasCase {
|
||||||
|
|
||||||
override val model: PodDevice.Model = PodDevice.Model.FAKE_AIRPODS_PRO2
|
override val model: PodDevice.Model = PodDevice.Model.FAKE_AIRPODS_PRO2
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import eu.darken.capod.main.core.GeneralSettings
|
|||||||
import eu.darken.capod.monitor.core.PodMonitor
|
import eu.darken.capod.monitor.core.PodMonitor
|
||||||
import eu.darken.capod.pods.core.HasEarDetection
|
import eu.darken.capod.pods.core.HasEarDetection
|
||||||
import eu.darken.capod.pods.core.HasEarDetectionDual
|
import eu.darken.capod.pods.core.HasEarDetectionDual
|
||||||
import eu.darken.capod.pods.core.apple.DualAirPods
|
import eu.darken.capod.pods.core.apple.DualApplePods
|
||||||
import eu.darken.capod.reaction.core.ReactionSettings
|
import eu.darken.capod.reaction.core.ReactionSettings
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -69,7 +69,7 @@ class AutoConnect @Inject constructor(
|
|||||||
val conditionFulfilled = when (condition) {
|
val conditionFulfilled = when (condition) {
|
||||||
AutoConnectCondition.WHEN_SEEN -> true
|
AutoConnectCondition.WHEN_SEEN -> true
|
||||||
AutoConnectCondition.CASE_OPEN -> when (mainDevice) {
|
AutoConnectCondition.CASE_OPEN -> when (mainDevice) {
|
||||||
is DualAirPods -> mainDevice.caseLidState == DualAirPods.LidState.OPEN
|
is DualApplePods -> mainDevice.caseLidState == DualApplePods.LidState.OPEN
|
||||||
else -> true
|
else -> true
|
||||||
}
|
}
|
||||||
AutoConnectCondition.IN_EAR -> when (mainDevice) {
|
AutoConnectCondition.IN_EAR -> when (mainDevice) {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import eu.darken.capod.common.flow.setupCommonEventHandlers
|
|||||||
import eu.darken.capod.common.flow.withPrevious
|
import eu.darken.capod.common.flow.withPrevious
|
||||||
import eu.darken.capod.monitor.core.PodMonitor
|
import eu.darken.capod.monitor.core.PodMonitor
|
||||||
import eu.darken.capod.pods.core.PodDevice
|
import eu.darken.capod.pods.core.PodDevice
|
||||||
import eu.darken.capod.pods.core.apple.DualAirPods
|
import eu.darken.capod.pods.core.apple.DualApplePods
|
||||||
import eu.darken.capod.reaction.core.ReactionSettings
|
import eu.darken.capod.reaction.core.ReactionSettings
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
@@ -34,7 +34,7 @@ class PopUpReaction @Inject constructor(
|
|||||||
.withPrevious()
|
.withPrevious()
|
||||||
.setupCommonEventHandlers(TAG) { "monitor" }
|
.setupCommonEventHandlers(TAG) { "monitor" }
|
||||||
.mapNotNull { (previous, current) ->
|
.mapNotNull { (previous, current) ->
|
||||||
if (previous !is DualAirPods? || current !is DualAirPods) {
|
if (previous !is DualApplePods? || current !is DualApplePods) {
|
||||||
return@mapNotNull null
|
return@mapNotNull null
|
||||||
}
|
}
|
||||||
log(TAG, VERBOSE) {
|
log(TAG, VERBOSE) {
|
||||||
@@ -57,8 +57,8 @@ class PopUpReaction @Inject constructor(
|
|||||||
tryPopWindow(current)
|
tryPopWindow(current)
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun tryPopWindow(current: DualAirPods): Event? = when {
|
private suspend fun tryPopWindow(current: DualApplePods): Event? = when {
|
||||||
current.caseLidState == DualAirPods.LidState.OPEN -> {
|
current.caseLidState == DualApplePods.LidState.OPEN -> {
|
||||||
log(TAG, INFO) { "Show popup" }
|
log(TAG, INFO) { "Show popup" }
|
||||||
|
|
||||||
val now = Instant.now()
|
val now = Instant.now()
|
||||||
@@ -74,9 +74,9 @@ class PopUpReaction @Inject constructor(
|
|||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
current.caseLidState != DualAirPods.LidState.OPEN -> {
|
current.caseLidState != DualApplePods.LidState.OPEN -> {
|
||||||
when (current.caseLidState) {
|
when (current.caseLidState) {
|
||||||
DualAirPods.LidState.CLOSED -> {
|
DualApplePods.LidState.CLOSED -> {
|
||||||
log(TAG, INFO) { "Lid was actively closed, resetting cooldown." }
|
log(TAG, INFO) { "Lid was actively closed, resetting cooldown." }
|
||||||
coolDowns.remove(current.identifier)
|
coolDowns.remove(current.identifier)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,14 +14,14 @@ class AirPodsFactoryTest : BaseAirPodsTest() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `create AirPodsGen1`() = runTest {
|
fun `create AirPodsGen1`() = runTest {
|
||||||
create<DualAirPods>("07 19 01 02 20 55 AA 56 31 00 00 6F E4 DF 10 AF 10 60 81 03 3B 76 D9 C7 11 22 88") {
|
create<DualApplePods>("07 19 01 02 20 55 AA 56 31 00 00 6F E4 DF 10 AF 10 60 81 03 3B 76 D9 C7 11 22 88") {
|
||||||
this shouldBe instanceOf<AirPodsGen1>()
|
this shouldBe instanceOf<AirPodsGen1>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `create AirPodsPro`() = runTest {
|
fun `create AirPodsPro`() = runTest {
|
||||||
create<DualAirPods>("07 19 01 0E 20 2B 99 8F 01 00 >09< 10 30 EE F3 41 B5 D8 9F A3 B0 B4 17 9F 85 97 5F") {
|
create<DualApplePods>("07 19 01 0E 20 2B 99 8F 01 00 >09< 10 30 EE F3 41 B5 D8 9F A3 B0 B4 17 9F 85 97 5F") {
|
||||||
this shouldBe instanceOf<AirPodsPro>()
|
this shouldBe instanceOf<AirPodsPro>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package eu.darken.capod.pods.core.apple
|
package eu.darken.capod.pods.core.apple
|
||||||
|
|
||||||
|
import eu.darken.capod.pods.core.apple.airpods.HasStateDetectionAirPods
|
||||||
import io.kotest.matchers.shouldBe
|
import io.kotest.matchers.shouldBe
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
@@ -8,7 +9,7 @@ class DualApplePodsTest : BaseAirPodsTest() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test bit mapping`() = runTest {
|
fun `test bit mapping`() = runTest {
|
||||||
create<DualAirPods>("07 19 01 0E 20 54 AA B5 31 00 00 E0 0C A7 8A 60 4B D3 7D F4 60 4F 2C 73 E9 A7 F4") {
|
create<DualApplePods>("07 19 01 0E 20 54 AA B5 31 00 00 E0 0C A7 8A 60 4B D3 7D F4 60 4F 2C 73 E9 A7 F4") {
|
||||||
|
|
||||||
rawPrefix shouldBe 0x01.toUByte()
|
rawPrefix shouldBe 0x01.toUByte()
|
||||||
rawDeviceModel shouldBe 0x0e20.toUShort()
|
rawDeviceModel shouldBe 0x0e20.toUShort()
|
||||||
@@ -24,13 +25,13 @@ class DualApplePodsTest : BaseAirPodsTest() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test AirPodDevice - active microphone`() = runTest {
|
fun `test AirPodDevice - active microphone`() = runTest {
|
||||||
create<DualAirPods>("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") {
|
create<DualApplePods>("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
|
// 00101011
|
||||||
// --^-----
|
// --^-----
|
||||||
isLeftPodMicrophone shouldBe true
|
isLeftPodMicrophone shouldBe true
|
||||||
isRightPodMicrophone shouldBe false
|
isRightPodMicrophone shouldBe false
|
||||||
}
|
}
|
||||||
create<DualAirPods>("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") {
|
create<DualApplePods>("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
|
// 00001011
|
||||||
// --^-----
|
// --^-----
|
||||||
isLeftPodMicrophone shouldBe false
|
isLeftPodMicrophone shouldBe false
|
||||||
@@ -41,24 +42,24 @@ class DualApplePodsTest : BaseAirPodsTest() {
|
|||||||
@Test
|
@Test
|
||||||
fun `test AirPodDevice - left pod ear status`() = runTest {
|
fun `test AirPodDevice - left pod ear status`() = runTest {
|
||||||
// Left Pod primary
|
// Left Pod primary
|
||||||
create<DualAirPods>("07 19 01 0E 20 >22< AA B5 31 00 00 E0 0C A7 8A 60 4B D3 7D F4 60 4F 2C 73 E9 A7 F4") {
|
create<DualApplePods>("07 19 01 0E 20 >22< AA B5 31 00 00 E0 0C A7 8A 60 4B D3 7D F4 60 4F 2C 73 E9 A7 F4") {
|
||||||
// 00100010
|
// 00100010
|
||||||
// 765432¹0
|
// 765432¹0
|
||||||
isLeftPodInEar shouldBe true
|
isLeftPodInEar shouldBe true
|
||||||
}
|
}
|
||||||
create<DualAirPods>("07 19 01 0E 20 >20< AA B5 31 00 00 E0 0C A7 8A 60 4B D3 7D F4 60 4F 2C 73 E9 A7 F4") {
|
create<DualApplePods>("07 19 01 0E 20 >20< AA B5 31 00 00 E0 0C A7 8A 60 4B D3 7D F4 60 4F 2C 73 E9 A7 F4") {
|
||||||
// 00100000
|
// 00100000
|
||||||
// 765432¹0
|
// 765432¹0
|
||||||
isLeftPodInEar shouldBe false
|
isLeftPodInEar shouldBe false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Right Pod is primary
|
// Right Pod is primary
|
||||||
create<DualAirPods>("07 19 01 0E 20 >09< AA B5 31 00 00 E0 0C A7 8A 60 4B D3 7D F4 60 4F 2C 73 E9 A7 F4") {
|
create<DualApplePods>("07 19 01 0E 20 >09< AA B5 31 00 00 E0 0C A7 8A 60 4B D3 7D F4 60 4F 2C 73 E9 A7 F4") {
|
||||||
// 00001001
|
// 00001001
|
||||||
// 7654³210
|
// 7654³210
|
||||||
isLeftPodInEar shouldBe true
|
isLeftPodInEar shouldBe true
|
||||||
}
|
}
|
||||||
create<DualAirPods>("07 19 01 0E 20 >20< AA B5 31 00 00 E0 0C A7 8A 60 4B D3 7D F4 60 4F 2C 73 E9 A7 F4") {
|
create<DualApplePods>("07 19 01 0E 20 >20< AA B5 31 00 00 E0 0C A7 8A 60 4B D3 7D F4 60 4F 2C 73 E9 A7 F4") {
|
||||||
// 00000001
|
// 00000001
|
||||||
// 7654³210
|
// 7654³210
|
||||||
isLeftPodInEar shouldBe false
|
isLeftPodInEar shouldBe false
|
||||||
@@ -68,24 +69,24 @@ class DualApplePodsTest : BaseAirPodsTest() {
|
|||||||
@Test
|
@Test
|
||||||
fun `test AirPodDevice - right pod ear status`() = runTest {
|
fun `test AirPodDevice - right pod ear status`() = runTest {
|
||||||
// Left Pod primary
|
// Left Pod primary
|
||||||
create<DualAirPods>("07 19 01 0E 20 >29< AA B5 31 00 00 E0 0C A7 8A 60 4B D3 7D F4 60 4F 2C 73 E9 A7 F4") {
|
create<DualApplePods>("07 19 01 0E 20 >29< AA B5 31 00 00 E0 0C A7 8A 60 4B D3 7D F4 60 4F 2C 73 E9 A7 F4") {
|
||||||
// 00101001
|
// 00101001
|
||||||
// 7654³210
|
// 7654³210
|
||||||
isRightPodInEar shouldBe true
|
isRightPodInEar shouldBe true
|
||||||
}
|
}
|
||||||
create<DualAirPods>("07 19 01 0E 20 >21< AA B5 31 00 00 E0 0C A7 8A 60 4B D3 7D F4 60 4F 2C 73 E9 A7 F4") {
|
create<DualApplePods>("07 19 01 0E 20 >21< AA B5 31 00 00 E0 0C A7 8A 60 4B D3 7D F4 60 4F 2C 73 E9 A7 F4") {
|
||||||
// 00100001
|
// 00100001
|
||||||
// 7654³210
|
// 7654³210
|
||||||
isRightPodInEar shouldBe false
|
isRightPodInEar shouldBe false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Right Pod is primary
|
// Right Pod is primary
|
||||||
create<DualAirPods>("07 19 01 0E 20 >03< AA B5 31 00 00 E0 0C A7 8A 60 4B D3 7D F4 60 4F 2C 73 E9 A7 F4") {
|
create<DualApplePods>("07 19 01 0E 20 >03< AA B5 31 00 00 E0 0C A7 8A 60 4B D3 7D F4 60 4F 2C 73 E9 A7 F4") {
|
||||||
// 00000011
|
// 00000011
|
||||||
// 765432¹0
|
// 765432¹0
|
||||||
isRightPodInEar shouldBe true
|
isRightPodInEar shouldBe true
|
||||||
}
|
}
|
||||||
create<DualAirPods>("07 19 01 0E 20 >01< AA B5 31 00 00 E0 0C A7 8A 60 4B D3 7D F4 60 4F 2C 73 E9 A7 F4") {
|
create<DualApplePods>("07 19 01 0E 20 >01< AA B5 31 00 00 E0 0C A7 8A 60 4B D3 7D F4 60 4F 2C 73 E9 A7 F4") {
|
||||||
// 00000001
|
// 00000001
|
||||||
// 765432¹0
|
// 765432¹0
|
||||||
isRightPodInEar shouldBe false
|
isRightPodInEar shouldBe false
|
||||||
@@ -95,13 +96,13 @@ class DualApplePodsTest : BaseAirPodsTest() {
|
|||||||
@Test
|
@Test
|
||||||
fun `test AirPodDevice - battery status`() = runTest {
|
fun `test AirPodDevice - battery status`() = runTest {
|
||||||
// Right Pod is primary
|
// Right Pod is primary
|
||||||
create<DualAirPods>("07 19 01 0E 20 0B >98< 94 52 00 05 09 73 3C 3D F9 2C 3E B3 DD 76 02 DD 4E 16 FD FB") {
|
create<DualApplePods>("07 19 01 0E 20 0B >98< 94 52 00 05 09 73 3C 3D F9 2C 3E B3 DD 76 02 DD 4E 16 FD FB") {
|
||||||
// 88 10001000
|
// 88 10001000
|
||||||
batteryLeftPodPercent shouldBe 0.9f
|
batteryLeftPodPercent shouldBe 0.9f
|
||||||
batteryRightPodPercent shouldBe 0.8f
|
batteryRightPodPercent shouldBe 0.8f
|
||||||
}
|
}
|
||||||
// Left Pod primary
|
// Left Pod primary
|
||||||
create<DualAirPods>("07 19 01 0E 20 2B >89< 94 52 00 05 09 73 3C 3D F9 2C 3E B3 DD 76 02 DD 4E 16 FD FB") {
|
create<DualApplePods>("07 19 01 0E 20 2B >89< 94 52 00 05 09 73 3C 3D F9 2C 3E B3 DD 76 02 DD 4E 16 FD FB") {
|
||||||
// F8 11111000
|
// F8 11111000
|
||||||
batteryLeftPodPercent shouldBe 0.9f
|
batteryLeftPodPercent shouldBe 0.9f
|
||||||
batteryRightPodPercent shouldBe 0.8f
|
batteryRightPodPercent shouldBe 0.8f
|
||||||
@@ -114,13 +115,13 @@ class DualApplePodsTest : BaseAirPodsTest() {
|
|||||||
* Right pod is charging
|
* Right pod is charging
|
||||||
*/
|
*/
|
||||||
// This is the left
|
// This is the left
|
||||||
create<DualAirPods>("07 19 01 0E 20 51 89 >94< 52 00 00 F4 89 82 6D 3E 27 7F 26 62 57 D0 E2 A6 49 E9 35") {
|
create<DualApplePods>("07 19 01 0E 20 51 89 >94< 52 00 00 F4 89 82 6D 3E 27 7F 26 62 57 D0 E2 A6 49 E9 35") {
|
||||||
// 1001 0100
|
// 1001 0100
|
||||||
isLeftPodCharging shouldBe false
|
isLeftPodCharging shouldBe false
|
||||||
isRightPodCharging shouldBe true
|
isRightPodCharging shouldBe true
|
||||||
}
|
}
|
||||||
// This is the right
|
// This is the right
|
||||||
create<DualAirPods>("07 19 01 0E 20 31 98 >A4< 01 00 00 31 B9 A0 C4 80 CD D1 CF B9 3A 9A 6D 48 31 08 EB") {
|
create<DualApplePods>("07 19 01 0E 20 31 98 >A4< 01 00 00 31 B9 A0 C4 80 CD D1 CF B9 3A 9A 6D 48 31 08 EB") {
|
||||||
// 1010 0100
|
// 1010 0100
|
||||||
isLeftPodCharging shouldBe false
|
isLeftPodCharging shouldBe false
|
||||||
isRightPodCharging shouldBe true
|
isRightPodCharging shouldBe true
|
||||||
@@ -130,26 +131,26 @@ class DualApplePodsTest : BaseAirPodsTest() {
|
|||||||
* Left pod is charging
|
* Left pod is charging
|
||||||
*/
|
*/
|
||||||
// This is the left
|
// This is the left
|
||||||
create<DualAirPods>("07 19 01 0E 20 71 98 >94< 52 00 05 A5 37 31 B2 BD 42 68 0C 64 FD 00 99 4A E5 3E F4") {
|
create<DualApplePods>("07 19 01 0E 20 71 98 >94< 52 00 05 A5 37 31 B2 BD 42 68 0C 64 FD 00 99 4A E5 3E F4") {
|
||||||
// 1001 0100
|
// 1001 0100
|
||||||
isLeftPodCharging shouldBe true
|
isLeftPodCharging shouldBe true
|
||||||
isRightPodCharging shouldBe false
|
isRightPodCharging shouldBe false
|
||||||
}
|
}
|
||||||
// This is the right
|
// This is the right
|
||||||
create<DualAirPods>("07 19 01 0E 20 11 89 >A4< 04 00 04 BA 79 1B C0 65 69 C6 9F 19 6E 37 7D 6D 86 8D D9") {
|
create<DualApplePods>("07 19 01 0E 20 11 89 >A4< 04 00 04 BA 79 1B C0 65 69 C6 9F 19 6E 37 7D 6D 86 8D D9") {
|
||||||
// 1010 0100
|
// 1010 0100
|
||||||
isLeftPodCharging shouldBe true
|
isLeftPodCharging shouldBe true
|
||||||
isRightPodCharging shouldBe false
|
isRightPodCharging shouldBe false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Both charging
|
// Both charging
|
||||||
create<DualAirPods>("07 19 01 0E 20 55 88 >B4< 59 00 05 4B FC DF 68 28 A5 45 52 65 9C FE 51 86 3A B5 DB") {
|
create<DualApplePods>("07 19 01 0E 20 55 88 >B4< 59 00 05 4B FC DF 68 28 A5 45 52 65 9C FE 51 86 3A B5 DB") {
|
||||||
// 1011 0100
|
// 1011 0100
|
||||||
isLeftPodCharging shouldBe true
|
isLeftPodCharging shouldBe true
|
||||||
isRightPodCharging shouldBe true
|
isRightPodCharging shouldBe true
|
||||||
}
|
}
|
||||||
// Both not charging
|
// Both not charging
|
||||||
create<DualAirPods>("07 19 01 0E 20 00 F8 >8F< 03 00 05 4C 0F A0 C4 05 24 DD EB AF 92 99 FD 54 B1 06 48") {
|
create<DualApplePods>("07 19 01 0E 20 00 F8 >8F< 03 00 05 4C 0F A0 C4 05 24 DD EB AF 92 99 FD 54 B1 06 48") {
|
||||||
// 1000 1111
|
// 1000 1111
|
||||||
isLeftPodCharging shouldBe false
|
isLeftPodCharging shouldBe false
|
||||||
isRightPodCharging shouldBe false
|
isRightPodCharging shouldBe false
|
||||||
@@ -158,11 +159,11 @@ class DualApplePodsTest : BaseAirPodsTest() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test AirPodDevice - case charging`() = runTest {
|
fun `test AirPodDevice - case charging`() = runTest {
|
||||||
create<DualAirPods>("07 19 01 0E 20 75 99 >B4< 31 00 05 77 C8 BA 0C 4E 1F BE AD 70 C5 40 71 D2 E9 17 A2") {
|
create<DualApplePods>("07 19 01 0E 20 75 99 >B4< 31 00 05 77 C8 BA 0C 4E 1F BE AD 70 C5 40 71 D2 E9 17 A2") {
|
||||||
// 0011 0011
|
// 0011 0011
|
||||||
isCaseCharging shouldBe false
|
isCaseCharging shouldBe false
|
||||||
}
|
}
|
||||||
create<DualAirPods>("07 19 01 0E 20 75 A9 >F4< 51 00 05 A0 37 92 35 49 79 CC DC 27 94 8E FB 72 12 94 52") {
|
create<DualApplePods>("07 19 01 0E 20 75 A9 >F4< 51 00 05 A0 37 92 35 49 79 CC DC 27 94 8E FB 72 12 94 52") {
|
||||||
// 0101 0011
|
// 0101 0011
|
||||||
isCaseCharging shouldBe true
|
isCaseCharging shouldBe true
|
||||||
}
|
}
|
||||||
@@ -171,75 +172,75 @@ class DualApplePodsTest : BaseAirPodsTest() {
|
|||||||
@Test
|
@Test
|
||||||
fun `test AirPodDevice - case lid test`() = runTest {
|
fun `test AirPodDevice - case lid test`() = runTest {
|
||||||
// Lid open
|
// Lid open
|
||||||
create<DualAirPods>("07 19 01 0E 20 55 AA B4 >31< 00 00 A1 D0 BD 82 D3 52 86 CA FC 11 62 DC 42 C6 92 8E") {
|
create<DualApplePods>("07 19 01 0E 20 55 AA B4 >31< 00 00 A1 D0 BD 82 D3 52 86 CA FC 11 62 DC 42 C6 92 8E") {
|
||||||
// 31 0011 0001
|
// 31 0011 0001
|
||||||
caseLidState shouldBe DualAirPods.LidState.OPEN
|
caseLidState shouldBe DualApplePods.LidState.OPEN
|
||||||
}
|
}
|
||||||
// Lid open, left pod in case
|
// Lid open, left pod in case
|
||||||
create<DualAirPods>("07 19 01 0E 20 51 9A 93 >31< 00 00 95 D0 A5 D7 E3 F4 F1 38 38 99 61 3B 57 95 37 B7") {
|
create<DualApplePods>("07 19 01 0E 20 51 9A 93 >31< 00 00 95 D0 A5 D7 E3 F4 F1 38 38 99 61 3B 57 95 37 B7") {
|
||||||
// 31 0011 0001
|
// 31 0011 0001
|
||||||
caseLidState shouldBe DualAirPods.LidState.OPEN
|
caseLidState shouldBe DualApplePods.LidState.OPEN
|
||||||
}
|
}
|
||||||
// Lid open, left pod in case
|
// Lid open, left pod in case
|
||||||
create<DualAirPods>("07 19 01 0E 20 71 A9 92 31 00 00 DB 48 7F 32 8C CE 80 6F D9 27 98 D6 76 45 9D 62") {
|
create<DualApplePods>("07 19 01 0E 20 71 A9 92 31 00 00 DB 48 7F 32 8C CE 80 6F D9 27 98 D6 76 45 9D 62") {
|
||||||
// 31 0011 0001
|
// 31 0011 0001
|
||||||
caseLidState shouldBe DualAirPods.LidState.OPEN
|
caseLidState shouldBe DualApplePods.LidState.OPEN
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Lid just closed
|
// Lid just closed
|
||||||
create<DualAirPods>("07 19 01 0E 20 55 AA B4 >39< 00 00 08 A6 DB 99 E0 5E 14 85 E5 C2 0B 68 D7 FF C3 A1") {
|
create<DualApplePods>("07 19 01 0E 20 55 AA B4 >39< 00 00 08 A6 DB 99 E0 5E 14 85 E5 C2 0B 68 D7 FF C3 A1") {
|
||||||
// 39 0011 1001
|
// 39 0011 1001
|
||||||
caseLidState shouldBe DualAirPods.LidState.CLOSED
|
caseLidState shouldBe DualApplePods.LidState.CLOSED
|
||||||
}
|
}
|
||||||
// Lid closed
|
// Lid closed
|
||||||
create<DualAirPods>("07 19 01 0E 20 55 AA B4 38 00 00 F3 F7 08 3B 98 09 C0 DD E4 BD BD 84 55 56 8B 81") {
|
create<DualApplePods>("07 19 01 0E 20 55 AA B4 38 00 00 F3 F7 08 3B 98 09 C0 DD E4 BD BD 84 55 56 8B 81") {
|
||||||
// 38 0011 1000
|
// 38 0011 1000
|
||||||
caseLidState shouldBe DualAirPods.LidState.CLOSED
|
caseLidState shouldBe DualApplePods.LidState.CLOSED
|
||||||
}
|
}
|
||||||
// Lid closed, right pod in case
|
// Lid closed, right pod in case
|
||||||
create<DualAirPods>("07 19 01 0E 20 51 9A 93 >38< 00 00 3A D8 85 76 B0 91 48 31 DA FF 6C 4A 2B C2 67 F4") {
|
create<DualApplePods>("07 19 01 0E 20 51 9A 93 >38< 00 00 3A D8 85 76 B0 91 48 31 DA FF 6C 4A 2B C2 67 F4") {
|
||||||
// 38 0011 1000
|
// 38 0011 1000
|
||||||
caseLidState shouldBe DualAirPods.LidState.CLOSED
|
caseLidState shouldBe DualApplePods.LidState.CLOSED
|
||||||
}
|
}
|
||||||
// Lid closed, left pod in case
|
// Lid closed, left pod in case
|
||||||
create<DualAirPods>("07 19 01 0E 20 71 A9 92 38 00 00 44 91 C4 8B 85 98 DD 55 4E 6A CA BC B5 CA 8D 37") {
|
create<DualApplePods>("07 19 01 0E 20 71 A9 92 38 00 00 44 91 C4 8B 85 98 DD 55 4E 6A CA BC B5 CA 8D 37") {
|
||||||
// 38 0011 1000
|
// 38 0011 1000
|
||||||
caseLidState shouldBe DualAirPods.LidState.CLOSED
|
caseLidState shouldBe DualApplePods.LidState.CLOSED
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test AirPodDevice - connection state`() = runTest {
|
fun `test AirPodDevice - connection state`() = runTest {
|
||||||
// Disconnected
|
// Disconnected
|
||||||
create<DualAirPods>("07 19 01 0E 20 2B AA 8F 01 00 >00< 62 D4 BB F1 A7 F8 64 98 D2 C8 BD 7B 3A EF 2E 15") {
|
create<HasStateDetectionAirPods>("07 19 01 0E 20 2B AA 8F 01 00 >00< 62 D4 BB F1 A7 F8 64 98 D2 C8 BD 7B 3A EF 2E 15") {
|
||||||
// 31 0011 0001
|
// 31 0011 0001
|
||||||
state shouldBe DualAirPods.ConnectionState.DISCONNECTED
|
state shouldBe HasStateDetectionAirPods.ConnectionState.DISCONNECTED
|
||||||
}
|
}
|
||||||
// Connected idle
|
// Connected idle
|
||||||
create<DualAirPods>("07 19 01 0E 20 2B AA 8F 01 00 >04< 1D 69 69 9C C2 51 F3 1F BF 6E 45 DA 90 4A A3 E3") {
|
create<HasStateDetectionAirPods>("07 19 01 0E 20 2B AA 8F 01 00 >04< 1D 69 69 9C C2 51 F3 1F BF 6E 45 DA 90 4A A3 E3") {
|
||||||
// 39 0011 1001
|
// 39 0011 1001
|
||||||
state shouldBe DualAirPods.ConnectionState.IDLE
|
state shouldBe HasStateDetectionAirPods.ConnectionState.IDLE
|
||||||
}
|
}
|
||||||
// Connected and playing music
|
// Connected and playing music
|
||||||
create<DualAirPods>("07 19 01 0E 20 2B A9 8F 01 00 >05< 14 F7 CB 49 9F D3 B3 22 77 D2 22 F1 74 8C AC A6") {
|
create<HasStateDetectionAirPods>("07 19 01 0E 20 2B A9 8F 01 00 >05< 14 F7 CB 49 9F D3 B3 22 77 D2 22 F1 74 8C AC A6") {
|
||||||
// 38 0011 1000
|
// 38 0011 1000
|
||||||
state shouldBe DualAirPods.ConnectionState.MUSIC
|
state shouldBe HasStateDetectionAirPods.ConnectionState.MUSIC
|
||||||
}
|
}
|
||||||
// Connected and call active
|
// Connected and call active
|
||||||
create<DualAirPods>("07 19 01 0E 20 2B 99 8F 01 00 >06< 0F 4B 43 25 E0 4A 73 63 14 22 C2 3C 89 13 BD 97") {
|
create<HasStateDetectionAirPods>("07 19 01 0E 20 2B 99 8F 01 00 >06< 0F 4B 43 25 E0 4A 73 63 14 22 C2 3C 89 13 BD 97") {
|
||||||
// 38 0011 1000
|
// 38 0011 1000
|
||||||
state shouldBe DualAirPods.ConnectionState.CALL
|
state shouldBe HasStateDetectionAirPods.ConnectionState.CALL
|
||||||
}
|
}
|
||||||
// Connected and call active
|
// Connected and call active
|
||||||
create<DualAirPods>("07 19 01 0E 20 2B 99 8F 01 00 >07< E7 DF 76 44 85 B5 30 F4 95 14 02 DC A1 A4 8A 09") {
|
create<HasStateDetectionAirPods>("07 19 01 0E 20 2B 99 8F 01 00 >07< E7 DF 76 44 85 B5 30 F4 95 14 02 DC A1 A4 8A 09") {
|
||||||
// 38 0011 1000
|
// 38 0011 1000
|
||||||
state shouldBe DualAirPods.ConnectionState.RINGING
|
state shouldBe HasStateDetectionAirPods.ConnectionState.RINGING
|
||||||
}
|
}
|
||||||
// Switching?
|
// Switching?
|
||||||
create<DualAirPods>("07 19 01 0E 20 2B 99 8F 01 00 >09< 10 30 EE F3 41 B5 D8 9F A3 B0 B4 17 9F 85 97 5F") {
|
create<HasStateDetectionAirPods>("07 19 01 0E 20 2B 99 8F 01 00 >09< 10 30 EE F3 41 B5 D8 9F A3 B0 B4 17 9F 85 97 5F") {
|
||||||
// 38 0011 1000
|
// 38 0011 1000
|
||||||
state shouldBe DualAirPods.ConnectionState.HANGING_UP
|
state shouldBe HasStateDetectionAirPods.ConnectionState.HANGING_UP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package eu.darken.capod.pods.core.apple.airpods
|
|||||||
|
|
||||||
import eu.darken.capod.pods.core.PodDevice
|
import eu.darken.capod.pods.core.PodDevice
|
||||||
import eu.darken.capod.pods.core.apple.BaseAirPodsTest
|
import eu.darken.capod.pods.core.apple.BaseAirPodsTest
|
||||||
import eu.darken.capod.pods.core.apple.DualAirPods
|
import eu.darken.capod.pods.core.apple.DualApplePods
|
||||||
import eu.darken.capod.pods.core.apple.HasAppleColor
|
import eu.darken.capod.pods.core.apple.HasAppleColor
|
||||||
import io.kotest.matchers.shouldBe
|
import io.kotest.matchers.shouldBe
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
@@ -35,9 +35,7 @@ class AirPodsGen1Test : BaseAirPodsTest() {
|
|||||||
isRightPodInEar shouldBe false
|
isRightPodInEar shouldBe false
|
||||||
batteryCasePercent shouldBe 0.6f
|
batteryCasePercent shouldBe 0.6f
|
||||||
|
|
||||||
caseLidState shouldBe DualAirPods.LidState.OPEN
|
caseLidState shouldBe DualApplePods.LidState.OPEN
|
||||||
|
|
||||||
state shouldBe DualAirPods.ConnectionState.DISCONNECTED
|
|
||||||
|
|
||||||
podStyle.identifier shouldBe HasAppleColor.DeviceColor.WHITE.name
|
podStyle.identifier shouldBe HasAppleColor.DeviceColor.WHITE.name
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package eu.darken.capod.pods.core.apple.airpods
|
|||||||
|
|
||||||
import eu.darken.capod.pods.core.PodDevice
|
import eu.darken.capod.pods.core.PodDevice
|
||||||
import eu.darken.capod.pods.core.apple.BaseAirPodsTest
|
import eu.darken.capod.pods.core.apple.BaseAirPodsTest
|
||||||
import eu.darken.capod.pods.core.apple.DualAirPods
|
import eu.darken.capod.pods.core.apple.DualApplePods
|
||||||
import eu.darken.capod.pods.core.apple.HasAppleColor
|
import eu.darken.capod.pods.core.apple.HasAppleColor
|
||||||
import io.kotest.matchers.shouldBe
|
import io.kotest.matchers.shouldBe
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
@@ -34,9 +34,9 @@ class AirPodsGen2Test : BaseAirPodsTest() {
|
|||||||
isRightPodInEar shouldBe true
|
isRightPodInEar shouldBe true
|
||||||
batteryCasePercent shouldBe null
|
batteryCasePercent shouldBe null
|
||||||
|
|
||||||
caseLidState shouldBe DualAirPods.LidState.NOT_IN_CASE
|
caseLidState shouldBe DualApplePods.LidState.NOT_IN_CASE
|
||||||
|
|
||||||
state shouldBe DualAirPods.ConnectionState.MUSIC
|
state shouldBe HasStateDetectionAirPods.ConnectionState.MUSIC
|
||||||
|
|
||||||
podStyle.identifier shouldBe HasAppleColor.DeviceColor.WHITE.name
|
podStyle.identifier shouldBe HasAppleColor.DeviceColor.WHITE.name
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package eu.darken.capod.pods.core.apple.airpods
|
|||||||
|
|
||||||
import eu.darken.capod.pods.core.PodDevice
|
import eu.darken.capod.pods.core.PodDevice
|
||||||
import eu.darken.capod.pods.core.apple.BaseAirPodsTest
|
import eu.darken.capod.pods.core.apple.BaseAirPodsTest
|
||||||
import eu.darken.capod.pods.core.apple.DualAirPods
|
import eu.darken.capod.pods.core.apple.DualApplePods
|
||||||
import eu.darken.capod.pods.core.apple.HasAppleColor
|
import eu.darken.capod.pods.core.apple.HasAppleColor
|
||||||
import io.kotest.matchers.shouldBe
|
import io.kotest.matchers.shouldBe
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
@@ -34,9 +34,9 @@ class AirPodsGen3Test : BaseAirPodsTest() {
|
|||||||
isRightPodInEar shouldBe false
|
isRightPodInEar shouldBe false
|
||||||
batteryCasePercent shouldBe 0.9f
|
batteryCasePercent shouldBe 0.9f
|
||||||
|
|
||||||
caseLidState shouldBe DualAirPods.LidState.OPEN
|
caseLidState shouldBe DualApplePods.LidState.OPEN
|
||||||
|
|
||||||
state shouldBe DualAirPods.ConnectionState.IDLE
|
state shouldBe HasStateDetectionAirPods.ConnectionState.IDLE
|
||||||
|
|
||||||
podStyle.identifier shouldBe HasAppleColor.DeviceColor.WHITE.name
|
podStyle.identifier shouldBe HasAppleColor.DeviceColor.WHITE.name
|
||||||
|
|
||||||
@@ -58,9 +58,9 @@ class AirPodsGen3Test : BaseAirPodsTest() {
|
|||||||
isRightPodInEar shouldBe true
|
isRightPodInEar shouldBe true
|
||||||
batteryCasePercent shouldBe null
|
batteryCasePercent shouldBe null
|
||||||
|
|
||||||
caseLidState shouldBe DualAirPods.LidState.NOT_IN_CASE
|
caseLidState shouldBe DualApplePods.LidState.NOT_IN_CASE
|
||||||
|
|
||||||
state shouldBe DualAirPods.ConnectionState.UNKNOWN
|
state shouldBe HasStateDetectionAirPods.ConnectionState.UNKNOWN
|
||||||
|
|
||||||
podStyle.identifier shouldBe HasAppleColor.DeviceColor.WHITE.name
|
podStyle.identifier shouldBe HasAppleColor.DeviceColor.WHITE.name
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -8,7 +8,7 @@ import eu.darken.capod.R
|
|||||||
import eu.darken.capod.common.lists.binding
|
import eu.darken.capod.common.lists.binding
|
||||||
import eu.darken.capod.databinding.OverviewPodsDualItemBinding
|
import eu.darken.capod.databinding.OverviewPodsDualItemBinding
|
||||||
import eu.darken.capod.pods.core.*
|
import eu.darken.capod.pods.core.*
|
||||||
import eu.darken.capod.pods.core.apple.DualAirPods
|
import eu.darken.capod.pods.core.apple.DualApplePods
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
|
||||||
class DualPodsCardVH(parent: ViewGroup) :
|
class DualPodsCardVH(parent: ViewGroup) :
|
||||||
@@ -32,7 +32,7 @@ class DualPodsCardVH(parent: ViewGroup) :
|
|||||||
if (item.isMainPod) setTypeface(null, Typeface.BOLD)
|
if (item.isMainPod) setTypeface(null, Typeface.BOLD)
|
||||||
else setTypeface(null, Typeface.NORMAL)
|
else setTypeface(null, Typeface.NORMAL)
|
||||||
|
|
||||||
if (device is DualAirPods && item.showDebug) {
|
if (device is DualApplePods && item.showDebug) {
|
||||||
append(" [${device.primaryPod.name}]")
|
append(" [${device.primaryPod.name}]")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ import eu.darken.capod.R
|
|||||||
import eu.darken.capod.common.lists.binding
|
import eu.darken.capod.common.lists.binding
|
||||||
import eu.darken.capod.databinding.OverviewPodsDualItemBinding
|
import eu.darken.capod.databinding.OverviewPodsDualItemBinding
|
||||||
import eu.darken.capod.pods.core.*
|
import eu.darken.capod.pods.core.*
|
||||||
import eu.darken.capod.pods.core.apple.DualAirPods
|
import eu.darken.capod.pods.core.apple.DualApplePods
|
||||||
import eu.darken.capod.pods.core.apple.DualAirPods.LidState
|
import eu.darken.capod.pods.core.apple.DualApplePods.LidState
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ class DualPodsCardVH(parent: ViewGroup) :
|
|||||||
if (item.isMainPod) setTypeface(null, Typeface.BOLD)
|
if (item.isMainPod) setTypeface(null, Typeface.BOLD)
|
||||||
else setTypeface(null, Typeface.NORMAL)
|
else setTypeface(null, Typeface.NORMAL)
|
||||||
|
|
||||||
if (device is DualAirPods && item.showDebug) {
|
if (device is DualApplePods && item.showDebug) {
|
||||||
append(" [${device.primaryPod.name}]")
|
append(" [${device.primaryPod.name}]")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -129,7 +129,7 @@ class DualPodsCardVH(parent: ViewGroup) :
|
|||||||
|
|
||||||
// Case lid state
|
// Case lid state
|
||||||
device.apply {
|
device.apply {
|
||||||
if (this is DualAirPods) {
|
if (this is DualApplePods) {
|
||||||
podCaseLidLabel.text = when (caseLidState) {
|
podCaseLidLabel.text = when (caseLidState) {
|
||||||
LidState.OPEN -> context.getString(R.string.pods_case_status_open_label)
|
LidState.OPEN -> context.getString(R.string.pods_case_status_open_label)
|
||||||
LidState.CLOSED -> context.getString(R.string.pods_case_status_closed_label)
|
LidState.CLOSED -> context.getString(R.string.pods_case_status_closed_label)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import android.widget.RemoteViews
|
|||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import eu.darken.capod.R
|
import eu.darken.capod.R
|
||||||
import eu.darken.capod.pods.core.*
|
import eu.darken.capod.pods.core.*
|
||||||
import eu.darken.capod.pods.core.apple.DualAirPods
|
import eu.darken.capod.pods.core.apple.DualApplePods
|
||||||
import eu.darken.capod.pods.core.apple.SingleApplePods
|
import eu.darken.capod.pods.core.apple.SingleApplePods
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@@ -16,12 +16,12 @@ class MonitorNotificationViewFactory @Inject constructor(
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
fun createContentView(device: PodDevice): RemoteViews = when (device) {
|
fun createContentView(device: PodDevice): RemoteViews = when (device) {
|
||||||
is DualAirPods -> createDualApplePods(device)
|
is DualApplePods -> createDualApplePods(device)
|
||||||
is SingleApplePods -> createSingleApplePods(device)
|
is SingleApplePods -> createSingleApplePods(device)
|
||||||
else -> createUnknownDevice(device)
|
else -> createUnknownDevice(device)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createDualApplePods(device: DualAirPods): RemoteViews = RemoteViews(
|
private fun createDualApplePods(device: DualApplePods): RemoteViews = RemoteViews(
|
||||||
context.packageName,
|
context.packageName,
|
||||||
R.layout.monitor_notification_dual_pods_small
|
R.layout.monitor_notification_dual_pods_small
|
||||||
).apply {
|
).apply {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import eu.darken.capod.common.debug.autoreport.DebugSettings
|
|||||||
import eu.darken.capod.databinding.PopupNotificationDualPodsBinding
|
import eu.darken.capod.databinding.PopupNotificationDualPodsBinding
|
||||||
import eu.darken.capod.databinding.PopupNotificationSinglePodsBinding
|
import eu.darken.capod.databinding.PopupNotificationSinglePodsBinding
|
||||||
import eu.darken.capod.pods.core.*
|
import eu.darken.capod.pods.core.*
|
||||||
import eu.darken.capod.pods.core.apple.DualAirPods
|
import eu.darken.capod.pods.core.apple.DualApplePods
|
||||||
import eu.darken.capod.pods.core.apple.SingleApplePods
|
import eu.darken.capod.pods.core.apple.SingleApplePods
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@@ -26,13 +26,13 @@ class PopUpPodViewFactory @Inject constructor(
|
|||||||
private val layoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
|
private val layoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
|
||||||
|
|
||||||
fun createContentView(parent: ViewGroup, device: PodDevice): View = when (device) {
|
fun createContentView(parent: ViewGroup, device: PodDevice): View = when (device) {
|
||||||
is DualAirPods -> createDualApplePods(parent, device)
|
is DualApplePods -> createDualApplePods(parent, device)
|
||||||
// Unused, has no case to trigger reaction?
|
// Unused, has no case to trigger reaction?
|
||||||
is SingleApplePods -> createSingleApplePods(parent, device)
|
is SingleApplePods -> createSingleApplePods(parent, device)
|
||||||
else -> throw IllegalArgumentException("Unexpected device: $device")
|
else -> throw IllegalArgumentException("Unexpected device: $device")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createDualApplePods(parent: ViewGroup, device: DualAirPods): View =
|
private fun createDualApplePods(parent: ViewGroup, device: DualApplePods): View =
|
||||||
PopupNotificationDualPodsBinding.inflate(layoutInflater, parent, false).apply {
|
PopupNotificationDualPodsBinding.inflate(layoutInflater, parent, false).apply {
|
||||||
device.apply {
|
device.apply {
|
||||||
podIcon.setImageResource(iconRes)
|
podIcon.setImageResource(iconRes)
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
### Updated by release.sh ###
|
### Updated by release.sh ###
|
||||||
project.versioning.major=2
|
project.versioning.major=2
|
||||||
project.versioning.minor=6
|
project.versioning.minor=6
|
||||||
project.versioning.patch=0
|
project.versioning.patch=1
|
||||||
project.versioning.build=0
|
project.versioning.build=0
|
||||||
#############################
|
#############################
|
||||||
|
|||||||
Reference in New Issue
Block a user