Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,14 @@ fun AppSettingsScreen(
enabled = state.isPremium
)

StyledToggle(
label = stringResource(R.string.conversational_awareness_both_pods_only),
description = stringResource(R.string.conversational_awareness_both_pods_only_description),
checked = state.conversationalAwarenessBothPodsOnlyEnabled,
onCheckedChange = viewModel::setConversationalAwarenessBothPodsOnlyEnabled,
enabled = state.isPremium,
)

StyledToggle(
label = stringResource(R.string.relative_conversational_awareness_volume),
description = stringResource(R.string.relative_conversational_awareness_volume_description),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import kotlin.math.roundToInt
data class AppSettingsUiState(
val showPhoneBatteryInWidget: Boolean = false,
val conversationalAwarenessPauseMusicEnabled: Boolean = false,
val conversationalAwarenessBothPodsOnlyEnabled: Boolean = false,
val relativeConversationalAwarenessVolumeEnabled: Boolean = true,
val disconnectWhenNotWearing: Boolean = false,
val takeoverWhenDisconnected: Boolean = false,
Expand Down Expand Up @@ -137,6 +138,7 @@ class AppSettingsViewModel(application: Application) : AndroidViewModel(applicat
currentState.copy(
showPhoneBatteryInWidget = sharedPreferences.getBoolean("show_phone_battery_in_widget", false),
conversationalAwarenessPauseMusicEnabled = sharedPreferences.getBoolean("conversational_awareness_pause_music", false),
conversationalAwarenessBothPodsOnlyEnabled = sharedPreferences.getBoolean("conversational_awareness_both_pods_only", false),
relativeConversationalAwarenessVolumeEnabled = sharedPreferences.getBoolean("relative_conversational_awareness_volume", true),
disconnectWhenNotWearing = sharedPreferences.getBoolean("disconnect_when_not_wearing", false),
takeoverWhenDisconnected = sharedPreferences.getBoolean("takeover_when_disconnected", false),
Expand Down Expand Up @@ -167,6 +169,11 @@ class AppSettingsViewModel(application: Application) : AndroidViewModel(applicat
_uiState.update { it.copy(conversationalAwarenessPauseMusicEnabled = enabled) }
}

fun setConversationalAwarenessBothPodsOnlyEnabled(enabled: Boolean) {
sharedPreferences.edit { putBoolean("conversational_awareness_both_pods_only", enabled) }
_uiState.update { it.copy(conversationalAwarenessBothPodsOnlyEnabled = enabled) }
}

fun setRelativeConversationalAwarenessVolumeEnabled(enabled: Boolean) {
sharedPreferences.edit { putBoolean("relative_conversational_awareness_volume", enabled) }
_uiState.update { it.copy(relativeConversationalAwarenessVolumeEnabled = enabled) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
var deviceName: String = "AirPods",
var earDetectionEnabled: Boolean = true,
var conversationalAwarenessPauseMusic: Boolean = false,
var conversationalAwarenessBothPodsOnly: Boolean = false,
var showPhoneBatteryInWidget: Boolean = true,
var relativeConversationalAwarenessVolume: Boolean = true,
var headGestures: Boolean = true,
Expand Down Expand Up @@ -440,6 +441,9 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
if (!contains("conversational_awareness_pause_music")) putBoolean(
"conversational_awareness_pause_music", false
)
if (!contains("conversational_awareness_both_pods_only")) putBoolean(
"conversational_awareness_both_pods_only", false
)
if (!contains("personalized_volume")) putBoolean("personalized_volume", false)
if (!contains("automatic_ear_detection")) putBoolean(
"automatic_ear_detection", true
Expand Down Expand Up @@ -912,10 +916,14 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
setPackage(packageName)
})

// Number of buds currently in the ear (0x00 == in ear).
val budsInEar = earDetectionNotification.status.count { it == 0x00.toByte() }
val blockedForSinglePod = config.conversationalAwarenessBothPodsOnly && budsInEar < 2

if (conversationAwarenessNotification.status == 1.toByte() || conversationAwarenessNotification.status == 2.toByte()) {
MediaController.startSpeaking()
} else if (conversationAwarenessNotification.status == 6.toByte() ||conversationAwarenessNotification.status == 8.toByte() || conversationAwarenessNotification.status == 9.toByte()) {
MediaController.stopSpeaking()
if (!blockedForSinglePod) MediaController.startSpeaking()
} else if (conversationAwarenessNotification.status == 6.toByte() || conversationAwarenessNotification.status == 8.toByte() || conversationAwarenessNotification.status == 9.toByte()) {
MediaController.stopSpeaking() // Never gate the "stop" side — volume must always be restored.
}

Log.d(
Expand Down Expand Up @@ -1360,6 +1368,9 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
conversationalAwarenessPauseMusic = sharedPreferences.getBoolean(
"conversational_awareness_pause_music", false
),
conversationalAwarenessBothPodsOnly = sharedPreferences.getBoolean(
"conversational_awareness_both_pods_only", false
),
showPhoneBatteryInWidget = sharedPreferences.getBoolean(
"show_phone_battery_in_widget", true
),
Expand Down Expand Up @@ -1473,6 +1484,9 @@ class AirPodsService : Service(), SharedPreferences.OnSharedPreferenceChangeList
"conversational_awareness_pause_music" -> config.conversationalAwarenessPauseMusic =
preferences.getBoolean(key, false)

"conversational_awareness_both_pods_only" -> config.conversationalAwarenessBothPodsOnly =
preferences.getBoolean(key, false)

"show_phone_battery_in_widget" -> {
config.showPhoneBatteryInWidget = preferences.getBoolean(key, true)
widgetMobileBatteryEnabled = config.showPhoneBatteryInWidget
Expand Down
2 changes: 2 additions & 0 deletions android/app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
<string name="relative_conversational_awareness_volume_description">Reduces to a percentage of the current volume instead of the maximum volume.</string>
<string name="conversational_awareness_pause_music">Pause Music</string>
<string name="conversational_awareness_pause_music_description">When you start speaking, music will be paused.</string>
<string name="conversational_awareness_both_pods_only">Only when both AirPods are worn</string>
<string name="conversational_awareness_both_pods_only_description">Only lowers the volume when you speak if both AirPods are in your ears.</string>
<string name="appwidget_text">EXAMPLE</string>
<string name="add_widget">Add widget</string>
<string name="noise_control_widget_description">Control Noise Control Mode directly from your Home Screen.</string>
Expand Down