mirror of
https://github.com/d4rken-org/capod.git
synced 2026-09-16 11:16:12 -04:00
fix(aap): Update feature flags for Max 2 and Powerbeats Pro 2, sync ear detection
Add H2-chip feature flags (adaptive ANC, conversation awareness, personalized volume, listening mode cycle, InitExt) to AirPods Max 2. Add sleep detection and ear detection toggle to Powerbeats Pro 2. Auto-sync device ear detection setting when auto-play/auto-pause reactions are toggled. Add flag invariant tests to prevent future drift.
This commit is contained in:
@@ -358,7 +358,8 @@ fun DeviceSettingsScreen(
|
||||
if (device.isAapConnected) {
|
||||
val convAwareness = device.conversationalAwareness
|
||||
val hasAnyAapReaction =
|
||||
(features.hasConversationAwareness && convAwareness != null) || features.hasSleepDetection
|
||||
(features.hasConversationAwareness && convAwareness != null) ||
|
||||
features.hasSleepDetection
|
||||
if (features.hasConversationAwareness && convAwareness != null) {
|
||||
SettingsSwitchItem(
|
||||
icon = Icons.TwoTone.Hearing,
|
||||
|
||||
+34
-4
@@ -302,14 +302,44 @@ class DeviceSettingsViewModel @Inject constructor(
|
||||
launch { updateProfileNow { it.copy(onePodMode = enabled) } }
|
||||
}
|
||||
|
||||
fun setAutoPlay(enabled: Boolean) {
|
||||
fun setAutoPlay(enabled: Boolean) = launch {
|
||||
log(TAG, INFO) { "setAutoPlay($enabled)" }
|
||||
proGatedReaction(enabled) { it.copy(autoPlay = enabled) }
|
||||
if (enabled && !upgradeRepo.isPro()) {
|
||||
navTo(Nav.Main.Upgrade)
|
||||
return@launch
|
||||
}
|
||||
updateProfileNow { it.copy(autoPlay = enabled) }
|
||||
syncEarDetection(autoPlay = enabled)
|
||||
}
|
||||
|
||||
fun setAutoPause(enabled: Boolean) {
|
||||
fun setAutoPause(enabled: Boolean) = launch {
|
||||
log(TAG, INFO) { "setAutoPause($enabled)" }
|
||||
proGatedReaction(enabled) { it.copy(autoPause = enabled) }
|
||||
if (enabled && !upgradeRepo.isPro()) {
|
||||
navTo(Nav.Main.Upgrade)
|
||||
return@launch
|
||||
}
|
||||
updateProfileNow { it.copy(autoPause = enabled) }
|
||||
syncEarDetection(autoPause = enabled)
|
||||
}
|
||||
|
||||
/**
|
||||
* Keeps the device-side Automatic Ear Detection setting in sync with the
|
||||
* auto-play / auto-pause reaction toggles. When either reaction is active
|
||||
* the device must report ear-in / ear-out events; when both are off the
|
||||
* setting is disabled to match the user's intent.
|
||||
*
|
||||
* Only sends when the model supports the setting and AAP is ready —
|
||||
* silent no-op otherwise (reactions are per-profile and work offline).
|
||||
*/
|
||||
private suspend fun syncEarDetection(autoPlay: Boolean? = null, autoPause: Boolean? = null) {
|
||||
val profileId = targetProfileId.value ?: return
|
||||
val device = deviceMonitor.getDeviceForProfile(profileId) ?: return
|
||||
if (device.model?.features?.hasEarDetectionToggle != true) return
|
||||
if (!device.isAapReady) return
|
||||
val reactions = device.reactions
|
||||
val effectiveAutoPlay = autoPlay ?: reactions.autoPlay
|
||||
val effectiveAutoPause = autoPause ?: reactions.autoPause
|
||||
sendInternal(AapCommand.SetEarDetectionEnabled(effectiveAutoPlay || effectiveAutoPause))
|
||||
}
|
||||
|
||||
fun setAutoConnect(enabled: Boolean) = launch {
|
||||
|
||||
@@ -271,10 +271,17 @@ enum class PodModel(
|
||||
Features(
|
||||
hasEarDetection = true,
|
||||
hasAncControl = true,
|
||||
hasAdaptiveAnc = true,
|
||||
hasConversationAwareness = true,
|
||||
hasPressSpeed = true,
|
||||
hasPressHoldDuration = true,
|
||||
hasPersonalizedVolume = true,
|
||||
hasToneVolume = true,
|
||||
hasAdaptiveAudioNoise = true,
|
||||
hasEarDetectionToggle = true,
|
||||
hasListeningModeCycle = true,
|
||||
hasAllowOffOption = true,
|
||||
needsInitExt = true,
|
||||
),
|
||||
modelNumbers = setOf("A3454"), // headphones
|
||||
),
|
||||
@@ -410,6 +417,8 @@ enum class PodModel(
|
||||
hasCase = true,
|
||||
hasEarDetection = true,
|
||||
hasAncControl = true,
|
||||
hasEarDetectionToggle = true,
|
||||
hasSleepDetection = true,
|
||||
),
|
||||
modelNumbers = setOf("A3157", "A3158", "A3159"), // L/R earbuds + case
|
||||
leftPodIconRes = R.drawable.device_powerbeats_pro2_left,
|
||||
|
||||
Reference in New Issue
Block a user