Skip to content

Commit 663e2d3

Browse files
b4shtirk1nd4rken
authored andcommitted
add support airpods max 2 & fix airpods max
1 parent 858b86a commit 663e2d3

File tree

4 files changed

+76
-1
lines changed

4 files changed

+76
-1
lines changed

app-common/src/main/java/eu/darken/capod/pods/core/PodDevice.kt

+4
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ interface PodDevice {
107107
"AirPods Max",
108108
R.drawable.devic_headphones_generic
109109
),
110+
@Json(name = "airpods.max2") AIRPODS_MAX2(
111+
"AirPods Max 2",
112+
R.drawable.devic_headphones_generic
113+
),
110114
@Json(name = "beats.flex") BEATS_FLEX(
111115
"Beats Flex"
112116
),

app-common/src/main/java/eu/darken/capod/pods/core/apple/AppleFactoryModule.kt

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import eu.darken.capod.pods.core.apple.airpods.AirPodsGen3
1111
import eu.darken.capod.pods.core.apple.airpods.AirPodsGen4
1212
import eu.darken.capod.pods.core.apple.airpods.AirPodsGen4Anc
1313
import eu.darken.capod.pods.core.apple.airpods.AirPodsMax
14+
import eu.darken.capod.pods.core.apple.airpods.AirPodsMax2
1415
import eu.darken.capod.pods.core.apple.airpods.AirPodsPro
1516
import eu.darken.capod.pods.core.apple.airpods.AirPodsPro2
1617
import eu.darken.capod.pods.core.apple.airpods.AirPodsPro2Usbc
@@ -42,6 +43,7 @@ abstract class AppleFactoryModule {
4243
@Binds @IntoSet abstract fun airPodsPro2(factory: AirPodsPro2.Factory): ApplePodsFactory<out ApplePods>
4344
@Binds @IntoSet abstract fun airPodsPro2Usbc(factory: AirPodsPro2Usbc.Factory): ApplePodsFactory<out ApplePods>
4445
@Binds @IntoSet abstract fun airPodsMax(factory: AirPodsMax.Factory): ApplePodsFactory<out ApplePods>
46+
@Binds @IntoSet abstract fun airPodsMax2(factory: AirPodsMax2.Factory): ApplePodsFactory<out ApplePods>
4547

4648
@Binds @IntoSet abstract fun beatsFlex(factory: BeatsFlex.Factory): ApplePodsFactory<out ApplePods>
4749
@Binds @IntoSet abstract fun beatsSolo3(factory: BeatsSolo3.Factory): ApplePodsFactory<out ApplePods>

app-common/src/main/java/eu/darken/capod/pods/core/apple/airpods/AirPodsMax.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ data class AirPodsMax(
6363
}
6464

6565
companion object {
66-
private val DEVICE_CODE_DIRTY = 10.toUByte()
66+
private val DEVICE_CODE_DIRTY = 0x200A.toUByte()
6767
private val TAG = logTag("PodDevice", "Apple", "AirPods", "Max")
6868
}
6969
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package eu.darken.capod.pods.core.apple.airpods
2+
3+
import eu.darken.capod.common.bluetooth.BleScanResult
4+
import eu.darken.capod.common.debug.logging.logTag
5+
import eu.darken.capod.common.isBitSet
6+
import eu.darken.capod.pods.core.HasChargeDetection
7+
import eu.darken.capod.pods.core.HasEarDetection
8+
import eu.darken.capod.pods.core.PodDevice
9+
import eu.darken.capod.pods.core.apple.ApplePods
10+
import eu.darken.capod.pods.core.apple.HasAppleColor
11+
import eu.darken.capod.pods.core.apple.SingleApplePods
12+
import eu.darken.capod.pods.core.apple.SingleApplePodsFactory
13+
import eu.darken.capod.pods.core.apple.protocol.ProximityPairing
14+
import java.time.Instant
15+
import javax.inject.Inject
16+
17+
data class AirPodsMax2(
18+
override val identifier: PodDevice.Id = PodDevice.Id(),
19+
override val seenLastAt: Instant = Instant.now(),
20+
override val seenFirstAt: Instant = Instant.now(),
21+
override val seenCounter: Int = 1,
22+
override val scanResult: BleScanResult,
23+
override val proximityMessage: ProximityPairing.Message,
24+
override val reliability: Float = PodDevice.BASE_CONFIDENCE,
25+
private val rssiAverage: Int? = null,
26+
) : SingleApplePods, HasEarDetection, HasChargeDetection, HasAppleColor {
27+
28+
override val model: PodDevice.Model = PodDevice.Model.AIRPODS_MAX2
29+
30+
override val rssi: Int
31+
get() = rssiAverage ?: super<SingleApplePods>.rssi
32+
33+
override val isHeadsetBeingCharged: Boolean
34+
get() = rawFlags.isBitSet(0)
35+
36+
override val isBeingWorn: Boolean
37+
get() = rawStatus.isBitSet(5)
38+
39+
class Factory @Inject constructor() : SingleApplePodsFactory(TAG) {
40+
41+
override fun isResponsible(message: ProximityPairing.Message): Boolean = message.run {
42+
getModelInfo().dirty == DEVICE_CODE_DIRTY && length == ProximityPairing.PAIRING_MESSAGE_LENGTH
43+
}
44+
45+
override fun create(scanResult: BleScanResult, message: ProximityPairing.Message): ApplePods {
46+
var basic = AirPodsMax2(scanResult = scanResult, proximityMessage = message)
47+
val result = searchHistory(basic)
48+
49+
if (result != null) basic = basic.copy(identifier = result.id)
50+
updateHistory(basic)
51+
52+
if (result == null) return basic
53+
54+
return basic.copy(
55+
identifier = result.id,
56+
seenFirstAt = result.seenFirstAt,
57+
seenLastAt = scanResult.receivedAt,
58+
seenCounter = result.seenCounter,
59+
reliability = result.reliability,
60+
rssiAverage = result.rssiSmoothed(basic.rssi),
61+
)
62+
}
63+
}
64+
65+
companion object {
66+
private val DEVICE_CODE_DIRTY = 0x201F.toUByte()
67+
private val TAG = logTag("PodDevice", "Apple", "AirPods", "Max2")
68+
}
69+
}

0 commit comments

Comments
 (0)