Merge changes from topic "ACH_CONFIGURATIONS" into main
* changes:
Add audio control configuraiton APIs VTS
Add default implementation to load current XML
Add audio configurations API to audio control HAL
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioDeviceConfiguration.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioDeviceConfiguration.aidl
new file mode 100644
index 0000000..2685f58
--- /dev/null
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioDeviceConfiguration.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.audiocontrol;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioDeviceConfiguration {
+ android.hardware.automotive.audiocontrol.RoutingDeviceConfiguration routingConfig;
+ boolean useCoreAudioVolume;
+ boolean useHalDuckingSignals;
+ boolean useCarVolumeGroupMuting;
+}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioFadeConfiguration.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioFadeConfiguration.aidl
new file mode 100644
index 0000000..0a3c677
--- /dev/null
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioFadeConfiguration.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.audiocontrol;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioFadeConfiguration {
+ String name;
+ android.hardware.automotive.audiocontrol.FadeState fadeState;
+ long fadeInDurationMs = DEFAULT_FADE_IN_DURATION_MS /* 1000 */;
+ long fadeOutDurationMs = DEFAULT_FADE_OUT_DURATION_MS /* 2000 */;
+ long fadeInDelayedForOffendersMs = DEFAULT_DELAY_FADE_IN_OFFENDERS_MS /* 2000 */;
+ android.media.audio.common.AudioUsage[] fadeableUsages;
+ @nullable android.media.audio.common.AudioContentType[] unfadeableContentTypes;
+ List<android.media.audio.common.AudioAttributes> unfadableAudioAttributes;
+ List<android.hardware.automotive.audiocontrol.FadeConfiguration> fadeOutConfigurations;
+ List<android.hardware.automotive.audiocontrol.FadeConfiguration> fadeInConfigurations;
+ const long DEFAULT_FADE_IN_DURATION_MS = 1000;
+ const long DEFAULT_FADE_OUT_DURATION_MS = 2000;
+ const long DEFAULT_DELAY_FADE_IN_OFFENDERS_MS = 2000;
+}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl
index 58a3667..8eab521 100644
--- a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl
@@ -39,7 +39,7 @@
GAIN_TRANSIENT = 2,
GAIN_TRANSIENT_MAY_DUCK = 3,
GAIN_TRANSIENT_EXCLUSIVE = 4,
- LOSS = -1,
- LOSS_TRANSIENT = -2,
- LOSS_TRANSIENT_CAN_DUCK = -3,
+ LOSS = ((-1) * GAIN) /* -1 */,
+ LOSS_TRANSIENT = ((-1) * GAIN_TRANSIENT) /* -2 */,
+ LOSS_TRANSIENT_CAN_DUCK = ((-1) * GAIN_TRANSIENT_MAY_DUCK) /* -3 */,
}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioZone.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioZone.aidl
new file mode 100644
index 0000000..2cb1760
--- /dev/null
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioZone.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.audiocontrol;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioZone {
+ String name;
+ int id;
+ int occupantZoneId = UNASSIGNED_OCCUPANT /* -1 */;
+ android.hardware.automotive.audiocontrol.AudioZoneContext audioZoneContext;
+ List<android.hardware.automotive.audiocontrol.AudioZoneConfig> audioZoneConfigs;
+ List<android.media.audio.common.AudioPort> inputAudioDevices;
+ const int PRIMARY_AUDIO_ZONE = 0;
+ const int UNASSIGNED_OCCUPANT = (-1) /* -1 */;
+}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioZoneConfig.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioZoneConfig.aidl
new file mode 100644
index 0000000..3fd37bc
--- /dev/null
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioZoneConfig.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.audiocontrol;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioZoneConfig {
+ String name;
+ boolean isDefault;
+ List<android.hardware.automotive.audiocontrol.VolumeGroupConfig> volumeGroups;
+ @nullable android.hardware.automotive.audiocontrol.AudioZoneFadeConfiguration fadeConfiguration;
+}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioZoneContext.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioZoneContext.aidl
new file mode 100644
index 0000000..0f8b946
--- /dev/null
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioZoneContext.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.audiocontrol;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioZoneContext {
+ List<android.hardware.automotive.audiocontrol.AudioZoneContextInfo> audioContextInfos;
+}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioZoneContextInfo.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioZoneContextInfo.aidl
new file mode 100644
index 0000000..01ab1be
--- /dev/null
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioZoneContextInfo.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.audiocontrol;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioZoneContextInfo {
+ String name;
+ int id = UNASSIGNED_CONTEXT_ID /* -1 */;
+ List<android.media.audio.common.AudioAttributes> audioAttributes;
+ const int UNASSIGNED_CONTEXT_ID = (-1) /* -1 */;
+}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioZoneFadeConfiguration.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioZoneFadeConfiguration.aidl
new file mode 100644
index 0000000..f3f32bf
--- /dev/null
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioZoneFadeConfiguration.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.audiocontrol;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioZoneFadeConfiguration {
+ android.hardware.automotive.audiocontrol.AudioFadeConfiguration defaultConfiguration;
+ List<android.hardware.automotive.audiocontrol.TransientFadeConfigurationEntry> transientConfiguration;
+}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/DeviceToContextEntry.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/DeviceToContextEntry.aidl
new file mode 100644
index 0000000..923b0bd
--- /dev/null
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/DeviceToContextEntry.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.audiocontrol;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable DeviceToContextEntry {
+ List<String> contextNames;
+ android.media.audio.common.AudioPort device;
+}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/FadeConfiguration.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/FadeConfiguration.aidl
new file mode 100644
index 0000000..2c978e7
--- /dev/null
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/FadeConfiguration.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.audiocontrol;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable FadeConfiguration {
+ long fadeDurationMillis;
+ android.hardware.automotive.audiocontrol.FadeConfiguration.AudioAttributesOrUsage audioAttributesOrUsage;
+ @JavaDerive(equals=true, toString=true) @VintfStability
+ union AudioAttributesOrUsage {
+ android.media.audio.common.AudioAttributes fadeAttribute;
+ android.media.audio.common.AudioUsage usage;
+ }
+}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/FadeState.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/FadeState.aidl
new file mode 100644
index 0000000..9b25dfb
--- /dev/null
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/FadeState.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.audiocontrol;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum FadeState {
+ FADE_STATE_DISABLED,
+ FADE_STATE_ENABLED_DEFAULT,
+}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl
index ffd575d..fe39f92 100644
--- a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl
@@ -12,6 +12,34 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
+ *//**
+ * Important note on Metadata:
+ * Metadata qualifies a playback track for an output stream.
+ * This is highly closed to {@link android.media.AudioAttributes}.
+ * It allows to identify the audio stream rendered / requesting / abandonning the focus.
+ *
+ * AudioControl 1.0 was limited to identification through {@code AttributeUsage} listed as
+ * {@code audioUsage} in audio_policy_configuration.xsd.
+ *
+ * Any new OEM needs would not be possible without extension.
+ *
+ * Relying on {@link android.hardware.automotive.audiocontrol.PlaybackTrackMetadata} allows
+ * to use a combination of {@code AttributeUsage}, {@code AttributeContentType} and
+ * {@code AttributeTags} to identify the use case / routing thanks to
+ * {@link android.media.audiopolicy.AudioProductStrategy}.
+ * The belonging to a strategy is deduced by an AOSP logic (in sync at native and java layer).
+ *
+ * IMPORTANT NOTE ON TAGS:
+ * To limit the possibilies and prevent from confusion, we expect the String to follow
+ * a given formalism that will be enforced.
+ *
+ * 1 / By convention, tags shall be a "key=value" pair.
+ * Vendor must namespace their tag's key (for example com.google.strategy=VR) to avoid conflicts.
+ * vendor specific applications and must be prefixed by "VX_". Vendor must
+ *
+ * 2 / Tags reported here shall be the same as the tags used to define a given
+ * {@link android.media.audiopolicy.AudioProductStrategy} and so in
+ * audio_policy_engine_configuration.xml file.
*/
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
@@ -48,4 +76,7 @@
oneway void registerGainCallback(in android.hardware.automotive.audiocontrol.IAudioGainCallback callback);
void setModuleChangeCallback(in android.hardware.automotive.audiocontrol.IModuleChangeCallback callback);
void clearModuleChangeCallback();
+ android.hardware.automotive.audiocontrol.AudioDeviceConfiguration getAudioDeviceConfiguration();
+ List<android.media.audio.common.AudioPort> getOutputMirroringDevices();
+ List<android.hardware.automotive.audiocontrol.AudioZone> getCarAudioZones();
}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/Reasons.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/Reasons.aidl
index c1e22d4..8d66985 100644
--- a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/Reasons.aidl
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/Reasons.aidl
@@ -34,14 +34,14 @@
package android.hardware.automotive.audiocontrol;
@Backing(type="int") @VintfStability
enum Reasons {
- FORCED_MASTER_MUTE = 1,
- REMOTE_MUTE = 2,
- TCU_MUTE = 4,
- ADAS_DUCKING = 8,
- NAV_DUCKING = 16,
- PROJECTION_DUCKING = 32,
- THERMAL_LIMITATION = 64,
- SUSPEND_EXIT_VOL_LIMITATION = 128,
- EXTERNAL_AMP_VOL_FEEDBACK = 256,
- OTHER = -2147483648,
+ FORCED_MASTER_MUTE = 0x1,
+ REMOTE_MUTE = 0x2,
+ TCU_MUTE = 0x4,
+ ADAS_DUCKING = 0x8,
+ NAV_DUCKING = 0x10,
+ PROJECTION_DUCKING = 0x20,
+ THERMAL_LIMITATION = 0x40,
+ SUSPEND_EXIT_VOL_LIMITATION = 0x80,
+ EXTERNAL_AMP_VOL_FEEDBACK = 0x100,
+ OTHER = 0x80000000,
}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/RoutingDeviceConfiguration.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/RoutingDeviceConfiguration.aidl
new file mode 100644
index 0000000..901078c
--- /dev/null
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/RoutingDeviceConfiguration.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.audiocontrol;
+@JavaDerive(equals=true, toString=true) @VintfStability
+enum RoutingDeviceConfiguration {
+ DEFAULT_AUDIO_ROUTING,
+ DYNAMIC_AUDIO_ROUTING,
+ CONFIGURABLE_AUDIO_ENGINE_ROUTING,
+}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/TransientFadeConfigurationEntry.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/TransientFadeConfigurationEntry.aidl
new file mode 100644
index 0000000..72b247b
--- /dev/null
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/TransientFadeConfigurationEntry.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.audiocontrol;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable TransientFadeConfigurationEntry {
+ android.media.audio.common.AudioUsage[] transientUsages;
+ android.hardware.automotive.audiocontrol.AudioFadeConfiguration transientFadeConfiguration;
+}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/VolumeActivationConfiguration.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/VolumeActivationConfiguration.aidl
new file mode 100644
index 0000000..50b76a1
--- /dev/null
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/VolumeActivationConfiguration.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.audiocontrol;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable VolumeActivationConfiguration {
+ @nullable String name;
+ List<android.hardware.automotive.audiocontrol.VolumeActivationConfigurationEntry> volumeActivationEntries;
+}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/VolumeActivationConfigurationEntry.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/VolumeActivationConfigurationEntry.aidl
new file mode 100644
index 0000000..d457e57
--- /dev/null
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/VolumeActivationConfigurationEntry.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.audiocontrol;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable VolumeActivationConfigurationEntry {
+ android.hardware.automotive.audiocontrol.VolumeInvocationType type = android.hardware.automotive.audiocontrol.VolumeInvocationType.ON_PLAYBACK_CHANGED;
+ int maxActivationVolumePercentage = DEFAULT_MAX_ACTIVATION_VALUE /* 100 */;
+ int minActivationVolumePercentage = DEFAULT_MIN_ACTIVATION_VALUE /* 0 */;
+ const int DEFAULT_MAX_ACTIVATION_VALUE = 100;
+ const int DEFAULT_MIN_ACTIVATION_VALUE = 0;
+}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/VolumeGroupConfig.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/VolumeGroupConfig.aidl
new file mode 100644
index 0000000..cc90bbe
--- /dev/null
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/VolumeGroupConfig.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.audiocontrol;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable VolumeGroupConfig {
+ String name;
+ int id = UNASSIGNED_ID /* -1 */;
+ List<android.hardware.automotive.audiocontrol.DeviceToContextEntry> carAudioRoutes;
+ @nullable android.hardware.automotive.audiocontrol.VolumeActivationConfiguration activationConfiguration;
+ const int UNASSIGNED_ID = (-1) /* -1 */;
+}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/VolumeInvocationType.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/VolumeInvocationType.aidl
new file mode 100644
index 0000000..8ce8491
--- /dev/null
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/VolumeInvocationType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.audiocontrol;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum VolumeInvocationType {
+ ON_PLAYBACK_CHANGED,
+ ON_SOURCE_CHANGED,
+ ON_BOOT,
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioDeviceConfiguration.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioDeviceConfiguration.aidl
new file mode 100644
index 0000000..9b5e724
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioDeviceConfiguration.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+import android.hardware.automotive.audiocontrol.RoutingDeviceConfiguration;
+
+/**
+ * Use to configure audio configurations at boot up time.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable AudioDeviceConfiguration {
+ /**
+ * Use to configure audio device routing mechanism
+ */
+ RoutingDeviceConfiguration routingConfig;
+
+ /**
+ * Use to configure core audio volume usage in car audio service
+ */
+ boolean useCoreAudioVolume;
+
+ /**
+ * Use to determine if HAL ducking signal should be sent to audio control HAL from car audio
+ * service
+ */
+ boolean useHalDuckingSignals;
+
+ /**
+ * Use to determine if HAL volume signal should be sent to audio control HAL from car audio
+ * service
+ */
+ boolean useCarVolumeGroupMuting;
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioFadeConfiguration.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioFadeConfiguration.aidl
new file mode 100644
index 0000000..d3181da
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioFadeConfiguration.aidl
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+import android.hardware.automotive.audiocontrol.FadeConfiguration;
+import android.hardware.automotive.audiocontrol.FadeState;
+import android.media.audio.common.AudioAttributes;
+import android.media.audio.common.AudioContentType;
+import android.media.audio.common.AudioUsage;
+
+/**
+ * Encapsulates the audio fade configuration info
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable AudioFadeConfiguration {
+ /**
+ * Default fade in duration
+ */
+ const long DEFAULT_FADE_IN_DURATION_MS = 1000;
+
+ /**
+ * Default fade out duration
+ */
+ const long DEFAULT_FADE_OUT_DURATION_MS = 2000;
+
+ /**
+ * Default delay for fade in offenders
+ */
+ const long DEFAULT_DELAY_FADE_IN_OFFENDERS_MS = 2000;
+
+ /**
+ * Audio configuration name, use for debugging purposes
+ */
+ String name;
+
+ /**
+ * Audio configuration state
+ */
+ FadeState fadeState;
+
+ /**
+ * Fade in duration in milliseconds
+ *
+ * <p>Use to construct the default fade in configuration. This can be overwritten for different
+ * attributes/usages by passing a list of fade-in configuration,
+ * see {@code #fadeInConfigurations}
+ */
+ long fadeInDurationMs = DEFAULT_FADE_IN_DURATION_MS;
+
+ /**
+ * Fade out duration in milliseconds
+ *
+ * <p>Use to construct the default fade out configuration. This can be overwritten for different
+ * attributes/usages by passing a list of fade-out configuration,
+ * see {@code #fadeOutConfigurations}
+ */
+ long fadeOutDurationMs = DEFAULT_FADE_OUT_DURATION_MS;
+
+ /**
+ * Fade in delayed duration for audio focus offender in milliseconds
+ */
+ long fadeInDelayedForOffendersMs = DEFAULT_DELAY_FADE_IN_OFFENDERS_MS;
+
+ /**
+ * List of audio attribute usage that should be faded using the parameters in
+ * this configuration.
+ *
+ *<p>If the list is empty car audio service will overwrite the list for the confgiruation with
+ * default usages, e.g. {AudioUsage#MEDIA, AudioUsage#GAME}
+ */
+ AudioUsage[] fadeableUsages;
+
+ /**
+ * Optional list of audio attribute content types that should not be faded.
+ *
+ **<p>The list can be empty in cases where there are no unfadeable content types.
+ *
+ *<p>If the list is not set car audio service will overwrite the list for the confgiruation
+ * with default content type, e.g. {AudioContentType#SPEECH}.
+ */
+ @nullable AudioContentType[] unfadeableContentTypes;
+
+ /**
+ * List of audio attribute that should not be faded.
+ *
+ *<p>The list can be empty in cases where there are no unfadeable attributes
+ */
+ List<AudioAttributes> unfadableAudioAttributes;
+
+ /**
+ * List of fade out configutions which should apply to this audio fade configurations
+ *
+ *<p>The list can be empty in cases where there are no fade out configurations.
+ */
+ List<FadeConfiguration> fadeOutConfigurations;
+
+ /**
+ * List of fade in configutions which should apply to this audio fade configurations
+ *
+ *<p>The list can be empty in cases where there are no fade out configurations
+ */
+ List<FadeConfiguration> fadeInConfigurations;
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioZone.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioZone.aidl
new file mode 100644
index 0000000..c90bcfd
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioZone.aidl
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+import android.hardware.automotive.audiocontrol.AudioZoneConfig;
+import android.hardware.automotive.audiocontrol.AudioZoneContext;
+import android.media.audio.common.AudioPort;
+
+/**
+ * Encapsulates the audio configurations for each audio zone
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable AudioZone {
+ /**
+ * Value indicating the primary audio zone
+ */
+ const int PRIMARY_AUDIO_ZONE = 0;
+
+ /**
+ * Value indicating the occupant zone is not assigned.
+ */
+ const int UNASSIGNED_OCCUPANT = -1;
+
+ /**
+ * Audio zone name, only use for debug purposes.
+ *
+ * <p>If present it must be non-empty otherwise car audio service will construct a name
+ * based on audio zone id.
+ */
+ String name;
+
+ /**
+ * Audio zone id use to distiguish between the different audio zones for
+ * volume management, fade, and min/max activation management.
+ */
+ int id;
+
+ /**
+ * Occupant zone id that should be mapped to this audio zone.
+ *
+ * <p>For audio zones not mapped to an occupant zone use UNASSIGNED_OCCUPANT
+ */
+ int occupantZoneId = UNASSIGNED_OCCUPANT;
+
+ /**
+ * Car audio context which can be used in the audio zone
+ */
+ AudioZoneContext audioZoneContext;
+
+ /**
+ * List of car audio configurations
+ */
+ List<AudioZoneConfig> audioZoneConfigs;
+
+ /**
+ * List of input audio devices used for this zone
+ */
+ List<AudioPort> inputAudioDevices;
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioZoneConfig.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioZoneConfig.aidl
new file mode 100644
index 0000000..6822da5
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioZoneConfig.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+import android.hardware.automotive.audiocontrol.AudioZoneFadeConfiguration;
+import android.hardware.automotive.audiocontrol.VolumeGroupConfig;
+
+/**
+ * Encapsulates the audio zone config information
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable AudioZoneConfig {
+ /**
+ * Audio zone config name
+ *
+ * <p>Must be non-empty and unique among the configurations within a zone.
+ */
+ String name;
+
+ /**
+ * Determines if the audio configuration is the default configuration.
+ *
+ * <p>There can only be a single default configuration per zone.
+ */
+ boolean isDefault;
+
+ /**
+ * List car volume group that should be managed within this configuration
+ */
+ List<VolumeGroupConfig> volumeGroups;
+
+ /**
+ * Car audio zone fade configuration
+ */
+ @nullable AudioZoneFadeConfiguration fadeConfiguration;
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioZoneContext.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioZoneContext.aidl
new file mode 100644
index 0000000..390cb09
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioZoneContext.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+import android.hardware.automotive.audiocontrol.AudioZoneContextInfo;
+
+/**
+ * Encapsulates the list of car audio context info definitions
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable AudioZoneContext {
+ /**
+ * List of car audio context info.
+ *
+ * <p>The list must include all audio attributes usages currently supported so that all audio
+ * attribute usages can be routed for each car audio configuration.
+ */
+ List<AudioZoneContextInfo> audioContextInfos;
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioZoneContextInfo.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioZoneContextInfo.aidl
new file mode 100644
index 0000000..0ca425c
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioZoneContextInfo.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+import android.media.audio.common.AudioAttributes;
+
+/**
+ * Encapsulates groups of audio attributes which should be managed together.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable AudioZoneContextInfo {
+ /**
+ * Value indicating the context info id is not assigned.
+ */
+ const int UNASSIGNED_CONTEXT_ID = -1;
+
+ /**
+ * Context name which can be used to map the info to an audio route
+ * management as described in each audio configuration.
+ *
+ * <P>Name must be non-empty and unique among all audio context info within the same
+ * {@link android.hardware.automotive.audiocontrol.AudioZoneContext} container.
+ */
+ String name;
+
+ /**
+ * Used in car audio service to manage the info
+ *
+ * <P>Must be non-negative integer if assigned, or UNASSIGNED_CONTEXT_ID otherwise. If using
+ * configurable audio policy engine audio routing with multi-zone configurations the value must
+ * be assigned.
+ */
+ int id = UNASSIGNED_CONTEXT_ID;
+
+ /**
+ * List of audio attributes that belong to the context
+ */
+ List<AudioAttributes> audioAttributes;
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioZoneFadeConfiguration.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioZoneFadeConfiguration.aidl
new file mode 100644
index 0000000..a604214
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioZoneFadeConfiguration.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+import android.hardware.automotive.audiocontrol.AudioFadeConfiguration;
+import android.hardware.automotive.audiocontrol.TransientFadeConfigurationEntry;
+
+/**
+ * Encapsulates the audio zone fade configuration
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable AudioZoneFadeConfiguration {
+ /**
+ * Defines the default fade configuration
+ */
+ AudioFadeConfiguration defaultConfiguration;
+
+ /**
+ * List of transient fade configurations.
+ *
+ * <p>The list can be empty if the fade configuration for the zone does not have transient fade
+ * configurations.
+ */
+ List<TransientFadeConfigurationEntry> transientConfiguration;
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/DeviceToContextEntry.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/DeviceToContextEntry.aidl
new file mode 100644
index 0000000..bcb5ee7
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/DeviceToContextEntry.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+import android.media.audio.common.AudioPort;
+
+/**
+ * Encapsulates the audio context that should be route to particular device
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable DeviceToContextEntry {
+ /**
+ * List of audio context names that should be routed to the audio device.
+ *
+ * <p>The names must match a {@link AudioZoneContextInfo#name} in the corresponding
+ * {@link AudioZone#audioZoneContext).
+ *
+ * <p>Within a {@link AudioZoneConfig} a context name must not repeat among the different
+ * {@link VolumeGroupConfig}. The value can repeat among different {@link AudioZoneConfig}
+ * within a {@link AudioZone}.
+ */
+ List<String> contextNames;
+
+ /**
+ * Audio port where contexts should be routed.
+ *
+ * <p>For dynamic devices (OUT_HEADSET, OUT_HEADPHONE, etc.) , the audio device address can be
+ * omitted since the information will be obtained at run time when the device is
+ * connected/enabled.
+ */
+ AudioPort device;
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/FadeConfiguration.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/FadeConfiguration.aidl
new file mode 100644
index 0000000..e700d6c
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/FadeConfiguration.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+import android.media.audio.common.AudioAttributes;
+import android.media.audio.common.AudioUsage;
+
+/**
+ * Encapsulates the in/out fade configuration
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable FadeConfiguration {
+ /**
+ * Fade duration in milliseconds
+ */
+ long fadeDurationMillis;
+
+ @JavaDerive(equals=true, toString=true)
+ @VintfStability
+ union AudioAttributesOrUsage {
+ AudioAttributes fadeAttribute;
+ AudioUsage usage;
+ }
+
+ /**
+ * Audio attribute or usage that should be impacted by the fade out duration
+ * {@code #fadeDurationMillis}
+ */
+ AudioAttributesOrUsage audioAttributesOrUsage;
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/FadeState.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/FadeState.aidl
new file mode 100644
index 0000000..346caae
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/FadeState.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+/**
+ * Encapsulates the audio fade configuration state
+ */
+@VintfStability
+@Backing(type="int")
+@JavaDerive(toString=true)
+enum FadeState {
+ /**
+ * Fade configuration should be disabled
+ */
+ FADE_STATE_DISABLED,
+ /**
+ * Fade configuration should be enabled by default
+ */
+ FADE_STATE_ENABLED_DEFAULT,
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl
index 9564efc..1202b4c 100644
--- a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl
@@ -46,14 +46,17 @@
* audio_policy_engine_configuration.xml file.
*/
import android.hardware.audio.common.PlaybackTrackMetadata;
+import android.hardware.automotive.audiocontrol.AudioDeviceConfiguration;
import android.hardware.automotive.audiocontrol.AudioFocusChange;
import android.hardware.automotive.audiocontrol.AudioGainConfigInfo;
+import android.hardware.automotive.audiocontrol.AudioZone;
import android.hardware.automotive.audiocontrol.DuckingInfo;
import android.hardware.automotive.audiocontrol.IAudioGainCallback;
import android.hardware.automotive.audiocontrol.IFocusListener;
import android.hardware.automotive.audiocontrol.IModuleChangeCallback;
import android.hardware.automotive.audiocontrol.MutingInfo;
import android.hardware.automotive.audiocontrol.Reasons;
+import android.media.audio.common.AudioPort;
/**
* Interacts with the car's audio subsystem to manage audio sources and volumes
@@ -206,4 +209,41 @@
* @throws EX_UNSUPPORTED_OPERATION if dynamic audio configs are not supported.
*/
void clearModuleChangeCallback();
+
+ /**
+ * Returns the audio device configurations that should be used to configure
+ * the car audio service audio management.
+ *
+ * <p>If this method is not supported, car audio service will attempt to configure the car audio
+ * service properties based on previously supported mechanisms.
+ *
+ * <p>If the returned value contains the
+ * {@link RoutingDeviceConfiguration#DEFAULT_AUDIO_ROUTING} value, the car audio service will
+ * attempt to configure audio routing based on the mechanism previously supported by car audio
+ * service (e.g. car audio configuration file). Otherwise, the {@link #getCarAudioZones()}
+ * API must return valid audio zone(s) configuration(s) for the device.
+ *
+ */
+ AudioDeviceConfiguration getAudioDeviceConfiguration();
+
+ /**
+ * Returns the list of audio devices that can be used for mirroring between different audio
+ * zones.
+ *
+ * @throws EX_UNSUPPORTED_OPERATION if mirroring devices are not supported.
+ */
+ List<AudioPort> getOutputMirroringDevices();
+
+ /**
+ * List of audio zones used to configure car audio service at bootup.
+ *
+ * <p>If the returned value from {@link #getAudioDeviceConfiguration()} contains
+ * {@link RoutingDeviceConfiguration#DEFAULT_AUDIO_ROUTING} value, the car audio service will
+ * attempt to configure the audio routing based on the mechanism previously supported by
+ * car audio service (e.g. car audio configuration file). Otherwise, this method must return
+ * valid audio zone(s) configuration(s) for the device.
+ *
+ * @throws EX_UNSUPPORTED_OPERATION if audio zone configuration are not supported.
+ */
+ List<AudioZone> getCarAudioZones();
}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/RoutingDeviceConfiguration.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/RoutingDeviceConfiguration.aidl
new file mode 100644
index 0000000..2d17540
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/RoutingDeviceConfiguration.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+/**
+ * Use to configure audio device routing mechanism
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+enum RoutingDeviceConfiguration {
+ /**
+ * Use to indicate that audio should be managed based on previously supportec mechamisms in
+ * car audio service.
+ *
+ * <p>If this used then the API to setup the audio zones can just throw
+ * {@code EX_UNSUPPORTED_OPERATION} if called.
+ */
+ DEFAULT_AUDIO_ROUTING,
+ /**
+ * Use to indicate that audio should be managed using the dynamic audio
+ * policy as setup by car audio service using the setup configuration from
+ * the {@Link android.hardware.automotive.audiocontrol.AudioZone}'s info from audio control HAL.
+ *
+ * <p>If this used then the APIs to setup the audio zones must return a valid audio zone
+ * configuration for the device.
+ */
+ DYNAMIC_AUDIO_ROUTING,
+ /**
+ * Use to indicate that audio should be managed using the core audio
+ * routing as setup by car audio service using the setup configuration from
+ * the {@Link android.hardware.automotive.audiocontrol.AudioZone}'s info from audio control HAL
+ * and the information contained within the configurable audio policy engine.
+ *
+ * <p>If this used then the APIs to setup the audio zone(s) must return valid audio zone
+ * configuration(s) for the device.
+ */
+ CONFIGURABLE_AUDIO_ENGINE_ROUTING,
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/TransientFadeConfigurationEntry.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/TransientFadeConfigurationEntry.aidl
new file mode 100644
index 0000000..1984236
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/TransientFadeConfigurationEntry.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+import android.hardware.automotive.audiocontrol.AudioFadeConfiguration;
+import android.media.audio.common.AudioUsage;
+
+/**
+ * Encapsulates the transient audio fade configuration entry.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable TransientFadeConfigurationEntry {
+ /**
+ * List of audio usages gainers that should be used for this configuration entry.
+ */
+ AudioUsage[] transientUsages;
+
+ /**
+ * Defines the transient fade configuration that should be used for the focus interaction with
+ * the usages defined in {@link #transientUsages}
+ */
+ AudioFadeConfiguration transientFadeConfiguration;
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/VolumeActivationConfiguration.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/VolumeActivationConfiguration.aidl
new file mode 100644
index 0000000..edc5f60
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/VolumeActivationConfiguration.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+import android.hardware.automotive.audiocontrol.VolumeActivationConfigurationEntry;
+
+/**
+ * Use to configure audio activiations, only used at boot up time.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable VolumeActivationConfiguration {
+ /**
+ * Configuration name used for debugging purposes to identify config used.
+ *
+ * <p>Is present, it must be non-empty and unique for all volume acvitations, otherwise
+ * car audio service will construct one based on audio zone, configuration and volume group
+ * info.
+ */
+ @nullable String name;
+
+ /**
+ * List of activation configurations.
+ *
+ * <P>Car audio service currently only uses the first activation config on the list.
+ */
+ List<VolumeActivationConfigurationEntry> volumeActivationEntries;
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/VolumeActivationConfigurationEntry.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/VolumeActivationConfigurationEntry.aidl
new file mode 100644
index 0000000..7072a2c
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/VolumeActivationConfigurationEntry.aidl
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+import android.hardware.automotive.audiocontrol.VolumeInvocationType;
+
+/**
+ * Audio activiation volume configuration entry.
+ *
+ * <p> The entry can defined both the minimum and maximum activation values or only one. The latter
+ * allows activations to occur only on the minimum value or maximum value as configured.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable VolumeActivationConfigurationEntry {
+ /**
+ * Default maximum activation value.
+ */
+ const int DEFAULT_MAX_ACTIVATION_VALUE = 100;
+
+ /**
+ * Default minimum activation value.
+ */
+ const int DEFAULT_MIN_ACTIVATION_VALUE = 0;
+
+ /**
+ * Activation type, should be one of:
+ * ON_PLAYBACK_CHANGED, ON_SOURCE_CHANGED, ON_BOOT
+ */
+ VolumeInvocationType type = VolumeInvocationType.ON_PLAYBACK_CHANGED;
+
+ /**
+ * Max activation percentage between {@code DEFAULT_MIN_ACTIVATION_VALUE} to
+ * {@code DEFAULT_MAX_ACTIVATION_VALUE} percen.
+ *
+ * <p>The value should be {@code DEFAULT_MAX_ACTIVATION_VALUE} if max activation should not
+ * apply.
+ */
+ int maxActivationVolumePercentage = DEFAULT_MAX_ACTIVATION_VALUE;
+
+ /**
+ * Min activation percentage between {@code DEFAULT_MIN_ACTIVATION_VALUE} to
+ * {@code DEFAULT_MAX_ACTIVATION_VALUE} percent.
+ *
+ * <p>The value should be {@code DEFAULT_MIN_ACTIVATION_VALUE} if min activation should not
+ * apply.
+ */
+ int minActivationVolumePercentage = DEFAULT_MIN_ACTIVATION_VALUE;
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/VolumeGroupConfig.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/VolumeGroupConfig.aidl
new file mode 100644
index 0000000..7e3bc60
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/VolumeGroupConfig.aidl
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+import android.hardware.automotive.audiocontrol.DeviceToContextEntry;
+import android.hardware.automotive.audiocontrol.VolumeActivationConfiguration;
+
+/**
+ * Encapsulates the audio volume grouping for audio zone config.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable VolumeGroupConfig {
+ /**
+ * Value indicating the volume group is not assigned an ID.
+ */
+ const int UNASSIGNED_ID = -1;
+
+ /**
+ * Audio zone group name.
+ *
+ * <p>Must be non-empty if using configurable audio policy engine volume management, see
+ * {@code AudioDeviceConfiguration#useCoreAudioVolume} for details.
+ */
+ String name;
+
+ /**
+ * Audio zone group id.
+ *
+ * <p>Must be set if using configurable audio policy engine volume management, can be
+ * {@code #UNASSIGNED_ID} otherwise. See {@code AudioDeviceConfiguration#useCoreAudioVolume}
+ * for details.
+ */
+ int id = UNASSIGNED_ID;
+
+ /**
+ * Entries of audio device to audio context that are managed similarly for this volume group.
+ */
+ List<DeviceToContextEntry> carAudioRoutes;
+
+ /**
+ * Optional volume activation configuration that should be used for this volume group.
+ */
+ @nullable VolumeActivationConfiguration activationConfiguration;
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/VolumeInvocationType.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/VolumeInvocationType.aidl
new file mode 100644
index 0000000..0323505
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/VolumeInvocationType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+/**
+ * Audio activiation type which can be used to activate the min/max
+ * volume changes.
+ */
+@VintfStability
+@Backing(type="int")
+@JavaDerive(toString=true)
+enum VolumeInvocationType {
+ /**
+ * Invocation of volume group activation performed at every playback change.
+ */
+ ON_PLAYBACK_CHANGED,
+ /**
+ * Invocation of volume group activation performed only once at playback after first playback
+ * for a client (app/service UID).
+ */
+ ON_SOURCE_CHANGED,
+ /**
+ * Invocation of volume group activation in perform only at playback once after boot up.
+ */
+ ON_BOOT,
+}
diff --git a/automotive/audiocontrol/aidl/default/Android.bp b/automotive/audiocontrol/aidl/default/Android.bp
index fd7e167..1c11c989 100644
--- a/automotive/audiocontrol/aidl/default/Android.bp
+++ b/automotive/audiocontrol/aidl/default/Android.bp
@@ -31,13 +31,19 @@
"latest_android_hardware_audio_common_ndk_shared",
"latest_android_hardware_automotive_audiocontrol_ndk_shared",
"powerpolicyclient_defaults",
+ "car.audio.configuration.xsd.default",
+ "car.fade.configuration.xsd.default",
],
shared_libs: [
"android.hardware.audio.common@7.0-enums",
- "libbase",
"libbinder_ndk",
"libcutils",
"liblog",
+ "libbase",
+ "libxml2",
+ "libutils",
+ "android.hardware.audiocontrol.internal",
+ "libaudio_aidl_conversion_common_ndk",
],
srcs: [
"AudioControl.cpp",
diff --git a/automotive/audiocontrol/aidl/default/AudioControl.cpp b/automotive/audiocontrol/aidl/default/AudioControl.cpp
index 7e7e145..9ae422b 100644
--- a/automotive/audiocontrol/aidl/default/AudioControl.cpp
+++ b/automotive/audiocontrol/aidl/default/AudioControl.cpp
@@ -19,6 +19,7 @@
#include "AudioControl.h"
+#include <aidl/android/hardware/automotive/audiocontrol/AudioDeviceConfiguration.h>
#include <aidl/android/hardware/automotive/audiocontrol/AudioFocusChange.h>
#include <aidl/android/hardware/automotive/audiocontrol/DuckingInfo.h>
#include <aidl/android/hardware/automotive/audiocontrol/IFocusListener.h>
@@ -27,8 +28,8 @@
#include <android-base/parsebool.h>
#include <android-base/parseint.h>
#include <android-base/strings.h>
-
#include <android_audio_policy_configuration_V7_0-enums.h>
+
#include <private/android_filesystem_config.h>
#include <numeric>
@@ -41,16 +42,18 @@
using ::android::base::ParseBool;
using ::android::base::ParseBoolResult;
using ::android::base::ParseInt;
+using ::android::hardware::audiocontrol::internal::CarAudioConfigurationXmlConverter;
using ::std::shared_ptr;
using ::std::string;
-namespace xsd {
-using namespace ::android::audio::policy::configuration::V7_0;
+namespace converter {
+using namespace ::android::hardware::audiocontrol::internal;
}
+namespace api = aidl::android::hardware::automotive::audiocontrol;
+namespace xsd = ::android::audio::policy::configuration::V7_0;
+
namespace {
-const float kLowerBound = -1.0f;
-const float kUpperBound = 1.0f;
bool checkCallerHasWritePermissions(int fd) {
// Double check that's only called by root - it should be be blocked at debug() level,
// but it doesn't hurt to make sure...
@@ -62,7 +65,7 @@
}
bool isValidValue(float value) {
- return (value >= kLowerBound) && (value <= kUpperBound);
+ return (value >= -1.0f) && (value <= 1.0f);
}
bool safelyParseInt(string s, int* out) {
@@ -71,6 +74,53 @@
}
return true;
}
+
+std::string formatDump(const std::string& input) {
+ const char kSpacer = ' ';
+ std::string output;
+ int indentLevel = 0;
+ bool newLine = false;
+
+ for (char c : input) {
+ switch (c) {
+ case '{':
+ if (!newLine) {
+ output += '\n';
+ }
+ newLine = true;
+ indentLevel++;
+ for (int i = 0; i < indentLevel; ++i) {
+ output += kSpacer;
+ }
+ break;
+ case '}':
+ if (!newLine) {
+ output += '\n';
+ }
+ newLine = true;
+ indentLevel--;
+ for (int i = 0; i < indentLevel; ++i) {
+ output += kSpacer;
+ }
+ break;
+ case ',':
+ if (!newLine) {
+ output += '\n';
+ }
+ newLine = true;
+ for (int i = 0; i < indentLevel; ++i) {
+ output += kSpacer;
+ }
+ break;
+ default:
+ newLine = false;
+ output += c;
+ }
+ }
+
+ return output;
+}
+
} // namespace
namespace {
@@ -90,6 +140,9 @@
using ::aidl::android::media::audio::common::AudioProfile;
using ::aidl::android::media::audio::common::PcmType;
+const static std::string kAudioConfigFile = "/vendor/etc/car_audio_configuration.xml";
+const static std::string kFadeConfigFile = "/vendor/etc/car_audio_fade_configuration.xml";
+
// reuse common code artifacts
void fillProfile(const std::vector<int32_t>& channelLayouts,
const std::vector<int32_t>& sampleRates, AudioProfile* profile) {
@@ -162,6 +215,12 @@
}
} // namespace
+AudioControl::AudioControl() : AudioControl(kAudioConfigFile, kFadeConfigFile) {}
+
+AudioControl::AudioControl(const std::string& carAudioConfig, const std::string& audioFadeConfig)
+ : mCarAudioConfigurationConverter(std::make_shared<CarAudioConfigurationXmlConverter>(
+ carAudioConfig, audioFadeConfig)) {}
+
ndk::ScopedAStatus AudioControl::registerFocusListener(
const shared_ptr<IFocusListener>& in_listener) {
LOG(DEBUG) << "registering focus listener";
@@ -245,14 +304,23 @@
static inline std::string toString(const std::vector<aidl_type>& in_values) {
return std::accumulate(std::begin(in_values), std::end(in_values), std::string{},
[](const std::string& ls, const aidl_type& rs) {
- return ls + (ls.empty() ? "" : ",") + rs.toString();
+ return ls + (ls.empty() ? "" : ", ") + rs.toString();
});
}
template <typename aidl_enum_type>
static inline std::string toEnumString(const std::vector<aidl_enum_type>& in_values) {
return std::accumulate(std::begin(in_values), std::end(in_values), std::string{},
[](const std::string& ls, const aidl_enum_type& rs) {
- return ls + (ls.empty() ? "" : ",") + toString(rs);
+ return ls + (ls.empty() ? "" : ", ") + toString(rs);
+ });
+}
+
+template <typename aidl_type>
+static inline std::string toString(const std::vector<std::optional<aidl_type>>& in_values) {
+ return std::accumulate(std::begin(in_values), std::end(in_values), std::string{},
+ [](const std::string& ls, const std::optional<aidl_type>& rs) {
+ return ls + (ls.empty() ? "" : ", ") +
+ (rs.has_value() ? rs.value().toString() : "empty");
});
}
@@ -309,6 +377,50 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus AudioControl::getAudioDeviceConfiguration(
+ AudioDeviceConfiguration* audioDeviceConfig) {
+ if (!audioDeviceConfig) {
+ LOG(ERROR) << __func__ << "Audio device configuration must not be null";
+ return ndk::ScopedAStatus::fromStatus(STATUS_UNEXPECTED_NULL);
+ }
+ if (!mCarAudioConfigurationConverter) {
+ return ndk::ScopedAStatus::ok();
+ }
+ const auto& innerDeviceConfig = mCarAudioConfigurationConverter->getAudioDeviceConfiguration();
+ audioDeviceConfig->routingConfig = innerDeviceConfig.routingConfig;
+ audioDeviceConfig->useCoreAudioVolume = innerDeviceConfig.useCoreAudioVolume;
+ audioDeviceConfig->useCarVolumeGroupMuting = innerDeviceConfig.useCarVolumeGroupMuting;
+ audioDeviceConfig->useHalDuckingSignals = innerDeviceConfig.useHalDuckingSignals;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AudioControl::getOutputMirroringDevices(
+ std::vector<AudioPort>* mirroringDevices) {
+ if (!mirroringDevices) {
+ LOG(ERROR) << __func__ << "Mirroring devices must not be null";
+ return ndk::ScopedAStatus::fromStatus(STATUS_UNEXPECTED_NULL);
+ }
+ if (!mCarAudioConfigurationConverter || !mCarAudioConfigurationConverter->getErrors().empty()) {
+ return ndk::ScopedAStatus::ok();
+ }
+ const auto& innerDevice = mCarAudioConfigurationConverter->getOutputMirroringDevices();
+ mirroringDevices->insert(mirroringDevices->end(), innerDevice.begin(), innerDevice.end());
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AudioControl::getCarAudioZones(std::vector<AudioZone>* audioZones) {
+ if (!audioZones) {
+ LOG(ERROR) << __func__ << "Audio zones must not be null";
+ return ndk::ScopedAStatus::fromStatus(STATUS_UNEXPECTED_NULL);
+ }
+ if (!mCarAudioConfigurationConverter || !mCarAudioConfigurationConverter->getErrors().empty()) {
+ return ndk::ScopedAStatus::ok();
+ }
+ const auto& innerZones = mCarAudioConfigurationConverter->getAudioZones();
+ audioZones->insert(audioZones->end(), innerZones.begin(), innerZones.end());
+ return ndk::ScopedAStatus::ok();
+}
+
binder_status_t AudioControl::dump(int fd, const char** args, uint32_t numArgs) {
if (numArgs == 0) {
return dumpsys(fd);
@@ -342,6 +454,25 @@
dprintf(fd, "Focus listener registered\n");
}
dprintf(fd, "AudioGainCallback %sregistered\n", (mAudioGainCallback == nullptr ? "NOT " : ""));
+
+ AudioDeviceConfiguration configuration;
+ if (getAudioDeviceConfiguration(&configuration).isOk()) {
+ dprintf(fd, "AudioDeviceConfiguration: %s\n", configuration.toString().c_str());
+ }
+ std::vector<AudioZone> audioZones;
+ if (getCarAudioZones(&audioZones).isOk()) {
+ dprintf(fd, "Audio zones count: %zu\n", audioZones.size());
+ for (const auto& zone : audioZones) {
+ dprintf(fd, "AudioZone: %s\n", formatDump(zone.toString()).c_str());
+ }
+ }
+ std::vector<AudioPort> mirroringDevices;
+ if (getOutputMirroringDevices(&mirroringDevices).isOk()) {
+ dprintf(fd, "Mirroring devices count: %zu\n", mirroringDevices.size());
+ for (const auto& device : mirroringDevices) {
+ dprintf(fd, "Mirroring device: %s\n", formatDump(device.toString()).c_str());
+ }
+ }
return STATUS_OK;
}
diff --git a/automotive/audiocontrol/aidl/default/AudioControl.h b/automotive/audiocontrol/aidl/default/AudioControl.h
index 7eca446..0425570 100644
--- a/automotive/audiocontrol/aidl/default/AudioControl.h
+++ b/automotive/audiocontrol/aidl/default/AudioControl.h
@@ -35,13 +35,17 @@
#include <aidl/android/media/audio/common/AudioIoFlags.h>
#include <aidl/android/media/audio/common/AudioOutputFlags.h>
+#include "converter/include/CarAudioConfigurationXmlConverter.h"
+
namespace aidl::android::hardware::automotive::audiocontrol {
-namespace audiohalcommon = ::aidl::android::hardware::audio::common;
namespace audiomediacommon = ::aidl::android::media::audio::common;
+namespace audiohalcommon = ::aidl::android::hardware::audio::common;
class AudioControl : public BnAudioControl {
public:
+ AudioControl();
+ AudioControl(const std::string& carAudioConfig, const std::string& audioFadeConfig);
ndk::ScopedAStatus onAudioFocusChange(const std::string& in_usage, int32_t in_zoneId,
AudioFocusChange in_focusChange) override;
ndk::ScopedAStatus onDevicesToDuckChange(
@@ -63,6 +67,11 @@
ndk::ScopedAStatus setModuleChangeCallback(
const std::shared_ptr<IModuleChangeCallback>& in_callback) override;
ndk::ScopedAStatus clearModuleChangeCallback() override;
+ ndk::ScopedAStatus getAudioDeviceConfiguration(
+ AudioDeviceConfiguration* audioDeviceConfig) override;
+ ndk::ScopedAStatus getOutputMirroringDevices(
+ std::vector<::aidl::android::media::audio::common::AudioPort>* mirrorDevices) override;
+ ndk::ScopedAStatus getCarAudioZones(std::vector<AudioZone>* audioZones) override;
binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
@@ -81,6 +90,9 @@
std::shared_ptr<IModuleChangeCallback> mModuleChangeCallback = nullptr;
+ std::shared_ptr<::android::hardware::audiocontrol::internal::CarAudioConfigurationXmlConverter>
+ mCarAudioConfigurationConverter = nullptr;
+
binder_status_t cmdHelp(int fd) const;
binder_status_t cmdRequestFocus(int fd, const char** args, uint32_t numArgs);
binder_status_t cmdAbandonFocus(int fd, const char** args, uint32_t numArgs);
diff --git a/automotive/audiocontrol/aidl/default/audiocontrol-default.xml b/automotive/audiocontrol/aidl/default/audiocontrol-default.xml
index bcb5669..ffef7fc 100644
--- a/automotive/audiocontrol/aidl/default/audiocontrol-default.xml
+++ b/automotive/audiocontrol/aidl/default/audiocontrol-default.xml
@@ -1,7 +1,7 @@
<manifest version="2.0" type="device">
<hal format="aidl">
<name>android.hardware.automotive.audiocontrol</name>
- <version>4</version>
+ <version>5</version>
<fqname>IAudioControl/default</fqname>
</hal>
</manifest>
diff --git a/automotive/audiocontrol/aidl/default/converter/Android.bp b/automotive/audiocontrol/aidl/default/converter/Android.bp
new file mode 100644
index 0000000..c00afa2
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/converter/Android.bp
@@ -0,0 +1,56 @@
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_library {
+ name: "android.hardware.audiocontrol.internal",
+ vendor: true,
+ srcs: [
+ "src/CarAudioConfigurationXmlConverter.cpp",
+ "src/CarAudioConfigurationUtils.cpp",
+ ],
+ export_include_dirs: [
+ "include",
+ ],
+ defaults: [
+ "latest_android_hardware_audio_common_ndk_static",
+ "latest_android_hardware_automotive_audiocontrol_ndk_shared",
+ "car.audio.configuration.xsd.default",
+ "car.fade.configuration.xsd.default",
+ "aidlaudioservice_defaults",
+ "latest_android_media_audio_common_types_ndk_static",
+ ],
+ shared_libs: [
+ "libbase",
+ "libutils",
+ "libmedia_helper",
+ "car.audio.configuration.xsd.default",
+ "car.fade.configuration.xsd.default",
+ "liblog",
+ ],
+ static_libs: [
+ "libaudio_aidl_conversion_common_ndk_cpp",
+ ],
+ header_libs: [
+ "libaudio_system_headers",
+ ],
+}
diff --git a/automotive/audiocontrol/aidl/default/converter/include/CarAudioConfigurationUtils.h b/automotive/audiocontrol/aidl/default/converter/include/CarAudioConfigurationUtils.h
new file mode 100644
index 0000000..29fec0b
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/converter/include/CarAudioConfigurationUtils.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_AUDIOCONTROL_INTERNAL_CONFIGURATION_UTILS_H
+#define ANDROID_HARDWARE_AUDIOCONTROL_INTERNAL_CONFIGURATION_UTILS_H
+
+#include <string>
+
+#include <aidl/android/hardware/automotive/audiocontrol/AudioZoneContext.h>
+#include <aidl/android/hardware/automotive/audiocontrol/AudioZoneContextInfo.h>
+
+namespace android {
+namespace hardware {
+namespace audiocontrol {
+namespace internal {
+
+::aidl::android::hardware::automotive::audiocontrol::AudioZoneContext getDefaultCarAudioContext();
+
+} // namespace internal
+} // namespace audiocontrol
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_AUDIOCONTROL_INTERNAL_CONFIGURATION_UTILS_H
diff --git a/automotive/audiocontrol/aidl/default/converter/include/CarAudioConfigurationXmlConverter.h b/automotive/audiocontrol/aidl/default/converter/include/CarAudioConfigurationXmlConverter.h
new file mode 100644
index 0000000..ed29172
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/converter/include/CarAudioConfigurationXmlConverter.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MAIN8_CARAUDIOCONFIGURATIONXMLCONVERTER_H
+#define MAIN8_CARAUDIOCONFIGURATIONXMLCONVERTER_H
+
+#include <string>
+
+#include "../include/CarAudioConfigurationUtils.h"
+
+#include <aidl/android/hardware/automotive/audiocontrol/AudioDeviceConfiguration.h>
+#include <aidl/android/hardware/automotive/audiocontrol/AudioZone.h>
+#include <aidl/android/hardware/automotive/audiocontrol/AudioZoneContext.h>
+
+namespace android::hardware::automotive::audiocontrol {
+class CarAudioConfigurationType;
+}
+
+namespace android {
+namespace hardware {
+namespace audiocontrol {
+namespace internal {
+
+class CarAudioConfigurationXmlConverter {
+ public:
+ explicit CarAudioConfigurationXmlConverter(const std::string& audioConfigFile,
+ const std::string& fadeConfigFile)
+ : mAudioConfigFile(audioConfigFile), mFadeConfigFile(fadeConfigFile) {
+ init();
+ }
+
+ ::aidl::android::hardware::automotive::audiocontrol::AudioDeviceConfiguration
+ getAudioDeviceConfiguration() const;
+
+ std::vector<::aidl::android::hardware::automotive::audiocontrol::AudioZone> getAudioZones()
+ const;
+ std::vector<::aidl::android::media::audio::common::AudioPort> getOutputMirroringDevices() const;
+
+ const std::string getErrors() const { return mParseErrors; }
+
+ private:
+ void init();
+ void initNonDynamicRouting();
+ void initFadeConfigurations();
+ void initAudioDeviceConfiguration(
+ const ::android::hardware::automotive::audiocontrol::CarAudioConfigurationType&
+ carAudioConfigurationType);
+ void initCarAudioConfigurations(
+ const ::android::hardware::automotive::audiocontrol::CarAudioConfigurationType&
+ carAudioConfigurationType);
+ void parseAudioDeviceConfigurations(
+ const ::android::hardware::automotive::audiocontrol::CarAudioConfigurationType&
+ carAudioConfigurationType);
+
+ const std::string mAudioConfigFile;
+ const std::string mFadeConfigFile;
+ ::aidl::android::hardware::automotive::audiocontrol::AudioDeviceConfiguration
+ mAudioDeviceConfiguration;
+ std::optional<::aidl::android::hardware::automotive::audiocontrol::AudioZoneContext>
+ mAudioZoneContext;
+ std::vector<::aidl::android::hardware::automotive::audiocontrol::AudioZone> mAudioZones;
+ std::vector<::aidl::android::media::audio::common::AudioPort> mOutputMirroringDevices;
+ std::string mParseErrors;
+ std::unordered_map<std::string,
+ ::aidl::android::hardware::automotive::audiocontrol::AudioFadeConfiguration>
+ mFadeConfigurations;
+};
+
+} // namespace internal
+} // namespace audiocontrol
+} // namespace hardware
+} // namespace android
+
+#endif // MAIN8_CARAUDIOCONFIGURATIONXMLCONVERTER_H
diff --git a/automotive/audiocontrol/aidl/default/converter/src/CarAudioConfigurationUtils.cpp b/automotive/audiocontrol/aidl/default/converter/src/CarAudioConfigurationUtils.cpp
new file mode 100644
index 0000000..e2f8191
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/converter/src/CarAudioConfigurationUtils.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+
+#include "../include/CarAudioConfigurationUtils.h"
+
+#include <aidl/android/media/audio/common/AudioAttributes.h>
+#include <aidl/android/media/audio/common/AudioUsage.h>
+
+#include <tuple>
+#include <vector>
+
+using ::aidl::android::hardware::automotive::audiocontrol::AudioZoneContext;
+using ::aidl::android::hardware::automotive::audiocontrol::AudioZoneContextInfo;
+
+using aidl::android::media::audio::common::AudioAttributes;
+using aidl::android::media::audio::common::AudioUsage;
+using aidl::android::media::audio::common::AudioUsage::ALARM;
+using aidl::android::media::audio::common::AudioUsage::ANNOUNCEMENT;
+using aidl::android::media::audio::common::AudioUsage::ASSISTANCE_ACCESSIBILITY;
+using aidl::android::media::audio::common::AudioUsage::ASSISTANCE_NAVIGATION_GUIDANCE;
+using aidl::android::media::audio::common::AudioUsage::ASSISTANCE_SONIFICATION;
+using aidl::android::media::audio::common::AudioUsage::ASSISTANT;
+using aidl::android::media::audio::common::AudioUsage::CALL_ASSISTANT;
+using aidl::android::media::audio::common::AudioUsage::EMERGENCY;
+using aidl::android::media::audio::common::AudioUsage::GAME;
+using aidl::android::media::audio::common::AudioUsage::MEDIA;
+using aidl::android::media::audio::common::AudioUsage::NOTIFICATION;
+using aidl::android::media::audio::common::AudioUsage::NOTIFICATION_EVENT;
+using aidl::android::media::audio::common::AudioUsage::NOTIFICATION_TELEPHONY_RINGTONE;
+using aidl::android::media::audio::common::AudioUsage::SAFETY;
+using aidl::android::media::audio::common::AudioUsage::UNKNOWN;
+using aidl::android::media::audio::common::AudioUsage::VEHICLE_STATUS;
+using aidl::android::media::audio::common::AudioUsage::VOICE_COMMUNICATION;
+using aidl::android::media::audio::common::AudioUsage::VOICE_COMMUNICATION_SIGNALLING;
+
+namespace android {
+namespace hardware {
+namespace audiocontrol {
+namespace internal {
+
+std::vector<AudioAttributes> createAudioAttributes(const std::vector<AudioUsage>& usages) {
+ std::vector<AudioAttributes> audioAttributes;
+ for (const auto& usage : usages) {
+ AudioAttributes attributes;
+ attributes.usage = usage;
+ audioAttributes.push_back(attributes);
+ }
+ return audioAttributes;
+}
+
+AudioZoneContextInfo createAudioZoneContextInfo(const std::string& name, int id,
+ const std::vector<AudioUsage>& usages) {
+ AudioZoneContextInfo info;
+ info.name = name;
+ info.id = id;
+ info.audioAttributes = createAudioAttributes(usages);
+ return info;
+}
+
+AudioZoneContext createAudioZoneContextInfo(const std::vector<AudioZoneContextInfo>& info) {
+ AudioZoneContext context;
+ context.audioContextInfos.insert(context.audioContextInfos.begin(), info.begin(), info.end());
+ return context;
+}
+
+AudioZoneContext getDefaultCarAudioContext() {
+ // For legacy reasons, context names are lower case here.
+ static const AudioZoneContext kDefaultContext = createAudioZoneContextInfo(
+ {createAudioZoneContextInfo("music", 1, {UNKNOWN, MEDIA, GAME}),
+ createAudioZoneContextInfo("navigation", 2, {ASSISTANCE_NAVIGATION_GUIDANCE}),
+ createAudioZoneContextInfo("voice_command", 3, {ASSISTANCE_ACCESSIBILITY, ASSISTANT}),
+ createAudioZoneContextInfo("call_ring", 4, {NOTIFICATION_TELEPHONY_RINGTONE}),
+ createAudioZoneContextInfo(
+ "call", 5,
+ {VOICE_COMMUNICATION, CALL_ASSISTANT, VOICE_COMMUNICATION_SIGNALLING}),
+ createAudioZoneContextInfo("alarm", 6, {ALARM}),
+ createAudioZoneContextInfo("notification", 7, {NOTIFICATION, NOTIFICATION_EVENT}),
+ createAudioZoneContextInfo("system_sound", 8, {ASSISTANCE_SONIFICATION}),
+ createAudioZoneContextInfo("emergency", 9, {EMERGENCY}),
+ createAudioZoneContextInfo("safety", 10, {SAFETY}),
+ createAudioZoneContextInfo("vehicle_status", 11, {VEHICLE_STATUS}),
+ createAudioZoneContextInfo("announcement", 12, {ANNOUNCEMENT})});
+ return kDefaultContext;
+}
+
+} // namespace internal
+} // namespace audiocontrol
+} // namespace hardware
+} // namespace android
diff --git a/automotive/audiocontrol/aidl/default/converter/src/CarAudioConfigurationXmlConverter.cpp b/automotive/audiocontrol/aidl/default/converter/src/CarAudioConfigurationXmlConverter.cpp
new file mode 100644
index 0000000..d43b595
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/converter/src/CarAudioConfigurationXmlConverter.cpp
@@ -0,0 +1,1134 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AudioControl::XSD_Converter"
+
+#define LOG_NDEBUG 0
+#include <android-base/logging.h>
+
+#include "../include/CarAudioConfigurationXmlConverter.h"
+
+#include <aidl/android/hardware/automotive/audiocontrol/RoutingDeviceConfiguration.h>
+#include <android-base/parsebool.h>
+#include <android_hardware_automotive_audiocontrol.h>
+#include <android_hardware_automotive_audiocontrol_fade.h>
+
+#include <android-base/parseint.h>
+#include <android-base/strings.h>
+#include <media/AidlConversionCppNdk.h>
+#include <media/TypeConverter.h>
+#include <media/convert.h>
+#include <system/audio.h>
+#include <unistd.h>
+#include <unordered_map>
+
+namespace android {
+namespace hardware {
+namespace audiocontrol {
+namespace internal {
+namespace xsd = ::android::hardware::automotive::audiocontrol;
+namespace fade = android::hardware::automotive::audiocontrol::fade;
+namespace api = ::aidl::android::hardware::automotive::audiocontrol;
+
+using aidl::android::media::audio::common::AudioAttributes;
+using aidl::android::media::audio::common::AudioContentType;
+using aidl::android::media::audio::common::AudioDevice;
+using aidl::android::media::audio::common::AudioDeviceAddress;
+using aidl::android::media::audio::common::AudioDeviceDescription;
+using aidl::android::media::audio::common::AudioDeviceType;
+using aidl::android::media::audio::common::AudioPort;
+using aidl::android::media::audio::common::AudioPortDeviceExt;
+using aidl::android::media::audio::common::AudioPortExt;
+using aidl::android::media::audio::common::AudioUsage;
+
+using namespace ::android::base;
+
+namespace {
+
+static const std::string kUseCoreRouting{"useCoreAudioRouting"};
+static const std::string kUseCoreVolume{"useCoreAudioVolume"};
+static const std::string kUseHalDuckingSignals{"useHalDuckingSignals"};
+static const std::string kUseCarVolumeGroupMuting{"useCarVolumeGroupMuting"};
+
+static constexpr char kOutBusType[] = "AUDIO_DEVICE_OUT_BUS";
+static constexpr char kInBusType[] = "AUDIO_DEVICE_IN_BUS";
+
+using ActivationMap = std::unordered_map<std::string, api::VolumeActivationConfiguration>;
+using FadeConfigurationMap = std::unordered_map<
+ std::string, ::aidl::android::hardware::automotive::audiocontrol::AudioFadeConfiguration>;
+
+inline bool isReadableConfigurationFile(const std::string& filePath) {
+ return !filePath.empty() && filePath.ends_with(".xml") && (access(filePath.c_str(), R_OK) == 0);
+}
+
+inline bool parseBoolOrDefaultIfFailed(const std::string& value, bool defaultValue) {
+ ParseBoolResult results = ParseBool(value);
+ return results == ParseBoolResult::kError ? defaultValue : results == ParseBoolResult::kTrue;
+}
+
+void parseCoreRoutingInfo(const std::string& value, api::AudioDeviceConfiguration& config) {
+ if (!parseBoolOrDefaultIfFailed(value, /* defaultValue= */ false)) {
+ return;
+ }
+ config.routingConfig = api::RoutingDeviceConfiguration::CONFIGURABLE_AUDIO_ENGINE_ROUTING;
+}
+
+void parseCoreVolumeInfo(const std::string& value, api::AudioDeviceConfiguration& config) {
+ config.useCoreAudioVolume = parseBoolOrDefaultIfFailed(value, config.useCoreAudioVolume);
+}
+
+void parseHalDuckingInfo(const std::string& value, api::AudioDeviceConfiguration& config) {
+ config.useHalDuckingSignals = parseBoolOrDefaultIfFailed(value, config.useHalDuckingSignals);
+}
+
+void parseHalMutingInfo(const std::string& value, api::AudioDeviceConfiguration& config) {
+ config.useCarVolumeGroupMuting =
+ parseBoolOrDefaultIfFailed(value, config.useCarVolumeGroupMuting);
+}
+
+bool parseAudioAttributeUsageString(const std::string& usageString, AudioUsage& usage) {
+ audio_usage_t legacyUsage;
+ if (!::android::UsageTypeConverter::fromString(usageString, legacyUsage)) {
+ LOG(ERROR) << __func__ << " could not parse usage from string " << usageString;
+ return false;
+ }
+ ConversionResult<AudioUsage> result =
+ ::aidl::android::legacy2aidl_audio_usage_t_AudioUsage(legacyUsage);
+ if (!result.ok()) {
+ LOG(ERROR) << __func__ << " could not parse usage legacy type " << legacyUsage;
+ return false;
+ }
+ usage = result.value();
+ return true;
+}
+
+bool parseAudioAttributeUsage(const xsd::UsageType& usageType, AudioAttributes& attributes) {
+ if (!usageType.hasValue()) {
+ LOG(ERROR) << __func__ << " usage does not have value";
+ return false;
+ }
+ if (!parseAudioAttributeUsageString(xsd::toString(usageType.getValue()), attributes.usage)) {
+ return false;
+ }
+ return true;
+}
+
+bool parseAudioAttributesUsages(const std::vector<xsd::UsageType>& usages,
+ std::vector<AudioAttributes>& audioAttributes) {
+ for (const auto& xsdUsage : usages) {
+ AudioAttributes attributes;
+ if (!parseAudioAttributeUsage(xsdUsage, attributes)) {
+ return false;
+ }
+ audioAttributes.push_back(attributes);
+ }
+ return true;
+}
+
+bool parseContentTypeString(const std::string& typeString, AudioContentType& type) {
+ audio_content_type_t legacyContentType;
+ if (!::android::AudioContentTypeConverter::fromString(typeString, legacyContentType)) {
+ LOG(ERROR) << __func__ << " could not parse content type from string " << typeString;
+ return false;
+ }
+ ConversionResult<AudioContentType> result =
+ ::aidl::android::legacy2aidl_audio_content_type_t_AudioContentType(legacyContentType);
+ if (!result.ok()) {
+ LOG(ERROR) << __func__ << " could not convert legacy content type " << legacyContentType;
+ return false;
+ }
+ type = result.value();
+ return true;
+}
+
+bool parseAudioAttribute(const xsd::AttributesType& attributesType, AudioAttributes& attributes) {
+ if (attributesType.hasUsage()) {
+ if (!parseAudioAttributeUsageString(xsd::toString(attributesType.getUsage()),
+ attributes.usage)) {
+ LOG(ERROR) << __func__ << " could not parse audio usage: "
+ << xsd::toString(attributesType.getUsage());
+ return false;
+ }
+ }
+
+ if (attributesType.hasContentType()) {
+ if (!parseContentTypeString(xsd::toString(attributesType.getContentType()),
+ attributes.contentType)) {
+ return false;
+ }
+ }
+
+ if (attributesType.hasTags()) {
+ attributes.tags.push_back(attributesType.getTags());
+ }
+ return true;
+}
+
+bool parseAudioAttributes(const std::vector<xsd::AttributesType>& xsdAttributes,
+ std::vector<AudioAttributes>& audioAttributes) {
+ for (const auto& xsdAttribute : xsdAttributes) {
+ AudioAttributes attribute;
+ if (!parseAudioAttribute(xsdAttribute, attribute)) {
+ return false;
+ }
+ audioAttributes.push_back(attribute);
+ }
+ return true;
+}
+
+bool parseAudioAttributes(const xsd::AudioAttributesUsagesType& xsdAttributeOrUsages,
+ std::vector<AudioAttributes>& audioAttributes) {
+ if (xsdAttributeOrUsages.hasUsage_optional()) {
+ if (!parseAudioAttributesUsages(xsdAttributeOrUsages.getUsage_optional(),
+ audioAttributes)) {
+ LOG(ERROR) << __func__ << " could not parse audio usages";
+ return false;
+ }
+ }
+
+ if (xsdAttributeOrUsages.hasAudioAttribute_optional()) {
+ if (!parseAudioAttributes(xsdAttributeOrUsages.getAudioAttribute_optional(),
+ audioAttributes)) {
+ LOG(ERROR) << __func__ << " could not parse audio attributes";
+ return false;
+ }
+ }
+ return true;
+}
+
+bool parseAudioContext(const xsd::OemContextType& xsdContextInfo,
+ api::AudioZoneContextInfo& contextInfo) {
+ if (!xsdContextInfo.hasName()) {
+ LOG(ERROR) << __func__ << " Audio context info missing name";
+ return false;
+ }
+
+ contextInfo.name = xsdContextInfo.getName();
+
+ if (xsdContextInfo.hasId()) {
+ ParseInt(xsdContextInfo.getId().c_str(), &contextInfo.id);
+ }
+
+ if (xsdContextInfo.hasAudioAttributes()) {
+ if (!parseAudioAttributes(*xsdContextInfo.getFirstAudioAttributes(),
+ contextInfo.audioAttributes)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool parseAudioContexts(const xsd::OemContextsType* xsdContexts, api::AudioZoneContext& context) {
+ if (!xsdContexts->hasOemContext()) {
+ return false;
+ }
+ const auto xsdContextInfos = xsdContexts->getOemContext();
+ for (const auto& xsdContextInfo : xsdContextInfos) {
+ api::AudioZoneContextInfo info;
+ if (!parseAudioContext(xsdContextInfo, info)) {
+ continue;
+ }
+ context.audioContextInfos.push_back(info);
+ }
+ return true;
+}
+
+bool createAudioDevice(const std::string& address, const std::string& type, AudioPort& port) {
+ audio_devices_t legacyDeviceType = AUDIO_DEVICE_NONE;
+ ::android::DeviceConverter::fromString(type, legacyDeviceType);
+ std::string tempString;
+ ::android::DeviceConverter::toString(legacyDeviceType, tempString);
+ ConversionResult<AudioDeviceDescription> result =
+ ::aidl::android::legacy2aidl_audio_devices_t_AudioDeviceDescription(legacyDeviceType);
+ if (legacyDeviceType == AUDIO_DEVICE_NONE || !result.ok()) {
+ LOG(ERROR) << __func__ << " could not parse legacy device type";
+ return false;
+ }
+ AudioDevice device;
+ if (!address.empty()) {
+ device.address = AudioDeviceAddress::make<AudioDeviceAddress::Tag::id>(address);
+ }
+ device.type = result.value();
+
+ port.ext = AudioPortExt::make<AudioPortExt::Tag::device>(device);
+
+ return true;
+}
+
+std::string outTypeToOutAudioDevice(const std::string& device) {
+ const static std::unordered_map<std::string, std::string> typeToOutDevice{
+ {"TYPE_BUILTIN_SPEAKER", "AUDIO_DEVICE_OUT_SPEAKER"},
+ {"TYPE_WIRED_HEADSET", "AUDIO_DEVICE_OUT_WIRED_HEADSET"},
+ {"TYPE_WIRED_HEADPHONES", "AUDIO_DEVICE_OUT_WIRED_HEADPHONE,"},
+ {"TYPE_BLUETOOTH_A2DP", "AUDIO_DEVICE_OUT_BLUETOOTH_A2DP"},
+ {"TYPE_HDMI", "AUDIO_DEVICE_OUT_HDMI"},
+ {"TYPE_USB_ACCESSORY", "AUDIO_DEVICE_OUT_USB_ACCESSORY"},
+ {"TYPE_USB_DEVICE", "AUDIO_DEVICE_OUT_USB_DEVICE,"},
+ {"TYPE_USB_HEADSET", "AUDIO_DEVICE_OUT_USB_HEADSET"},
+ {"TYPE_AUX_LINE", "AUDIO_DEVICE_OUT_AUX_LINE"},
+ {"TYPE_BUS", "AUDIO_DEVICE_OUT_BUS"},
+ {"TYPE_BLE_HEADSET", "AUDIO_DEVICE_OUT_BLE_HEADSET"},
+ {"TYPE_BLE_SPEAKER", "AUDIO_DEVICE_OUT_BLE_SPEAKER"},
+ {"TYPE_BLE_BROADCAST", "AUDIO_DEVICE_OUT_BLE_BROADCAST"},
+ };
+
+ if (!device.starts_with("TYPE_")) {
+ return device;
+ }
+
+ const auto it = typeToOutDevice.find(device);
+ return it != typeToOutDevice.end() ? it->second : device;
+}
+
+bool parseAudioDeviceToContexts(const xsd::DeviceRoutesType& deviceRoutesType,
+ api::DeviceToContextEntry& route) {
+ std::string address = deviceRoutesType.hasAddress() ? deviceRoutesType.getAddress() : "";
+ // Default type is bus for schema
+ std::string type = outTypeToOutAudioDevice(deviceRoutesType.hasType()
+ ? xsd::toString(deviceRoutesType.getType())
+ : std::string(kOutBusType));
+ // Address must be present for audio device bus
+ if (address.empty() && type == std::string(kOutBusType)) {
+ LOG(ERROR) << __func__ << " empty device address for bus device type";
+ return false;
+ }
+ if (!createAudioDevice(address, type, route.device)) {
+ return false;
+ }
+
+ if (!deviceRoutesType.hasContext()) {
+ LOG(ERROR) << __func__ << " empty device context mapping";
+ return false;
+ }
+
+ for (const auto& xsdContext : deviceRoutesType.getContext()) {
+ if (!xsdContext.hasContext()) {
+ LOG(ERROR) << __func__ << " audio device route missing context info";
+ return false;
+ }
+ route.contextNames.push_back(xsdContext.getContext());
+ }
+
+ return true;
+}
+
+bool parseAudioDeviceRoutes(const std::vector<xsd::DeviceRoutesType> deviceRoutesTypes,
+ std::vector<api::DeviceToContextEntry>& routes) {
+ for (const auto& deviceRouteType : deviceRoutesTypes) {
+ api::DeviceToContextEntry entry;
+ if (!parseAudioDeviceToContexts(deviceRouteType, entry)) {
+ return false;
+ }
+ routes.push_back(entry);
+ }
+ return true;
+}
+
+void parseVolumeGroupActivation(const std::string& activationConfigName,
+ const ActivationMap& activations,
+ api::VolumeGroupConfig& volumeGroup) {
+ if (activationConfigName.empty()) {
+ LOG(ERROR) << __func__ << " Volume group " << volumeGroup.name
+ << " has empty volume group activation name";
+ return;
+ }
+ const auto& it = activations.find(activationConfigName);
+ if (it == activations.end()) {
+ LOG(ERROR) << __func__ << " Volume group " << volumeGroup.name
+ << " has non-existing volume group activation name " << activationConfigName;
+ return;
+ }
+ volumeGroup.activationConfiguration = it->second;
+}
+
+bool parseVolumeGroup(const xsd::VolumeGroupType& volumeGroupType, const ActivationMap& activations,
+ api::VolumeGroupConfig& volumeGroup) {
+ if (!volumeGroupType.hasDevice()) {
+ LOG(ERROR) << __func__ << " no device found";
+ return false;
+ }
+
+ if (volumeGroupType.hasName()) {
+ volumeGroup.name = volumeGroupType.getName();
+ }
+
+ if (!parseAudioDeviceRoutes(volumeGroupType.getDevice(), volumeGroup.carAudioRoutes)) {
+ return false;
+ }
+
+ if (volumeGroupType.hasActivationConfig()) {
+ parseVolumeGroupActivation(volumeGroupType.getActivationConfig(), activations, volumeGroup);
+ }
+
+ return true;
+}
+
+bool parseVolumeGroups(const xsd::VolumeGroupsType* volumeGroupsType,
+ const ActivationMap& activations,
+ std::vector<api::VolumeGroupConfig>& volumeGroups) {
+ if (!volumeGroupsType->hasGroup()) {
+ LOG(ERROR) << __func__ << " no volume groups found";
+ return false;
+ }
+ for (const auto& volumeGroupType : volumeGroupsType->getGroup()) {
+ api::VolumeGroupConfig volumeGroup;
+ if (!parseVolumeGroup(volumeGroupType, activations, volumeGroup)) {
+ return false;
+ }
+ volumeGroups.push_back(volumeGroup);
+ }
+ return true;
+}
+
+void parseFadeConfigurationUsages(const xsd::ApplyFadeConfigType& fadeConfigType,
+ std::vector<AudioUsage>& usages) {
+ if (!fadeConfigType.hasAudioAttributes()) {
+ return;
+ }
+ const xsd::AudioAttributeUsagesType* attributesOrUsagesType =
+ fadeConfigType.getFirstAudioAttributes();
+ if (!attributesOrUsagesType->hasUsage()) {
+ return;
+ }
+ for (const auto& usageType : attributesOrUsagesType->getUsage()) {
+ AudioUsage usage;
+ if (!usageType.hasValue() ||
+ !parseAudioAttributeUsageString(xsd::toString(usageType.getValue()), usage)) {
+ continue;
+ }
+ usages.push_back(usage);
+ }
+}
+
+void parseZoneFadeConfiguration(const xsd::ApplyFadeConfigType& fadeConfigType,
+ const FadeConfigurationMap& fadeConfigurations,
+ api::AudioZoneFadeConfiguration& zoneFadeConfiguration) {
+ if (!fadeConfigType.hasName()) {
+ LOG(ERROR) << __func__ << " Found a fade config without a name, skipping assignment";
+ return;
+ }
+
+ const auto it = fadeConfigurations.find(fadeConfigType.getName());
+ if (it == fadeConfigurations.end()) {
+ LOG(ERROR) << __func__ << " Config name " << fadeConfigType.getName()
+ << " not found, skipping assignment";
+ return;
+ }
+ // Return for default since default configurations do not have any audio attributes mapping
+ if (fadeConfigType.hasIsDefault()) {
+ zoneFadeConfiguration.defaultConfiguration = it->second;
+ return;
+ }
+
+ api::TransientFadeConfigurationEntry entry;
+ entry.transientFadeConfiguration = it->second;
+ parseFadeConfigurationUsages(fadeConfigType, entry.transientUsages);
+ zoneFadeConfiguration.transientConfiguration.push_back(entry);
+}
+
+void parseZoneFadeConfigurations(const xsd::ZoneConfigType& zoneConfigType,
+ const FadeConfigurationMap& fadeConfigurations,
+ std::optional<api::AudioZoneFadeConfiguration>& zoneFadeConfig) {
+ if (!zoneConfigType.hasApplyFadeConfigs()) {
+ return;
+ }
+ const xsd::ApplyFadeConfigsType* applyFadeConfigs = zoneConfigType.getFirstApplyFadeConfigs();
+ if (!applyFadeConfigs->hasFadeConfig()) {
+ return;
+ }
+ api::AudioZoneFadeConfiguration zoneFadeConfiguration;
+ for (const auto& fadeConfigType : applyFadeConfigs->getFadeConfig()) {
+ parseZoneFadeConfiguration(fadeConfigType, fadeConfigurations, zoneFadeConfiguration);
+ }
+ zoneFadeConfig = zoneFadeConfiguration;
+}
+
+bool parseAudioZoneConfig(const xsd::ZoneConfigType& zoneConfigType,
+ const ActivationMap& activations,
+ const FadeConfigurationMap& fadeConfigurations,
+ api::AudioZoneConfig& config) {
+ if (!zoneConfigType.hasVolumeGroups()) {
+ LOG(ERROR) << __func__ << " no volume groups found";
+ return false;
+ }
+
+ if (zoneConfigType.hasName()) {
+ config.name = zoneConfigType.getName();
+ }
+ if (!parseVolumeGroups(zoneConfigType.getFirstVolumeGroups(), activations,
+ config.volumeGroups)) {
+ return false;
+ }
+
+ parseZoneFadeConfigurations(zoneConfigType, fadeConfigurations, config.fadeConfiguration);
+
+ config.isDefault = zoneConfigType.hasIsDefault() && zoneConfigType.getIsDefault();
+
+ return true;
+}
+
+bool parseAudioZoneConfigs(const xsd::ZoneConfigsType* zoneConfigsType,
+ const ActivationMap& activations,
+ const FadeConfigurationMap& fadeConfigurations,
+ std::vector<api::AudioZoneConfig>& configs) {
+ if (!zoneConfigsType->hasZoneConfig()) {
+ LOG(ERROR) << __func__ << " No zone configs found";
+ return false;
+ }
+
+ if (zoneConfigsType->getZoneConfig().empty()) {
+ LOG(ERROR) << __func__ << " Empty list of audio configurations";
+ return false;
+ }
+
+ for (const auto& zoneConfigType : zoneConfigsType->getZoneConfig()) {
+ api::AudioZoneConfig config;
+ if (!parseAudioZoneConfig(zoneConfigType, activations, fadeConfigurations, config)) {
+ return false;
+ }
+ configs.push_back(config);
+ }
+
+ return true;
+}
+
+bool parseInputDevice(const xsd::InputDeviceType& xsdInputDevice, AudioPort& inputDevice) {
+ // Input device must have a non-empty address
+ if (!xsdInputDevice.hasAddress() || xsdInputDevice.getAddress().empty()) {
+ LOG(ERROR) << __func__ << " missing device address";
+ return false;
+ }
+ // By default a device is bus type, unless specified
+ std::string inputDeviceType =
+ xsdInputDevice.hasType() ? xsd::toString(xsdInputDevice.getType()) : kInBusType;
+ if (!createAudioDevice(xsdInputDevice.getAddress(), inputDeviceType, inputDevice)) {
+ return false;
+ }
+ return true;
+}
+
+void parseInputDevices(const xsd::InputDevicesType* xsdInputDevices,
+ std::vector<AudioPort>& inputDevices) {
+ if (!xsdInputDevices->hasInputDevice()) {
+ return;
+ }
+ for (const auto& xsdInputDevice : xsdInputDevices->getInputDevice()) {
+ AudioPort inputDevice;
+ if (!parseInputDevice(xsdInputDevice, inputDevice)) {
+ continue;
+ }
+ inputDevices.push_back(inputDevice);
+ }
+}
+
+bool parseAudioZone(const xsd::ZoneType& zone, const ActivationMap& activations,
+ const FadeConfigurationMap& fadeConfigurations, api::AudioZone& audioZone) {
+ if (zone.hasName()) {
+ audioZone.name = zone.getName();
+ }
+
+ if (zone.hasOccupantZoneId()) {
+ ParseInt(zone.getOccupantZoneId().c_str(), &audioZone.occupantZoneId);
+ }
+
+ if (zone.hasInputDevices()) {
+ parseInputDevices(zone.getFirstInputDevices(), audioZone.inputAudioDevices);
+ }
+
+ // Audio zone id is required
+ if (!zone.hasAudioZoneId()) {
+ LOG(ERROR) << __func__ << " Audio zone id required for each zone";
+ return false;
+ }
+
+ bool isPrimary = zone.hasIsPrimary() && zone.getIsPrimary();
+
+ if (isPrimary) {
+ audioZone.id = api::AudioZone::PRIMARY_AUDIO_ZONE;
+ }
+
+ // ID not required in XML for primary zone
+ if (!ParseInt(zone.getAudioZoneId().c_str(), &audioZone.id) && !isPrimary) {
+ LOG(ERROR) << __func__
+ << " Could not parse audio zone id, must be a non-negative integer or isPrimary "
+ "must be specify as true for primary zone";
+ return false;
+ }
+
+ if (isPrimary && audioZone.id != api::AudioZone::PRIMARY_AUDIO_ZONE) {
+ LOG(ERROR) << __func__ << " Audio zone is primary but has zone id "
+ << std::to_string(audioZone.id) << " instead of primary zone id "
+ << std::to_string(api::AudioZone::PRIMARY_AUDIO_ZONE);
+ return false;
+ }
+
+ if (!zone.hasZoneConfigs()) {
+ LOG(ERROR) << __func__ << " Missing audio zone configs for audio zone id " << audioZone.id;
+ return false;
+ }
+ if (!parseAudioZoneConfigs(zone.getFirstZoneConfigs(), activations, fadeConfigurations,
+ audioZone.audioZoneConfigs)) {
+ LOG(ERROR) << __func__ << " Could not parse zone configs for audio zone id " << audioZone.id
+ << ", name " << audioZone.name;
+ return false;
+ }
+
+ return true;
+}
+
+std::string parseAudioZones(const xsd::ZonesType* zones, const api::AudioZoneContext& context,
+ const ActivationMap& activations,
+ const FadeConfigurationMap& fadeConfigurations,
+ std::vector<api::AudioZone>& audioZones) {
+ if (!zones->hasZone()) {
+ return "audio zones are missing";
+ }
+ const auto& xsdZones = zones->getZone();
+ for (const auto& xsdZone : xsdZones) {
+ api::AudioZone audioZone;
+ audioZone.audioZoneContext = context;
+ if (!parseAudioZone(xsdZone, activations, fadeConfigurations, audioZone)) {
+ continue;
+ }
+ audioZones.push_back(audioZone);
+ }
+ return "";
+}
+
+std::unordered_map<std::string,
+ std::function<void(const std::string&, api::AudioDeviceConfiguration&)>>
+getConfigsParsers() {
+ static const std::unordered_map<
+ std::string, std::function<void(const std::string&, api::AudioDeviceConfiguration&)>>
+ parsers{
+ {kUseCoreRouting, parseCoreRoutingInfo},
+ {kUseCoreVolume, parseCoreVolumeInfo},
+ {kUseHalDuckingSignals, parseHalDuckingInfo},
+ {kUseCarVolumeGroupMuting, parseHalMutingInfo},
+ };
+
+ return parsers;
+}
+
+bool parseVolumeActivationType(const xsd::ActivationType& xsdType,
+ api::VolumeInvocationType& activationType) {
+ switch (xsdType) {
+ case xsd::ActivationType::onBoot:
+ activationType = api::VolumeInvocationType::ON_BOOT;
+ break;
+ case xsd::ActivationType::onSourceChanged:
+ activationType = api::VolumeInvocationType::ON_SOURCE_CHANGED;
+ break;
+ case xsd::ActivationType::onPlaybackChanged:
+ activationType = api::VolumeInvocationType::ON_PLAYBACK_CHANGED;
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+
+bool parseVolumeGroupActivationEntry(const xsd::ActivationVolumeConfigEntryType& xsdEntry,
+ api::VolumeActivationConfigurationEntry& entry) {
+ if (!xsdEntry.hasInvocationType()) {
+ LOG(ERROR) << __func__ << " Activation config entry missing invocation type";
+ return false;
+ }
+
+ if (!parseVolumeActivationType(xsdEntry.getInvocationType(), entry.type)) {
+ LOG(ERROR) << __func__ << " Could not parse configuration entry type";
+ return false;
+ }
+
+ if (xsdEntry.hasMaxActivationVolumePercentage()) {
+ // Parse int ranges are not inclusive
+ ParseInt(xsdEntry.getMaxActivationVolumePercentage().c_str(),
+ &entry.maxActivationVolumePercentage,
+ api::VolumeActivationConfigurationEntry::DEFAULT_MIN_ACTIVATION_VALUE - 1,
+ api::VolumeActivationConfigurationEntry::DEFAULT_MAX_ACTIVATION_VALUE + 1);
+ }
+
+ if (xsdEntry.hasMinActivationVolumePercentage()) {
+ // Parse int ranges are not inclusive
+ ParseInt(xsdEntry.getMinActivationVolumePercentage().c_str(),
+ &entry.minActivationVolumePercentage,
+ api::VolumeActivationConfigurationEntry::DEFAULT_MIN_ACTIVATION_VALUE - 1,
+ api::VolumeActivationConfigurationEntry::DEFAULT_MAX_ACTIVATION_VALUE + 1);
+ }
+
+ return true;
+}
+
+bool parseVolumeGroupActivationEntries(
+ const std::vector<xsd::ActivationVolumeConfigEntryType>& xsdEntries,
+ std::vector<api::VolumeActivationConfigurationEntry>& entries) {
+ for (const auto& xsdEntry : xsdEntries) {
+ api::VolumeActivationConfigurationEntry entry;
+ if (!parseVolumeGroupActivationEntry(xsdEntry, entry)) {
+ LOG(ERROR) << __func__ << " Could not parse volume group activation entries";
+ return false;
+ }
+ entries.push_back(entry);
+ }
+ return true;
+}
+
+bool parseVolumeGroupActivation(const xsd::ActivationVolumeConfigType& xsdActivationConfig,
+ api::VolumeActivationConfiguration& activation) {
+ if (!xsdActivationConfig.hasName()) {
+ LOG(ERROR) << __func__ << " Activation config missing volume activation name";
+ return false;
+ }
+ if (!xsdActivationConfig.hasActivationVolumeConfigEntry()) {
+ LOG(ERROR) << __func__ << " Activation config missing volume activation entries";
+ return false;
+ }
+ if (!parseVolumeGroupActivationEntries(xsdActivationConfig.getActivationVolumeConfigEntry(),
+ activation.volumeActivationEntries)) {
+ LOG(ERROR) << __func__ << " Could not parse volume activation name";
+ return false;
+ }
+ activation.name = xsdActivationConfig.getName();
+ return true;
+}
+
+void parseVolumeGroupActivations(const xsd::ActivationVolumeConfigsType* xsdActivationConfigs,
+ ActivationMap& activations) {
+ if (!xsdActivationConfigs->hasActivationVolumeConfig()) {
+ LOG(ERROR) << __func__ << " No volume group activations found";
+ return;
+ }
+ for (const auto& xsdActivationConfig : xsdActivationConfigs->getActivationVolumeConfig()) {
+ api::VolumeActivationConfiguration activationConfiguration;
+ if (!parseVolumeGroupActivation(xsdActivationConfig, activationConfiguration)) {
+ continue;
+ }
+ std::string name = xsdActivationConfig.getName();
+ activations.emplace(name, activationConfiguration);
+ }
+}
+
+void parseOutputMirroringDevices(const xsd::MirroringDevicesType* mirroringDevicesType,
+ std::vector<AudioPort>& mirroringDevices) {
+ if (!mirroringDevicesType->hasMirroringDevice()) {
+ LOG(ERROR) << __func__ << " Missing audio mirroring devices";
+ return;
+ }
+ for (const auto& xsdMirrorDevice : mirroringDevicesType->getMirroringDevice()) {
+ AudioPort mirrorDevicePort;
+ if (!xsdMirrorDevice.hasAddress()) {
+ LOG(ERROR) << __func__ << " Missing audio mirroring device address";
+ continue;
+ }
+ if (!createAudioDevice(xsdMirrorDevice.getAddress(), kOutBusType, mirrorDevicePort)) {
+ LOG(ERROR) << __func__ << " Could not create mirror device with address "
+ << xsdMirrorDevice.getAddress();
+ continue;
+ }
+ mirroringDevices.push_back(mirrorDevicePort);
+ }
+}
+
+api::FadeState getFadeState(const fade::FadeStateType& xsdFadeState) {
+ // Return default value if missing
+ if (!xsdFadeState.hasValue()) {
+ return api::FadeState::FADE_STATE_ENABLED_DEFAULT;
+ }
+ // For legacy files, "0" and "1 " need to be supported.
+ switch (xsdFadeState.getValue()) {
+ case fade::FadeStateEnumType::_0:
+ // Fallthrough
+ case fade::FadeStateEnumType::FADE_STATE_DISABLED:
+ return api::FadeState::FADE_STATE_DISABLED;
+ case fade::FadeStateEnumType::_1:
+ // Fallthrough
+ case fade::FadeStateEnumType::FADE_STATE_ENABLED_DEFAULT:
+ // Fallthrough
+ default:
+ return api::FadeState::FADE_STATE_ENABLED_DEFAULT;
+ }
+}
+
+void parseFadeableUsages(const fade::FadeableUsagesType& fadeUsages,
+ std::vector<AudioUsage>& usages) {
+ if (!fadeUsages.hasUsage()) {
+ return;
+ }
+ for (const auto& fadeUsage : fadeUsages.getUsage()) {
+ AudioUsage audioUsage;
+ if (!fadeUsage.hasValue() ||
+ !parseAudioAttributeUsageString(fade::toString(fadeUsage.getValue()), audioUsage)) {
+ continue;
+ }
+ usages.push_back(audioUsage);
+ }
+}
+
+void parseFadeAudioAttribute(const fade::AttributesType& fadeAttributes,
+ AudioAttributes& attributes) {
+ if (fadeAttributes.hasUsage()) {
+ parseAudioAttributeUsageString(fade::toString(fadeAttributes.getUsage()), attributes.usage);
+ }
+ if (fadeAttributes.hasContentType()) {
+ parseContentTypeString(fade::toString(fadeAttributes.getContentType()),
+ attributes.contentType);
+ }
+ if (fadeAttributes.hasTags()) {
+ attributes.tags.push_back(fadeAttributes.getTags());
+ }
+}
+
+bool parseFadeAudioAttribute(const fade::AudioAttributesUsagesType& fadeAttributes,
+ std::vector<AudioAttributes>& audioAttributes) {
+ if (fadeAttributes.hasUsage_optional()) {
+ for (const auto& usage : fadeAttributes.getUsage_optional()) {
+ AudioAttributes attributes;
+ if (!usage.hasValue() || !parseAudioAttributeUsageString(
+ fade::toString(usage.getValue()), attributes.usage)) {
+ continue;
+ }
+ audioAttributes.push_back(attributes);
+ }
+ }
+ if (fadeAttributes.hasAudioAttribute_optional()) {
+ for (const auto& fadeAttribute : fadeAttributes.getAudioAttribute_optional()) {
+ AudioAttributes attribute;
+ parseFadeAudioAttribute(fadeAttribute, attribute);
+ audioAttributes.push_back(attribute);
+ }
+ }
+ return true;
+}
+
+void parseUnfadeableAudioAttributes(const fade::UnfadeableAudioAttributesType& fadeAttributes,
+ std::vector<AudioAttributes>& audioAttributes) {
+ if (!fadeAttributes.hasAudioAttributes()) {
+ return;
+ }
+ parseFadeAudioAttribute(*fadeAttributes.getFirstAudioAttributes(), audioAttributes);
+}
+
+void parseUnfadeableContentType(const fade::UnfadeableContentTypesType& fadeTypes,
+ std::optional<std::vector<AudioContentType>>& contentTypes) {
+ if (!fadeTypes.hasContentType()) {
+ return;
+ }
+ std::vector<AudioContentType> contents;
+ for (const auto& fadeContentType : fadeTypes.getContentType()) {
+ AudioContentType contentType;
+ if (!fadeContentType.hasValue() ||
+ !parseContentTypeString(fade::toString(fadeContentType.getValue()), contentType)) {
+ continue;
+ }
+ contents.push_back(contentType);
+ }
+ contentTypes = contents;
+}
+
+void parseFadeConfigAudioAttributes(const fade::AudioAttributesUsagesType& fadeAudioAttributesType,
+ const int64_t fadeDurationMillins,
+ std::vector<api::FadeConfiguration>& fadeInConfigurations) {
+ if (fadeAudioAttributesType.hasAudioAttribute_optional()) {
+ for (const auto& fadeAudioAttribute :
+ fadeAudioAttributesType.getAudioAttribute_optional()) {
+ api::FadeConfiguration fadeConfiguration;
+ AudioAttributes attributes;
+ parseFadeAudioAttribute(fadeAudioAttribute, attributes);
+ fadeConfiguration.fadeDurationMillis = fadeDurationMillins;
+ fadeConfiguration.audioAttributesOrUsage
+ .set<api::FadeConfiguration::AudioAttributesOrUsage::fadeAttribute>(attributes);
+ fadeInConfigurations.push_back(fadeConfiguration);
+ }
+ }
+
+ if (fadeAudioAttributesType.hasUsage_optional()) {
+ for (const auto& fadeAudioUsage : fadeAudioAttributesType.getUsage_optional()) {
+ api::FadeConfiguration fadeConfiguration;
+ AudioUsage usage;
+ if (!fadeAudioUsage.hasValue() ||
+ !parseAudioAttributeUsageString(fade::toString(fadeAudioUsage.getValue()), usage)) {
+ continue;
+ }
+ fadeConfiguration.fadeDurationMillis = fadeDurationMillins;
+ fadeConfiguration.audioAttributesOrUsage
+ .set<api::FadeConfiguration::AudioAttributesOrUsage::usage>(usage);
+ fadeInConfigurations.push_back(fadeConfiguration);
+ }
+ }
+}
+void parseFadeConfiguration(const fade::FadeConfigurationType& fadeConfigurationType,
+ std::vector<api::FadeConfiguration>& fadeConfigurations) {
+ if (!fadeConfigurationType.hasFadeDurationMillis() ||
+ !fadeConfigurationType.hasAudioAttributes() ||
+ fadeConfigurationType.getAudioAttributes().empty()) {
+ return;
+ }
+
+ int64_t fadeDurationMillis = 0L;
+
+ if (!ParseInt(fadeConfigurationType.getFadeDurationMillis().c_str(), &fadeDurationMillis,
+ static_cast<int64_t>(0))) {
+ return;
+ }
+ parseFadeConfigAudioAttributes(*fadeConfigurationType.getFirstAudioAttributes(),
+ fadeDurationMillis, fadeConfigurations);
+}
+
+void parseFadeInConfigurations(const fade::FadeInConfigurationsType& fadeInConfigurationsType,
+ std::vector<api::FadeConfiguration>& fadeInConfigurations) {
+ if (!fadeInConfigurationsType.hasFadeConfiguration()) {
+ return;
+ }
+ for (const auto& fadeConfigurationType : fadeInConfigurationsType.getFadeConfiguration()) {
+ parseFadeConfiguration(fadeConfigurationType, fadeInConfigurations);
+ }
+}
+
+void parseFadeOutConfigurations(const fade::FadeOutConfigurationsType& fadeOutConfigurationsType,
+ std::vector<api::FadeConfiguration>& fadeOutConfigurations) {
+ if (!fadeOutConfigurationsType.hasFadeConfiguration()) {
+ return;
+ }
+ for (const auto& fadeConfigurationType : fadeOutConfigurationsType.getFadeConfiguration()) {
+ parseFadeConfiguration(fadeConfigurationType, fadeOutConfigurations);
+ }
+}
+
+bool parseFadeConfig(const fade::FadeConfigurationConfig& fadeConfig,
+ api::AudioFadeConfiguration& configuration) {
+ // Fade configuration must have a name for zone association. Fade state is also needed to
+ // determine accurate usage.
+ if (!fadeConfig.hasName()) {
+ LOG(ERROR) << __func__ << " Fade configuration missing name";
+ return false;
+ }
+ if (!fadeConfig.hasFadeState()) {
+ LOG(ERROR) << __func__ << " Fade configuration missing fade state";
+ return false;
+ }
+ configuration.name = fadeConfig.getName();
+ configuration.fadeState = getFadeState(*fadeConfig.getFirstFadeState());
+ if (fadeConfig.hasDefaultFadeOutDurationInMillis()) {
+ ParseInt(fadeConfig.getDefaultFadeOutDurationInMillis().c_str(),
+ &configuration.fadeOutDurationMs, static_cast<int64_t>(0));
+ }
+ if (fadeConfig.hasDefaultFadeInDurationInMillis()) {
+ ParseInt(fadeConfig.getDefaultFadeInDurationInMillis().c_str(),
+ &configuration.fadeInDurationMs, static_cast<int64_t>(0));
+ }
+ if (fadeConfig.hasDefaultFadeInDelayForOffenders()) {
+ ParseInt(fadeConfig.getDefaultFadeInDelayForOffenders().c_str(),
+ &configuration.fadeInDelayedForOffendersMs, static_cast<int64_t>(0));
+ }
+
+ if (fadeConfig.hasFadeableUsages()) {
+ parseFadeableUsages(*fadeConfig.getFirstFadeableUsages(), configuration.fadeableUsages);
+ }
+
+ if (fadeConfig.hasUnfadeableContentTypes()) {
+ parseUnfadeableContentType(*fadeConfig.getFirstUnfadeableContentTypes(),
+ configuration.unfadeableContentTypes);
+ }
+
+ if (fadeConfig.hasUnfadeableAudioAttributes()) {
+ parseUnfadeableAudioAttributes(*fadeConfig.getFirstUnfadeableAudioAttributes(),
+ configuration.unfadableAudioAttributes);
+ }
+ if (fadeConfig.hasFadeInConfigurations()) {
+ parseFadeInConfigurations(*fadeConfig.getFirstFadeInConfigurations(),
+ configuration.fadeInConfigurations);
+ }
+ if (fadeConfig.hasFadeOutConfigurations()) {
+ parseFadeOutConfigurations(*fadeConfig.getFirstFadeOutConfigurations(),
+ configuration.fadeOutConfigurations);
+ }
+
+ return true;
+}
+
+void parseFadeConfigs(const std::vector<fade::FadeConfigurationConfig>& fadeConfigTypes,
+ std::vector<api::AudioFadeConfiguration>& fadeConfigs) {
+ for (const auto& fadeConfig : fadeConfigTypes) {
+ api::AudioFadeConfiguration configuration;
+ if (!parseFadeConfig(fadeConfig, configuration)) {
+ continue;
+ }
+ fadeConfigs.push_back(configuration);
+ }
+}
+
+void parseFadeConfigs(const fade::FadeConfigurationConfigs& fadeConfigsType,
+ std::vector<api::AudioFadeConfiguration>& fadeConfigs) {
+ if (!fadeConfigsType.hasConfig()) {
+ LOG(ERROR) << __func__ << " Fade config file does not contains any fade configs";
+ return;
+ }
+ parseFadeConfigs(fadeConfigsType.getConfig(), fadeConfigs);
+}
+} // namespace
+
+void CarAudioConfigurationXmlConverter::init() {
+ if (!isReadableConfigurationFile(mAudioConfigFile)) {
+ mParseErrors = "Configuration file " + mAudioConfigFile + " is not readable";
+ initNonDynamicRouting();
+ return;
+ }
+
+ // Supports loading legacy fade configurations from a different file
+ if (isReadableConfigurationFile(mFadeConfigFile)) {
+ initFadeConfigurations();
+ }
+
+ const auto& configOptional = xsd::read(mAudioConfigFile.c_str());
+
+ if (!configOptional.has_value()) {
+ mParseErrors =
+ "Configuration file " + mAudioConfigFile + " , does not have any configurations";
+ initNonDynamicRouting();
+ return;
+ }
+
+ const auto& configurations = configOptional.value();
+ initAudioDeviceConfiguration(configurations);
+ initCarAudioConfigurations(configurations);
+}
+
+void CarAudioConfigurationXmlConverter::initFadeConfigurations() {
+ const auto& fadeConfigOptional = fade::read(mFadeConfigFile.c_str());
+ if (!fadeConfigOptional.has_value() || !fadeConfigOptional.value().hasConfigs()) {
+ LOG(ERROR) << __func__ << " Fade config file " << mFadeConfigFile.c_str()
+ << " does not contains fade configuration";
+ return;
+ }
+
+ const auto& fadeConfigs = fadeConfigOptional.value().getConfigs();
+
+ if (fadeConfigs.empty()) {
+ LOG(ERROR) << __func__ << " Fade config file " << mFadeConfigFile.c_str()
+ << " does not contains fade configs";
+ }
+ std::vector<api::AudioFadeConfiguration> fadeConfigurations;
+ parseFadeConfigs(fadeConfigs.front(), fadeConfigurations);
+ for (const auto& fadeConfiguration : fadeConfigurations) {
+ mFadeConfigurations.emplace(fadeConfiguration.name, fadeConfiguration);
+ }
+}
+
+void CarAudioConfigurationXmlConverter::initNonDynamicRouting() {
+ mAudioDeviceConfiguration.routingConfig =
+ api::RoutingDeviceConfiguration::DEFAULT_AUDIO_ROUTING;
+}
+
+void CarAudioConfigurationXmlConverter::initAudioDeviceConfiguration(
+ const xsd::CarAudioConfigurationType& carAudioConfigurationType) {
+ parseAudioDeviceConfigurations(carAudioConfigurationType);
+}
+
+void CarAudioConfigurationXmlConverter::parseAudioDeviceConfigurations(
+ const xsd::CarAudioConfigurationType& carAudioConfigurationType) {
+ if (!carAudioConfigurationType.hasDeviceConfigurations()) {
+ return;
+ }
+
+ mAudioDeviceConfiguration.routingConfig =
+ api::RoutingDeviceConfiguration::DYNAMIC_AUDIO_ROUTING;
+
+ const auto deviceConfigs = carAudioConfigurationType.getFirstDeviceConfigurations();
+ if (!deviceConfigs->hasDeviceConfiguration()) {
+ return;
+ }
+
+ std::vector<::android::hardware::automotive::audiocontrol::DeviceConfigurationType> configs =
+ deviceConfigs->getDeviceConfiguration();
+ const auto& parsers = getConfigsParsers();
+ for (const auto& deviceConfig : configs) {
+ if (!deviceConfig.hasName() || !deviceConfig.hasValue()) {
+ continue;
+ }
+ const auto& parser = parsers.find(deviceConfig.getName());
+ if (parser == parsers.end()) {
+ continue;
+ }
+ const auto& method = parser->second;
+ method(deviceConfig.getValue(), mAudioDeviceConfiguration);
+ }
+}
+
+void CarAudioConfigurationXmlConverter::initCarAudioConfigurations(
+ const automotive::audiocontrol::CarAudioConfigurationType& carAudioConfigurationType) {
+ if (!carAudioConfigurationType.hasZones()) {
+ mParseErrors = "Audio zones not found in file " + mAudioConfigFile;
+ initNonDynamicRouting();
+ return;
+ }
+
+ api::AudioZoneContext context;
+ if (!carAudioConfigurationType.hasOemContexts() ||
+ !parseAudioContexts(carAudioConfigurationType.getFirstOemContexts(), context)) {
+ context = getDefaultCarAudioContext();
+ }
+
+ ActivationMap activations;
+ if (carAudioConfigurationType.hasActivationVolumeConfigs()) {
+ parseVolumeGroupActivations(carAudioConfigurationType.getFirstActivationVolumeConfigs(),
+ activations);
+ }
+
+ if (carAudioConfigurationType.hasMirroringDevices()) {
+ parseOutputMirroringDevices(carAudioConfigurationType.getFirstMirroringDevices(),
+ mOutputMirroringDevices);
+ }
+
+ const auto audioZones = carAudioConfigurationType.getFirstZones();
+
+ std::string message =
+ parseAudioZones(audioZones, context, activations, mFadeConfigurations, mAudioZones);
+
+ // Assign dynamic configuration if not assigned
+ if (!mAudioZones.empty() && mAudioDeviceConfiguration.routingConfig ==
+ api::RoutingDeviceConfiguration::DEFAULT_AUDIO_ROUTING) {
+ mAudioDeviceConfiguration.routingConfig =
+ api::RoutingDeviceConfiguration::DYNAMIC_AUDIO_ROUTING;
+ }
+
+ if (message.empty()) {
+ return;
+ }
+ mParseErrors =
+ "Error parsing audio zone(s) in file " + mAudioConfigFile + ", message: " + message;
+ LOG(ERROR) << __func__ << " Error parsing zones: " << message;
+ initNonDynamicRouting();
+}
+
+api::AudioDeviceConfiguration CarAudioConfigurationXmlConverter::getAudioDeviceConfiguration()
+ const {
+ return mAudioDeviceConfiguration;
+}
+
+std::vector<api::AudioZone> CarAudioConfigurationXmlConverter::getAudioZones() const {
+ return mAudioZones;
+}
+
+std::vector<::aidl::android::media::audio::common::AudioPort>
+CarAudioConfigurationXmlConverter::getOutputMirroringDevices() const {
+ return mOutputMirroringDevices;
+}
+
+} // namespace internal
+} // namespace audiocontrol
+} // namespace hardware
+} // namespace android
\ No newline at end of file
diff --git a/automotive/audiocontrol/aidl/default/converter/test/Android.bp b/automotive/audiocontrol/aidl/default/converter/test/Android.bp
new file mode 100644
index 0000000..70d4a20
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/converter/test/Android.bp
@@ -0,0 +1,63 @@
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ default_team: "trendy_team_aaos_framework",
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+filegroup {
+ name: "simple_car_audio_configuration_xml",
+ srcs: [
+ "simple_car_audio_configuration.xml",
+ "simple_car_audio_configuration_with_device_type.xml",
+ "multi_zone_car_audio_configuration.xml",
+ "car_audio_configuration_without_configuration.xml",
+ "car_audio_configuration_with_default_context.xml",
+ "car_audio_configuration_with_missing_zones.xml",
+ "car_audio_configuration_without_audio_zone.xml",
+ "car_audio_fade_configuration.xml",
+ ],
+}
+
+cc_test {
+ name: "AudioControlConverterUnitTest",
+ vendor: true,
+ require_root: true,
+ srcs: ["*.cpp"],
+ stl: "libc++_static",
+ static_libs: [
+ "libbase",
+ "android.hardware.audiocontrol.internal",
+ "libgtest",
+ "libgmock",
+ "libutils",
+ "libaudio_aidl_conversion_common_ndk",
+ ],
+ shared_libs: ["liblog"],
+ defaults: [
+ "latest_android_hardware_audio_common_ndk_static",
+ "car.audio.configuration.xsd.default",
+ "car.fade.configuration.xsd.default",
+ "latest_android_hardware_automotive_audiocontrol_ndk_static",
+ "latest_android_media_audio_common_types_ndk_static",
+ ],
+ data: [
+ ":simple_car_audio_configuration_xml",
+ ],
+ test_suites: ["device-tests"],
+ exclude_shared_libs: [
+ "android.hardware.automotive.audiocontrol-V5-ndk",
+ ],
+}
diff --git a/automotive/audiocontrol/aidl/default/converter/test/AudioControlConverterUnitTest.cpp b/automotive/audiocontrol/aidl/default/converter/test/AudioControlConverterUnitTest.cpp
new file mode 100644
index 0000000..b6bebe5
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/converter/test/AudioControlConverterUnitTest.cpp
@@ -0,0 +1,834 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/file.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include <CarAudioConfigurationXmlConverter.h>
+#include <aidl/android/hardware/automotive/audiocontrol/AudioDeviceConfiguration.h>
+
+namespace converter = ::android::hardware::audiocontrol::internal;
+namespace api = ::aidl::android::hardware::automotive::audiocontrol;
+
+using ::testing::ContainsRegex;
+using ::testing::UnorderedElementsAreArray;
+
+namespace {
+
+using ::aidl::android::media::audio::common::AudioAttributes;
+using ::aidl::android::media::audio::common::AudioContentType;
+using ::aidl::android::media::audio::common::AudioDevice;
+using ::aidl::android::media::audio::common::AudioDeviceAddress;
+using ::aidl::android::media::audio::common::AudioDeviceDescription;
+using ::aidl::android::media::audio::common::AudioDeviceType;
+using ::aidl::android::media::audio::common::AudioPort;
+using ::aidl::android::media::audio::common::AudioPortDeviceExt;
+using ::aidl::android::media::audio::common::AudioPortExt;
+using ::aidl::android::media::audio::common::AudioUsage;
+
+std::string getTestFilePath(const std::string& filename) {
+ static std::string baseDir = android::base::GetExecutableDirectory();
+ return baseDir + "/" + filename;
+}
+
+AudioAttributes createAudioAttributes(const AudioUsage& usage,
+ const AudioContentType& type = AudioContentType::UNKNOWN,
+ const std::string tags = "") {
+ AudioAttributes attributes;
+ attributes.usage = usage;
+ attributes.contentType = type;
+ if (!tags.empty()) {
+ attributes.tags.push_back(tags);
+ }
+ return attributes;
+}
+
+api::AudioZoneContextInfo createContextInfo(const std::string& name,
+ const std::vector<AudioAttributes>& attributes,
+ const int id = -1) {
+ api::AudioZoneContextInfo info;
+ info.name = name;
+ if (id != -1) {
+ info.id = id;
+ }
+ for (const auto& attribute : attributes) {
+ info.audioAttributes.push_back(attribute);
+ }
+ return info;
+}
+
+api::AudioZoneContextInfo createContextInfo(const std::string& name,
+ const std::vector<AudioUsage>& usages,
+ const int id = -1) {
+ std::vector<AudioAttributes> attributes;
+ attributes.reserve(usages.size());
+ for (const auto& usage : usages) {
+ attributes.push_back(createAudioAttributes(usage));
+ }
+ return createContextInfo(name, attributes, id);
+}
+
+AudioPort createAudioPort(const std::string& address, const AudioDeviceType& type,
+ const std::string& connection = "") {
+ AudioPort port;
+ AudioDevice device;
+ device.address = AudioDeviceAddress::make<AudioDeviceAddress::Tag::id>(address);
+
+ AudioDeviceDescription description;
+ description.type = type;
+ description.connection = connection;
+ device.type = description;
+
+ port.ext = AudioPortExt::make<AudioPortExt::Tag::device>(device);
+
+ return port;
+}
+
+api::DeviceToContextEntry createRoutes(const AudioPort& port,
+ const std::vector<std::string>& contexts) {
+ api::DeviceToContextEntry entry;
+ entry.device = port;
+ entry.contextNames = contexts;
+ return entry;
+}
+
+api::VolumeGroupConfig createVolumeGroup(const std::string& name,
+ const api::VolumeActivationConfiguration& activation,
+ const std::vector<api::DeviceToContextEntry>& routes) {
+ api::VolumeGroupConfig config;
+ config.name = name;
+ config.activationConfiguration = activation;
+ config.carAudioRoutes = routes;
+ return config;
+}
+
+api::AudioZoneConfig createAudioZoneConfig(const std::string& name,
+ const api::AudioZoneFadeConfiguration& fadeConfiguration,
+ const std::vector<api::VolumeGroupConfig>& groups,
+ bool isDefault = false) {
+ api::AudioZoneConfig config;
+ config.name = name;
+ config.isDefault = isDefault;
+ config.volumeGroups = groups;
+ config.fadeConfiguration = fadeConfiguration;
+ return config;
+}
+
+api::VolumeActivationConfiguration createVolumeActivation(const std::string& name,
+ const api::VolumeInvocationType& type,
+ int minVolume, int maxVolume) {
+ api::VolumeActivationConfiguration activation;
+ activation.name = name;
+ api::VolumeActivationConfigurationEntry entry;
+ entry.maxActivationVolumePercentage = maxVolume;
+ entry.minActivationVolumePercentage = minVolume;
+ entry.type = type;
+ activation.volumeActivationEntries.push_back(entry);
+
+ return activation;
+}
+
+api::FadeConfiguration createFadeConfiguration(const long& fadeDurationsMillis,
+ const AudioAttributes& audioAttributes) {
+ api::FadeConfiguration configuration;
+ configuration.fadeDurationMillis = fadeDurationsMillis;
+ configuration.audioAttributesOrUsage
+ .set<api::FadeConfiguration::AudioAttributesOrUsage::Tag::fadeAttribute>(
+ audioAttributes);
+ return configuration;
+}
+
+api::FadeConfiguration createFadeConfiguration(const long& fadeDurationsMillis,
+ const AudioUsage& audioUsage) {
+ api::FadeConfiguration configuration;
+ configuration.fadeDurationMillis = fadeDurationsMillis;
+ configuration.audioAttributesOrUsage
+ .set<api::FadeConfiguration::AudioAttributesOrUsage::Tag::usage>(audioUsage);
+ return configuration;
+}
+
+api::AudioFadeConfiguration createAudioFadeConfiguration(
+ const std::string& name, const api::FadeState& state,
+ const std::vector<AudioUsage>& fadeableUsages = std::vector<AudioUsage>(),
+ const std::optional<std::vector<AudioContentType>>& unfadeableContentTypes = std::nullopt,
+ const std::vector<AudioAttributes> unfadeableAudioAttributes =
+ std::vector<AudioAttributes>(),
+ const std::vector<api::FadeConfiguration> fadeOutConfigurations =
+ std::vector<api::FadeConfiguration>(),
+ const std::vector<api::FadeConfiguration> fadeInConfigurations =
+ std::vector<api::FadeConfiguration>(),
+ const long& fadeOutDurationMs = api::AudioFadeConfiguration::DEFAULT_FADE_OUT_DURATION_MS,
+ const long& fadeInDurationMs = api::AudioFadeConfiguration::DEFAULT_FADE_IN_DURATION_MS,
+ const long& fadeInDelayedForOffendersMs =
+ api::AudioFadeConfiguration::DEFAULT_DELAY_FADE_IN_OFFENDERS_MS) {
+ api::AudioFadeConfiguration audioZoneFadeConfiguration;
+ audioZoneFadeConfiguration.name = name;
+ audioZoneFadeConfiguration.fadeInDurationMs = fadeInDurationMs;
+ audioZoneFadeConfiguration.fadeOutDurationMs = fadeOutDurationMs;
+ audioZoneFadeConfiguration.fadeInDelayedForOffendersMs = fadeInDelayedForOffendersMs;
+ audioZoneFadeConfiguration.fadeState = state;
+ audioZoneFadeConfiguration.fadeableUsages = fadeableUsages;
+ audioZoneFadeConfiguration.unfadeableContentTypes = unfadeableContentTypes;
+ audioZoneFadeConfiguration.unfadableAudioAttributes = unfadeableAudioAttributes;
+ audioZoneFadeConfiguration.fadeOutConfigurations = fadeOutConfigurations;
+ audioZoneFadeConfiguration.fadeInConfigurations = fadeInConfigurations;
+
+ return audioZoneFadeConfiguration;
+}
+
+api::TransientFadeConfigurationEntry createTransientFadeConfiguration(
+ const api::AudioFadeConfiguration& fadeConfig, const std::vector<AudioUsage>& usages) {
+ api::TransientFadeConfigurationEntry entry;
+ entry.transientFadeConfiguration = fadeConfig;
+ entry.transientUsages = usages;
+ return entry;
+}
+
+api::AudioZoneFadeConfiguration createAudioZoneFadeConfiguration(
+ const api::AudioFadeConfiguration& defaultConfig,
+ const std::vector<api::TransientFadeConfigurationEntry>& transientConfigs) {
+ api::AudioZoneFadeConfiguration zoneFadeConfiguration;
+ zoneFadeConfiguration.defaultConfiguration = defaultConfig;
+ zoneFadeConfiguration.transientConfiguration = transientConfigs;
+ return zoneFadeConfiguration;
+}
+
+api::AudioZone createAudioZone(const std::string& name, const int zoneId,
+ const std::vector<api::AudioZoneContextInfo>& contexts,
+ const std::vector<api::AudioZoneConfig>& configs) {
+ api::AudioZone zone;
+ zone.name = name;
+ zone.id = zoneId;
+ zone.occupantZoneId = zoneId;
+ zone.audioZoneContext.audioContextInfos = contexts;
+ zone.audioZoneConfigs = configs;
+ return zone;
+}
+
+const std::vector<AudioUsage> kFadeableUsages = {AudioUsage::MEDIA,
+ AudioUsage::GAME,
+ AudioUsage::ASSISTANCE_SONIFICATION,
+ AudioUsage::ASSISTANCE_ACCESSIBILITY,
+ AudioUsage::ASSISTANCE_NAVIGATION_GUIDANCE,
+ AudioUsage::ASSISTANT,
+ AudioUsage::NOTIFICATION,
+ AudioUsage::ANNOUNCEMENT};
+
+const std::vector<AudioAttributes> kUnfadeableAudioAttributes = {
+ createAudioAttributes(AudioUsage::MEDIA, AudioContentType::UNKNOWN, "oem_specific_tag1")};
+
+const std::vector<api::FadeConfiguration> kFadeOutConfigurations = {
+ createFadeConfiguration(
+ 500, createAudioAttributes(AudioUsage::ASSISTANT, AudioContentType::UNKNOWN,
+ "oem_specific_tag2")),
+ createFadeConfiguration(500, AudioUsage::MEDIA),
+ createFadeConfiguration(500, AudioUsage::GAME),
+ createFadeConfiguration(800, AudioUsage::ASSISTANCE_SONIFICATION),
+ createFadeConfiguration(800, AudioUsage::ASSISTANCE_ACCESSIBILITY),
+ createFadeConfiguration(800, AudioUsage::ASSISTANCE_NAVIGATION_GUIDANCE),
+ createFadeConfiguration(800, AudioUsage::ASSISTANT),
+ createFadeConfiguration(800, AudioUsage::ANNOUNCEMENT),
+};
+
+const std::vector<api::FadeConfiguration> kFadeInConfigurations = {
+ createFadeConfiguration(
+ 1000, createAudioAttributes(AudioUsage::ASSISTANT, AudioContentType::UNKNOWN,
+ "oem_specific_tag2")),
+ createFadeConfiguration(1000, AudioUsage::MEDIA),
+ createFadeConfiguration(1000, AudioUsage::GAME),
+ createFadeConfiguration(800, AudioUsage::ASSISTANCE_SONIFICATION),
+ createFadeConfiguration(800, AudioUsage::ASSISTANCE_ACCESSIBILITY),
+ createFadeConfiguration(800, AudioUsage::ASSISTANCE_NAVIGATION_GUIDANCE),
+ createFadeConfiguration(800, AudioUsage::ASSISTANT),
+ createFadeConfiguration(800, AudioUsage::ANNOUNCEMENT),
+};
+
+const api::AudioFadeConfiguration kRelaxedFading = createAudioFadeConfiguration(
+ "relaxed fading", api::FadeState::FADE_STATE_ENABLED_DEFAULT, kFadeableUsages,
+ std::optional<std::vector<AudioContentType>>(
+ {AudioContentType::SPEECH, AudioContentType::SONIFICATION}),
+ kUnfadeableAudioAttributes, kFadeOutConfigurations, kFadeInConfigurations, 800, 500, 10000);
+
+const std::vector<AudioAttributes> kAggressiveUnfadeableAudioAttributes = {
+ createAudioAttributes(AudioUsage::MEDIA, AudioContentType::UNKNOWN, "oem_specific_tag1"),
+ createAudioAttributes(AudioUsage::ASSISTANT, AudioContentType::UNKNOWN,
+ "oem_projection_service"),
+};
+
+const std::vector<api::FadeConfiguration> kAggressiveFadeOutConfigurations = {
+ createFadeConfiguration(150, AudioUsage::MEDIA),
+ createFadeConfiguration(150, AudioUsage::GAME),
+ createFadeConfiguration(400, AudioUsage::ASSISTANCE_SONIFICATION),
+ createFadeConfiguration(400, AudioUsage::ASSISTANCE_ACCESSIBILITY),
+ createFadeConfiguration(400, AudioUsage::ASSISTANCE_NAVIGATION_GUIDANCE),
+ createFadeConfiguration(400, AudioUsage::ASSISTANT),
+ createFadeConfiguration(400, AudioUsage::ANNOUNCEMENT),
+};
+
+const std::vector<api::FadeConfiguration> kAggressiveFadeInConfigurations = {
+ createFadeConfiguration(300, AudioUsage::MEDIA),
+ createFadeConfiguration(300, AudioUsage::GAME),
+ createFadeConfiguration(550, AudioUsage::ASSISTANCE_SONIFICATION),
+ createFadeConfiguration(550, AudioUsage::ASSISTANCE_ACCESSIBILITY),
+ createFadeConfiguration(550, AudioUsage::ASSISTANCE_NAVIGATION_GUIDANCE),
+ createFadeConfiguration(550, AudioUsage::ASSISTANT),
+ createFadeConfiguration(550, AudioUsage::ANNOUNCEMENT),
+};
+
+const api::AudioFadeConfiguration kAggressiveFading = createAudioFadeConfiguration(
+ "aggressive fading", api::FadeState::FADE_STATE_ENABLED_DEFAULT, kFadeableUsages,
+ std::optional<std::vector<AudioContentType>>(
+ {AudioContentType::SPEECH, AudioContentType::MUSIC}),
+ kAggressiveUnfadeableAudioAttributes, kAggressiveFadeOutConfigurations,
+ kAggressiveFadeInConfigurations);
+
+const api::AudioFadeConfiguration kDisabledFading =
+ createAudioFadeConfiguration("disabled fading", api::FadeState::FADE_STATE_DISABLED);
+
+const std::vector<api::FadeConfiguration> kDynamicFadeOutConfigurations = {
+ createFadeConfiguration(
+ 500, createAudioAttributes(AudioUsage::ASSISTANT, AudioContentType::UNKNOWN,
+ "oem_specific_tag2")),
+ createFadeConfiguration(800, AudioUsage::ASSISTANCE_SONIFICATION),
+ createFadeConfiguration(800, AudioUsage::ASSISTANCE_ACCESSIBILITY),
+ createFadeConfiguration(800, AudioUsage::ASSISTANCE_NAVIGATION_GUIDANCE),
+ createFadeConfiguration(800, AudioUsage::ASSISTANT),
+ createFadeConfiguration(800, AudioUsage::ANNOUNCEMENT),
+};
+
+const std::vector<api::FadeConfiguration> kDynamicFadeInConfigurations = {
+ createFadeConfiguration(
+ 1000, createAudioAttributes(AudioUsage::ASSISTANT, AudioContentType::UNKNOWN,
+ "oem_specific_tag2")),
+ createFadeConfiguration(800, AudioUsage::ASSISTANCE_SONIFICATION),
+ createFadeConfiguration(800, AudioUsage::ASSISTANCE_ACCESSIBILITY),
+ createFadeConfiguration(800, AudioUsage::ASSISTANCE_NAVIGATION_GUIDANCE),
+ createFadeConfiguration(800, AudioUsage::ASSISTANT),
+ createFadeConfiguration(800, AudioUsage::ANNOUNCEMENT),
+};
+
+const api::AudioFadeConfiguration kDynamicFading = createAudioFadeConfiguration(
+ "dynamic fading", api::FadeState::FADE_STATE_ENABLED_DEFAULT, kFadeableUsages,
+ std::optional<std::vector<AudioContentType>>(
+ {AudioContentType::SPEECH, AudioContentType::MOVIE}),
+ kUnfadeableAudioAttributes, kDynamicFadeOutConfigurations, kDynamicFadeInConfigurations,
+ 800, 500);
+
+const api::AudioZoneFadeConfiguration kDefaultAudioConfigFading = createAudioZoneFadeConfiguration(
+ kRelaxedFading,
+ {createTransientFadeConfiguration(
+ kAggressiveFading, {AudioUsage::VOICE_COMMUNICATION, AudioUsage::ANNOUNCEMENT,
+ AudioUsage::VEHICLE_STATUS, AudioUsage::SAFETY}),
+ createTransientFadeConfiguration(kDisabledFading, {AudioUsage::EMERGENCY})});
+
+const api::AudioZoneFadeConfiguration kDynamicDeviceAudioConfigFading =
+ createAudioZoneFadeConfiguration(
+ kDynamicFading,
+ {createTransientFadeConfiguration(
+ kAggressiveFading,
+ {AudioUsage::VOICE_COMMUNICATION, AudioUsage::ANNOUNCEMENT,
+ AudioUsage::VEHICLE_STATUS, AudioUsage::SAFETY}),
+ createTransientFadeConfiguration(kDisabledFading, {AudioUsage::EMERGENCY})});
+
+const api::AudioZoneContextInfo kMusicContextInfo =
+ createContextInfo("oem_music", {AudioUsage::MEDIA, AudioUsage::GAME, AudioUsage::UNKNOWN});
+const api::AudioZoneContextInfo kNotificationContextInfo = createContextInfo(
+ "oem_notification", {AudioUsage::NOTIFICATION, AudioUsage::NOTIFICATION_EVENT});
+const api::AudioZoneContextInfo kVoiceContextInfo = createContextInfo(
+ "oem_voice_command", {AudioUsage::ASSISTANT, AudioUsage::ASSISTANCE_ACCESSIBILITY,
+ AudioUsage::ASSISTANCE_NAVIGATION_GUIDANCE});
+const api::AudioZoneContextInfo kCallContextInfo =
+ createContextInfo("oem_call", {AudioUsage::VOICE_COMMUNICATION, AudioUsage::CALL_ASSISTANT,
+ AudioUsage::VOICE_COMMUNICATION_SIGNALLING});
+const api::AudioZoneContextInfo kRingContextInfo =
+ createContextInfo("oem_call_ring", {AudioUsage::NOTIFICATION_TELEPHONY_RINGTONE});
+const api::AudioZoneContextInfo kAlarmContextInfo =
+ createContextInfo("oem_alarm", {AudioUsage::ALARM});
+const api::AudioZoneContextInfo kSystemContextInfo = createContextInfo(
+ "oem_system_sound",
+ {AudioUsage::ASSISTANCE_SONIFICATION, AudioUsage::EMERGENCY, AudioUsage::SAFETY,
+ AudioUsage::VEHICLE_STATUS, AudioUsage::ANNOUNCEMENT});
+const api::AudioZoneContextInfo kOemContextInfo = createContextInfo(
+ "oem_context", {createAudioAttributes(AudioUsage::ASSISTANCE_NAVIGATION_GUIDANCE,
+ AudioContentType::SPEECH, "oem=extension_8675309")});
+
+const std::vector<api::AudioZoneContextInfo> kSimpleCarAudioConfigurationContext = {
+ kOemContextInfo, kMusicContextInfo, kNotificationContextInfo, kVoiceContextInfo,
+ kCallContextInfo, kRingContextInfo, kAlarmContextInfo, kSystemContextInfo};
+
+const api::AudioZoneContextInfo kDefaultMusicContextInfo =
+ createContextInfo("music", {AudioUsage::UNKNOWN, AudioUsage::MEDIA, AudioUsage::GAME}, 1);
+const api::AudioZoneContextInfo kDefaultNavContextInfo =
+ createContextInfo("navigation", {AudioUsage::ASSISTANCE_NAVIGATION_GUIDANCE}, 2);
+const api::AudioZoneContextInfo kDefaultVoiceContextInfo = createContextInfo(
+ "voice_command", {AudioUsage::ASSISTANCE_ACCESSIBILITY, AudioUsage::ASSISTANT}, 3);
+const api::AudioZoneContextInfo kDefaultRingContextInfo =
+ createContextInfo("call_ring", {AudioUsage::NOTIFICATION_TELEPHONY_RINGTONE}, 4);
+const api::AudioZoneContextInfo kDefaultCallContextInfo =
+ createContextInfo("call",
+ {AudioUsage::VOICE_COMMUNICATION, AudioUsage::CALL_ASSISTANT,
+ AudioUsage::VOICE_COMMUNICATION_SIGNALLING},
+ 5);
+const api::AudioZoneContextInfo kDefaultAlarmContextInfo =
+ createContextInfo("alarm", {AudioUsage::ALARM}, 6);
+const api::AudioZoneContextInfo kDefaultNotificationContextInfo = createContextInfo(
+ "notification", {AudioUsage::NOTIFICATION, AudioUsage::NOTIFICATION_EVENT}, 7);
+const api::AudioZoneContextInfo kDefaultSystemContextInfo =
+ createContextInfo("system_sound", {AudioUsage::ASSISTANCE_SONIFICATION}, 8);
+const api::AudioZoneContextInfo kDefaultEmergencyContextInfo =
+ createContextInfo("emergency", {AudioUsage::EMERGENCY}, 9);
+const api::AudioZoneContextInfo kDefaultSafetyContextInfo =
+ createContextInfo("safety", {AudioUsage::SAFETY}, 10);
+const api::AudioZoneContextInfo kDefaultVehicleStatusContextInfo =
+ createContextInfo("vehicle_status", {AudioUsage::VEHICLE_STATUS}, 11);
+const api::AudioZoneContextInfo kDefaultAnnouncementContextInfo =
+ createContextInfo("announcement", {AudioUsage::ANNOUNCEMENT}, 12);
+
+const std::vector<api::AudioZoneContextInfo> kDefaultCarAudioConfigurationContext = {
+ kDefaultMusicContextInfo, kDefaultNavContextInfo,
+ kDefaultVoiceContextInfo, kDefaultRingContextInfo,
+ kDefaultCallContextInfo, kDefaultAlarmContextInfo,
+ kDefaultNotificationContextInfo, kDefaultSystemContextInfo,
+ kDefaultEmergencyContextInfo, kDefaultSafetyContextInfo,
+ kDefaultVehicleStatusContextInfo, kDefaultAnnouncementContextInfo};
+
+const api::VolumeActivationConfiguration kOnBootVolumeActivation =
+ createVolumeActivation("on_boot_config", api::VolumeInvocationType::ON_BOOT, 0, 80);
+const api::VolumeActivationConfiguration kOnSourceVolumeActivation = createVolumeActivation(
+ "on_source_changed_config", api::VolumeInvocationType::ON_SOURCE_CHANGED, 20, 80);
+const api::VolumeActivationConfiguration kOnPlayVolumeActivation = createVolumeActivation(
+ "on_playback_changed_config", api::VolumeInvocationType::ON_PLAYBACK_CHANGED, 10, 90);
+
+const AudioPort kBusMediaDevice = createAudioPort("BUS00_MEDIA", AudioDeviceType::OUT_BUS);
+const AudioPort kBTMediaDevice = createAudioPort("temp", AudioDeviceType::OUT_DEVICE, "bt-a2dp");
+const AudioPort kUSBMediaDevice = createAudioPort("", AudioDeviceType::OUT_HEADSET, "usb");
+
+const AudioPort kBusNavDevice = createAudioPort("BUS02_NAV_GUIDANCE", AudioDeviceType::OUT_BUS);
+const AudioPort kBusPhoneDevice = createAudioPort("BUS03_PHONE", AudioDeviceType::OUT_BUS);
+const AudioPort kBusSysDevice = createAudioPort("BUS01_SYS_NOTIFICATION", AudioDeviceType::OUT_BUS);
+
+const AudioPort kMirrorDevice1 = createAudioPort("mirror_bus_device_1", AudioDeviceType::OUT_BUS);
+const AudioPort kMirrorDevice2 = createAudioPort("mirror_bus_device_2", AudioDeviceType::OUT_BUS);
+const std::vector<AudioPort> kMirroringDevices = {kMirrorDevice1, kMirrorDevice2};
+
+const AudioPort kMirrorDeviceThree =
+ createAudioPort("mirror_bus_device_three", AudioDeviceType::OUT_BUS);
+const AudioPort kMirrorDeviceFour =
+ createAudioPort("mirror_bus_device_four", AudioDeviceType::OUT_BUS);
+const std::vector<AudioPort> kMultiZoneMirroringDevices = {kMirrorDeviceThree, kMirrorDeviceFour};
+
+const AudioPort kInFMTunerDevice = createAudioPort("fm_tuner", AudioDeviceType::IN_FM_TUNER);
+const AudioPort kInMicDevice = createAudioPort("built_in_mic", AudioDeviceType::IN_MICROPHONE);
+const AudioPort kInBusDevice = createAudioPort("in_bus_device", AudioDeviceType::IN_BUS);
+const std::vector<AudioPort> kInputDevices{kInFMTunerDevice, kInMicDevice, kInBusDevice};
+
+const api::VolumeGroupConfig kBusMediaVolumeGroup = createVolumeGroup(
+ "entertainment", kOnBootVolumeActivation, {createRoutes(kBusMediaDevice, {"oem_music"})});
+const api::VolumeGroupConfig kUSBMediaVolumeGroup = createVolumeGroup(
+ "entertainment", kOnBootVolumeActivation, {createRoutes(kUSBMediaDevice, {"oem_music"})});
+const api::VolumeGroupConfig kBTMediaVolumeGroup = createVolumeGroup(
+ "entertainment", kOnBootVolumeActivation, {createRoutes(kBTMediaDevice, {"oem_music"})});
+const api::VolumeGroupConfig kBusNavVolumeGroup =
+ createVolumeGroup("navvoicecommand", kOnSourceVolumeActivation,
+ {createRoutes(kBusNavDevice, {"oem_voice_command"})});
+const api::VolumeGroupConfig kBusCallVolumeGroup =
+ createVolumeGroup("telringvol", kOnPlayVolumeActivation,
+ {createRoutes(kBusPhoneDevice, {"oem_call", "oem_call_ring"})});
+const api::VolumeGroupConfig kBusSysVolumeGroup = createVolumeGroup(
+ "systemalarm", kOnSourceVolumeActivation,
+ {createRoutes(kBusSysDevice, {"oem_alarm", "oem_system_sound", "oem_notification"})});
+
+const api::AudioZoneConfig kAllBusZoneConfig = createAudioZoneConfig(
+ "primary zone config 0", kDefaultAudioConfigFading,
+ {kBusMediaVolumeGroup, kBusNavVolumeGroup, kBusCallVolumeGroup, kBusSysVolumeGroup}, true);
+const api::AudioZoneConfig kBTMediaZoneConfig = createAudioZoneConfig(
+ "primary zone BT media", kDynamicDeviceAudioConfigFading,
+ {kBTMediaVolumeGroup, kBusNavVolumeGroup, kBusCallVolumeGroup, kBusSysVolumeGroup});
+const api::AudioZoneConfig kUsBMediaZoneConfig = createAudioZoneConfig(
+ "primary zone USB media", kDynamicDeviceAudioConfigFading,
+ {kUSBMediaVolumeGroup, kBusNavVolumeGroup, kBusCallVolumeGroup, kBusSysVolumeGroup});
+
+const std::unordered_map<std::string, api::AudioZoneConfig> kConfigNameToZoneConfig = {
+ {kAllBusZoneConfig.name, kAllBusZoneConfig},
+ {kBTMediaZoneConfig.name, kBTMediaZoneConfig},
+ {kUsBMediaZoneConfig.name, kUsBMediaZoneConfig},
+};
+
+const api::AudioZoneConfig kDriverZoneConfig = createAudioZoneConfig(
+ "driver zone config 0", kDefaultAudioConfigFading,
+ {kBusMediaVolumeGroup, kBusNavVolumeGroup, kBusCallVolumeGroup, kBusSysVolumeGroup}, true);
+
+const api::AudioZone kDriverZone =
+ createAudioZone("driver zone", api::AudioZone::PRIMARY_AUDIO_ZONE,
+ kSimpleCarAudioConfigurationContext, {kDriverZoneConfig});
+
+const api::AudioZoneFadeConfiguration kZoneAudioConfigFading = createAudioZoneFadeConfiguration(
+ kRelaxedFading,
+ {createTransientFadeConfiguration(kDisabledFading, {AudioUsage::EMERGENCY})});
+
+const AudioPort kBusFrontDevice = createAudioPort("BUS_FRONT", AudioDeviceType::OUT_BUS);
+const api::VolumeGroupConfig kFrontVolumeGroup = createVolumeGroup(
+ "entertainment", kOnBootVolumeActivation,
+ {createRoutes(kBusFrontDevice,
+ {"oem_music", "oem_voice_command", "oem_call", "oem_call_ring", "oem_alarm",
+ "oem_system_sound", "oem_notification"})});
+const api::AudioZoneConfig kFrontZoneConfig = createAudioZoneConfig(
+ "front passenger config 0", kZoneAudioConfigFading, {kFrontVolumeGroup}, true);
+const api::AudioZone kFrontZone =
+ createAudioZone("front passenger zone", api::AudioZone::PRIMARY_AUDIO_ZONE + 1,
+ kSimpleCarAudioConfigurationContext, {kFrontZoneConfig});
+
+const AudioPort kBusRearDevice = createAudioPort("BUS_REAR", AudioDeviceType::OUT_BUS);
+const api::VolumeGroupConfig kRearVolumeGroup =
+ createVolumeGroup("entertainment", kOnBootVolumeActivation,
+ {createRoutes(kBusRearDevice, {"oem_music", "oem_voice_command",
+ "oem_call", "oem_call_ring", "oem_alarm",
+ "oem_system_sound", "oem_notification"})});
+const api::AudioZoneConfig kRearZoneConfig = createAudioZoneConfig(
+ "rear seat config 0", kZoneAudioConfigFading, {kRearVolumeGroup}, true);
+const api::AudioZone kRearZone =
+ createAudioZone("rear seat zone", api::AudioZone::PRIMARY_AUDIO_ZONE + 2,
+ kSimpleCarAudioConfigurationContext, {kRearZoneConfig});
+
+std::vector<api::AudioZone> kMultiZones = {kDriverZone, kFrontZone, kRearZone};
+
+void expectSameFadeConfiguration(const api::AudioFadeConfiguration& actual,
+ const api::AudioFadeConfiguration& expected,
+ const std::string& configName) {
+ EXPECT_EQ(actual.name, expected.name) << "Audio fade configuration for config " << configName;
+ const std::string fadeConfigInfo =
+ "fade config " + actual.name + " in config name " + configName;
+ EXPECT_EQ(actual.fadeState, expected.fadeState)
+ << "Audio fade config state for " << fadeConfigInfo;
+ EXPECT_EQ(actual.fadeInDurationMs, expected.fadeInDurationMs)
+ << "Audio fade in duration for " << fadeConfigInfo;
+ EXPECT_EQ(actual.fadeOutDurationMs, expected.fadeOutDurationMs)
+ << "Audio fade out duration for " << fadeConfigInfo;
+ EXPECT_EQ(actual.fadeInDelayedForOffendersMs, expected.fadeInDelayedForOffendersMs)
+ << "Audio fade in delayed for offenders duration for " << fadeConfigInfo;
+ EXPECT_THAT(actual.fadeableUsages, UnorderedElementsAreArray(expected.fadeableUsages))
+ << "Fadeable usages for " << fadeConfigInfo;
+ EXPECT_TRUE(actual.unfadeableContentTypes.has_value() ==
+ expected.unfadeableContentTypes.has_value())
+ << "Optional unfadeable for " << fadeConfigInfo;
+ if (actual.unfadeableContentTypes.has_value() && expected.unfadeableContentTypes.has_value()) {
+ EXPECT_THAT(actual.unfadeableContentTypes.value(),
+ UnorderedElementsAreArray(expected.unfadeableContentTypes.value()))
+ << "Unfadeable content type for " << fadeConfigInfo;
+ }
+ EXPECT_THAT(actual.unfadableAudioAttributes,
+ UnorderedElementsAreArray(expected.unfadableAudioAttributes))
+ << "Unfadeable audio attributes type for " << fadeConfigInfo;
+ EXPECT_THAT(actual.fadeOutConfigurations,
+ UnorderedElementsAreArray(expected.fadeOutConfigurations))
+ << "Fade-out configurations for " << fadeConfigInfo;
+ EXPECT_THAT(actual.fadeInConfigurations,
+ UnorderedElementsAreArray(expected.fadeInConfigurations))
+ << "Fade-in configurations for " << fadeConfigInfo;
+}
+
+void expectSameAudioZoneFadeConfiguration(
+ const std::optional<api::AudioZoneFadeConfiguration>& actual,
+ const std::optional<api::AudioZoneFadeConfiguration>& expected,
+ const std::string& configName) {
+ if (!actual.has_value() || !expected.has_value()) {
+ EXPECT_EQ(actual.has_value(), expected.has_value())
+ << "Audio zone config " << configName << " fade configuration missing";
+ return;
+ }
+ const api::AudioZoneFadeConfiguration& actualConfig = actual.value();
+ const api::AudioZoneFadeConfiguration& expectedConfig = expected.value();
+ expectSameFadeConfiguration(actualConfig.defaultConfiguration,
+ expectedConfig.defaultConfiguration, configName);
+ EXPECT_THAT(actualConfig.transientConfiguration,
+ UnorderedElementsAreArray(expectedConfig.transientConfiguration))
+ << "Transient fade configuration for config " << configName;
+}
+
+void expectSameAudioZoneConfiguration(const api::AudioZoneConfig& actual,
+ const api::AudioZoneConfig& expected) {
+ EXPECT_EQ(actual.isDefault, expected.isDefault)
+ << "Zone default's status do not match for config " << actual.name;
+ EXPECT_THAT(actual.volumeGroups, UnorderedElementsAreArray(expected.volumeGroups))
+ << "Volume groups for config " << actual.name;
+ expectSameAudioZoneFadeConfiguration(actual.fadeConfiguration, expected.fadeConfiguration,
+ actual.name);
+}
+
+class CarAudioConfigurationTest : public testing::Test {
+ protected:
+ void SetUp() override;
+ void TearDown() override;
+
+ std::unique_ptr<converter::CarAudioConfigurationXmlConverter> converter;
+
+ protected:
+ virtual std::string getCarAudioConfiguration() = 0;
+ virtual std::string getCarFadeConfiguration() = 0;
+};
+
+void CarAudioConfigurationTest::SetUp() {
+ converter = std::make_unique<converter::CarAudioConfigurationXmlConverter>(
+ getTestFilePath(getCarAudioConfiguration()),
+ getTestFilePath(getCarFadeConfiguration()));
+}
+
+void CarAudioConfigurationTest::TearDown() {
+ converter.reset();
+}
+
+class SimpleCarAudioConfigurationTest : public CarAudioConfigurationTest {
+ virtual std::string getCarAudioConfiguration() { return "simple_car_audio_configuration.xml"; }
+
+ virtual std::string getCarFadeConfiguration() { return "car_audio_fade_configuration.xml"; }
+};
+
+TEST_F(SimpleCarAudioConfigurationTest, TestLoadSimpleConfiguration) {
+ EXPECT_EQ(converter->getErrors(), "");
+
+ const auto audioDeviceConfigs = converter->getAudioDeviceConfiguration();
+ EXPECT_EQ(audioDeviceConfigs.routingConfig,
+ api::RoutingDeviceConfiguration::DYNAMIC_AUDIO_ROUTING);
+ EXPECT_FALSE(audioDeviceConfigs.useCoreAudioVolume);
+ EXPECT_TRUE(audioDeviceConfigs.useHalDuckingSignals);
+ EXPECT_TRUE(audioDeviceConfigs.useCarVolumeGroupMuting);
+
+ const auto& mirroringDevices = converter->getOutputMirroringDevices();
+
+ EXPECT_EQ(mirroringDevices.size(), 2) << "Mirroring device size";
+ for (const auto& mirroringDevice : mirroringDevices) {
+ const auto& it =
+ std::find(kMirroringDevices.begin(), kMirroringDevices.end(), mirroringDevice);
+ EXPECT_TRUE(it != kMirroringDevices.end())
+ << "Mirroring device not found " << mirroringDevice.toString();
+ }
+
+ const auto zones = converter->getAudioZones();
+ EXPECT_EQ(zones.size(), 1);
+
+ const auto& zone = zones.front();
+ EXPECT_EQ(zone.id, api::AudioZone::PRIMARY_AUDIO_ZONE);
+ EXPECT_EQ(zone.occupantZoneId, 0);
+ EXPECT_EQ(zone.name, "primary zone");
+
+ EXPECT_EQ(zone.audioZoneContext.audioContextInfos.size(),
+ kSimpleCarAudioConfigurationContext.size());
+ for (const auto& info : zone.audioZoneContext.audioContextInfos) {
+ const auto iterator = std::find(kSimpleCarAudioConfigurationContext.begin(),
+ kSimpleCarAudioConfigurationContext.end(), info);
+ EXPECT_TRUE(iterator != kSimpleCarAudioConfigurationContext.end())
+ << "Context name " << info.toString() << kMusicContextInfo.toString();
+ }
+
+ for (const auto& config : zone.audioZoneConfigs) {
+ const auto& iterator = kConfigNameToZoneConfig.find(config.name);
+ EXPECT_TRUE(iterator != kConfigNameToZoneConfig.end())
+ << "Zone config not found " << config.name;
+ expectSameAudioZoneConfiguration(config, iterator->second);
+ }
+
+ const auto& inputDevices = zone.inputAudioDevices;
+ EXPECT_EQ(inputDevices.size(), 3) << "Input devices";
+ for (const auto& inputDevice : inputDevices) {
+ const auto& it = std::find(kInputDevices.begin(), kInputDevices.end(), inputDevice);
+ EXPECT_TRUE(it != kInputDevices.end())
+ << "Input device " << inputDevice.toString() << " not found";
+ }
+}
+
+class TypeDeviceCarAudioConfigurationTest : public CarAudioConfigurationTest {
+ virtual std::string getCarAudioConfiguration() {
+ return "simple_car_audio_configuration_with_device_type.xml";
+ }
+
+ virtual std::string getCarFadeConfiguration() { return "car_audio_fade_configuration.xml"; }
+};
+
+TEST_F(TypeDeviceCarAudioConfigurationTest, TestLoadConfigurationWithDeviceType) {
+ EXPECT_EQ(converter->getErrors(), "");
+
+ const auto audioDeviceConfigs = converter->getAudioDeviceConfiguration();
+ EXPECT_EQ(audioDeviceConfigs.routingConfig,
+ api::RoutingDeviceConfiguration::DYNAMIC_AUDIO_ROUTING);
+ EXPECT_FALSE(audioDeviceConfigs.useCoreAudioVolume);
+ EXPECT_TRUE(audioDeviceConfigs.useHalDuckingSignals);
+ EXPECT_TRUE(audioDeviceConfigs.useCarVolumeGroupMuting);
+
+ const auto& mirroringDevices = converter->getOutputMirroringDevices();
+
+ EXPECT_EQ(mirroringDevices.size(), 2) << "Mirroring device size";
+ for (const auto& mirroringDevice : mirroringDevices) {
+ const auto& it =
+ std::find(kMirroringDevices.begin(), kMirroringDevices.end(), mirroringDevice);
+ EXPECT_TRUE(it != kMirroringDevices.end())
+ << "Mirroring device not found " << mirroringDevice.toString();
+ }
+
+ const auto zones = converter->getAudioZones();
+ EXPECT_EQ(zones.size(), 1);
+
+ const auto& zone = zones.front();
+ EXPECT_EQ(zone.id, api::AudioZone::PRIMARY_AUDIO_ZONE);
+ EXPECT_EQ(zone.occupantZoneId, 0);
+ EXPECT_EQ(zone.name, "primary zone");
+
+ EXPECT_EQ(zone.audioZoneContext.audioContextInfos.size(),
+ kSimpleCarAudioConfigurationContext.size());
+ for (const auto& info : zone.audioZoneContext.audioContextInfos) {
+ const auto iterator = std::find(kSimpleCarAudioConfigurationContext.begin(),
+ kSimpleCarAudioConfigurationContext.end(), info);
+ EXPECT_TRUE(iterator != kSimpleCarAudioConfigurationContext.end())
+ << "Context name " << info.toString() << kMusicContextInfo.toString();
+ }
+
+ for (const auto& config : zone.audioZoneConfigs) {
+ const auto& iterator = kConfigNameToZoneConfig.find(config.name);
+ EXPECT_TRUE(iterator != kConfigNameToZoneConfig.end())
+ << "Zone config not found " << config.name;
+ expectSameAudioZoneConfiguration(config, iterator->second);
+ }
+
+ const auto& inputDevices = zone.inputAudioDevices;
+ EXPECT_EQ(inputDevices.size(), 3) << "Input devices";
+ for (const auto& inputDevice : inputDevices) {
+ const auto& it = std::find(kInputDevices.begin(), kInputDevices.end(), inputDevice);
+ EXPECT_TRUE(it != kInputDevices.end())
+ << "Input device " << inputDevice.toString() << " not found";
+ }
+}
+
+class CarAudioConfigurationWithDefaultContextTest : public CarAudioConfigurationTest {
+ virtual std::string getCarAudioConfiguration() {
+ return "car_audio_configuration_with_default_context.xml";
+ }
+
+ virtual std::string getCarFadeConfiguration() { return ""; }
+};
+
+TEST_F(CarAudioConfigurationWithDefaultContextTest, TestLoadConfiguration) {
+ EXPECT_EQ(converter->getErrors(), "");
+ const auto& zones = converter->getAudioZones();
+ EXPECT_EQ(zones.size(), 1) << "Default audio context zones";
+ const auto& zone = zones.front();
+ const auto& context = zone.audioZoneContext;
+ EXPECT_THAT(context.audioContextInfos,
+ UnorderedElementsAreArray(kDefaultCarAudioConfigurationContext))
+ << "Default audio contexts";
+}
+
+class MultiZoneCarAudioConfigurationTest : public CarAudioConfigurationTest {
+ std::string getCarAudioConfiguration() override {
+ return "multi_zone_car_audio_configuration.xml";
+ }
+
+ std::string getCarFadeConfiguration() override { return "car_audio_fade_configuration.xml"; }
+};
+
+TEST_F(MultiZoneCarAudioConfigurationTest, TestLoadMultiZoneConfiguration) {
+ EXPECT_EQ(converter->getErrors(), "");
+
+ const auto audioDeviceConfigs = converter->getAudioDeviceConfiguration();
+ EXPECT_EQ(audioDeviceConfigs.routingConfig,
+ api::RoutingDeviceConfiguration::CONFIGURABLE_AUDIO_ENGINE_ROUTING);
+ EXPECT_TRUE(audioDeviceConfigs.useCoreAudioVolume);
+ EXPECT_FALSE(audioDeviceConfigs.useHalDuckingSignals);
+ EXPECT_FALSE(audioDeviceConfigs.useCarVolumeGroupMuting);
+
+ const auto& mirroringDevices = converter->getOutputMirroringDevices();
+
+ EXPECT_THAT(mirroringDevices, UnorderedElementsAreArray(kMultiZoneMirroringDevices));
+
+ const auto zones = converter->getAudioZones();
+ EXPECT_THAT(zones, UnorderedElementsAreArray(kMultiZones));
+}
+
+class MalformedCarAudioConfigurationTest : public testing::Test {
+ protected:
+ void TearDown() override;
+
+ std::unique_ptr<converter::CarAudioConfigurationXmlConverter> converter;
+};
+
+void MalformedCarAudioConfigurationTest::TearDown() {
+ converter.reset();
+}
+
+TEST_F(MalformedCarAudioConfigurationTest, TestLoadEmptyConfiguration) {
+ converter =
+ std::make_unique<converter::CarAudioConfigurationXmlConverter>(getTestFilePath(""), "");
+ EXPECT_THAT(converter->getErrors(), ContainsRegex("Configuration file .+ is not readable"))
+ << "Empty configuration file";
+
+ const auto audioDeviceConfigs = converter->getAudioDeviceConfiguration();
+ EXPECT_EQ(audioDeviceConfigs.routingConfig,
+ api::RoutingDeviceConfiguration::DEFAULT_AUDIO_ROUTING)
+ << "Default configuration for empty file";
+}
+
+TEST_F(MalformedCarAudioConfigurationTest, TestLoadNonExistingConfiguration) {
+ converter = std::make_unique<converter::CarAudioConfigurationXmlConverter>(
+ getTestFilePath("non_existing_file.xml"), "");
+ EXPECT_THAT(converter->getErrors(), ContainsRegex("Configuration file .+ is not readable"))
+ << "Empty configuration file";
+
+ const auto audioDeviceConfigs = converter->getAudioDeviceConfiguration();
+ EXPECT_EQ(audioDeviceConfigs.routingConfig,
+ api::RoutingDeviceConfiguration::DEFAULT_AUDIO_ROUTING)
+ << "Default configuration for empty file";
+}
+
+TEST_F(MalformedCarAudioConfigurationTest, TestLoadMalforedConfiguration) {
+ converter = std::make_unique<converter::CarAudioConfigurationXmlConverter>(
+ getTestFilePath("car_audio_configuration_without_configuration.xml"), "");
+ EXPECT_THAT(converter->getErrors(),
+ ContainsRegex("Configuration file .+ does not have any configurations"))
+ << "Configuration file without configurations";
+
+ const auto audioDeviceConfigs = converter->getAudioDeviceConfiguration();
+ EXPECT_EQ(audioDeviceConfigs.routingConfig,
+ api::RoutingDeviceConfiguration::DEFAULT_AUDIO_ROUTING)
+ << "Default configuration for malformed file";
+}
+
+TEST_F(MalformedCarAudioConfigurationTest, TestLoadConfigurationWithoutZones) {
+ converter = std::make_unique<converter::CarAudioConfigurationXmlConverter>(
+ getTestFilePath("car_audio_configuration_without_audio_zone.xml"), "");
+ EXPECT_THAT(converter->getErrors(), ContainsRegex("Audio zones not found in file"))
+ << "Configuration file without zones";
+
+ const auto audioDeviceConfigs = converter->getAudioDeviceConfiguration();
+ EXPECT_EQ(audioDeviceConfigs.routingConfig,
+ api::RoutingDeviceConfiguration::DEFAULT_AUDIO_ROUTING)
+ << "Default configuration for file without zones";
+}
+
+TEST_F(MalformedCarAudioConfigurationTest, TestLoadConfigurationWithMissingZones) {
+ converter = std::make_unique<converter::CarAudioConfigurationXmlConverter>(
+ getTestFilePath("car_audio_configuration_with_missing_zones.xml"), "");
+ EXPECT_THAT(converter->getErrors(), ContainsRegex("Error parsing audio zone"))
+ << "Configuration file with missing zones";
+
+ const auto audioDeviceConfigs = converter->getAudioDeviceConfiguration();
+ EXPECT_EQ(audioDeviceConfigs.routingConfig,
+ api::RoutingDeviceConfiguration::DEFAULT_AUDIO_ROUTING)
+ << "Default configuration for file with missing zones";
+}
+
+} // namespace
diff --git a/automotive/audiocontrol/aidl/default/converter/test/car_audio_configuration_with_default_context.xml b/automotive/audiocontrol/aidl/default/converter/test/car_audio_configuration_with_default_context.xml
new file mode 100644
index 0000000..80cb5cd
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/converter/test/car_audio_configuration_with_default_context.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 The Android Open Source Project
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<carAudioConfiguration version="4">
+ <zones>
+ <zone name="primary zone" isPrimary="true">
+ <zoneConfigs>
+ <zoneConfig name="primary zone config" isDefault="true">
+ <volumeGroups>
+ <group name="entertainment" >
+ <device address="BUS00_MEDIA">
+ <context context="MUSIC"/>
+ </device>
+ </group>
+ <group name="navvoicecommand" >
+ <device address="BUS02_NAV_GUIDANCE">
+ <context context="NAVIGATION"/>
+ <context context="VOICE_COMMAND"/>
+ </device>
+ </group>
+ <group name="telringvol" >
+ <device address="BUS03_PHONE">
+ <context context="CALL"/>
+ <context context="CALL_RING"/>
+ </device>
+ </group>
+ <group name="alarm" >
+ <device address="BUS01_NOTIFICATION">
+ <context context="ALARM"/>
+ <context context="NOTIFICATION"/>
+ </device>
+ </group>
+ <group name="system" >
+ <device address="BUS05_SYSTEM">
+ <context context="SYSTEM_SOUND"/>
+ <context context="EMERGENCY"/>
+ <context context="SAFETY"/>
+ <context context="VEHICLE_STATUS"/>
+ <context context="ANNOUNCEMENT"/>
+ </device>
+ </group>
+ </volumeGroups>
+ </zoneConfig>
+ </zoneConfigs>
+ </zone>
+ </zones>
+</carAudioConfiguration>
diff --git a/automotive/audiocontrol/aidl/default/converter/test/car_audio_configuration_with_missing_zones.xml b/automotive/audiocontrol/aidl/default/converter/test/car_audio_configuration_with_missing_zones.xml
new file mode 100644
index 0000000..a5880b3
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/converter/test/car_audio_configuration_with_missing_zones.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 The Android Open Source Project
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<carAudioConfiguration version="4">
+ <deviceConfigurations>
+ <deviceConfiguration name="useHalDuckingSignals" value="true" />
+ <deviceConfiguration name="useCoreAudioRouting" value="false" />
+ <deviceConfiguration name="useCoreAudioVolume" value="false" />
+ <deviceConfiguration name="useCarVolumeGroupMuting" value="true" />
+ </deviceConfigurations>
+ <oemContexts>
+ <oemContext name="oem_context">
+ <audioAttributes>
+ <audioAttribute usage="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"
+ contentType="AUDIO_CONTENT_TYPE_SPEECH"
+ tags="oem=extension_8675309" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_music">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_MEDIA" />
+ <usage value="AUDIO_USAGE_GAME" />
+ <usage value="AUDIO_USAGE_UNKNOWN" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_notification">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_NOTIFICATION" />
+ <usage value="AUDIO_USAGE_NOTIFICATION_EVENT" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_voice_command">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_ASSISTANT" />
+ <usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
+ <usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_call">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_VOICE_COMMUNICATION" />
+ <usage value="AUDIO_USAGE_CALL_ASSISTANT" />
+ <usage value="AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_call_ring">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_alarm">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_ALARM" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_system_sound">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
+ <usage value="AUDIO_USAGE_EMERGENCY" />
+ <usage value="AUDIO_USAGE_SAFETY" />
+ <usage value="AUDIO_USAGE_VEHICLE_STATUS" />
+ <usage value="AUDIO_USAGE_ANNOUNCEMENT" />
+ </audioAttributes>
+ </oemContext>
+ </oemContexts>
+ <activationVolumeConfigs>
+ <activationVolumeConfig name="on_boot_config">
+ <activationVolumeConfigEntry maxActivationVolumePercentage="80" invocationType="onBoot" />
+ </activationVolumeConfig>
+ <activationVolumeConfig name="on_source_changed_config">
+ <activationVolumeConfigEntry minActivationVolumePercentage="20" maxActivationVolumePercentage="80" invocationType="onSourceChanged" />
+ </activationVolumeConfig>
+ <activationVolumeConfig name="on_playback_changed_config">
+ <activationVolumeConfigEntry minActivationVolumePercentage="10" maxActivationVolumePercentage="90" invocationType="onPlaybackChanged" />
+ </activationVolumeConfig>
+ </activationVolumeConfigs>
+ <mirroringDevices>
+ <mirroringDevice address="mirror_bus_device_1"/>
+ <mirroringDevice address="mirror_bus_device_2"/>
+ </mirroringDevices>
+ <zones>
+ </zones>
+</carAudioConfiguration>
diff --git a/automotive/audiocontrol/aidl/default/converter/test/car_audio_configuration_without_audio_zone.xml b/automotive/audiocontrol/aidl/default/converter/test/car_audio_configuration_without_audio_zone.xml
new file mode 100644
index 0000000..1e50e6e
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/converter/test/car_audio_configuration_without_audio_zone.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 The Android Open Source Project
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<carAudioConfiguration version="4">
+ <deviceConfigurations>
+ <deviceConfiguration name="useHalDuckingSignals" value="true" />
+ <deviceConfiguration name="useCoreAudioRouting" value="false" />
+ <deviceConfiguration name="useCoreAudioVolume" value="false" />
+ <deviceConfiguration name="useCarVolumeGroupMuting" value="true" />
+ </deviceConfigurations>
+ <oemContexts>
+ <oemContext name="oem_context">
+ <audioAttributes>
+ <audioAttribute usage="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"
+ contentType="AUDIO_CONTENT_TYPE_SPEECH"
+ tags="oem=extension_8675309" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_music">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_MEDIA" />
+ <usage value="AUDIO_USAGE_GAME" />
+ <usage value="AUDIO_USAGE_UNKNOWN" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_notification">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_NOTIFICATION" />
+ <usage value="AUDIO_USAGE_NOTIFICATION_EVENT" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_voice_command">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_ASSISTANT" />
+ <usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
+ <usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_call">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_VOICE_COMMUNICATION" />
+ <usage value="AUDIO_USAGE_CALL_ASSISTANT" />
+ <usage value="AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_call_ring">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_alarm">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_ALARM" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_system_sound">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
+ <usage value="AUDIO_USAGE_EMERGENCY" />
+ <usage value="AUDIO_USAGE_SAFETY" />
+ <usage value="AUDIO_USAGE_VEHICLE_STATUS" />
+ <usage value="AUDIO_USAGE_ANNOUNCEMENT" />
+ </audioAttributes>
+ </oemContext>
+ </oemContexts>
+ <activationVolumeConfigs>
+ <activationVolumeConfig name="on_boot_config">
+ <activationVolumeConfigEntry maxActivationVolumePercentage="80" invocationType="onBoot" />
+ </activationVolumeConfig>
+ <activationVolumeConfig name="on_source_changed_config">
+ <activationVolumeConfigEntry minActivationVolumePercentage="20" maxActivationVolumePercentage="80" invocationType="onSourceChanged" />
+ </activationVolumeConfig>
+ <activationVolumeConfig name="on_playback_changed_config">
+ <activationVolumeConfigEntry minActivationVolumePercentage="10" maxActivationVolumePercentage="90" invocationType="onPlaybackChanged" />
+ </activationVolumeConfig>
+ </activationVolumeConfigs>
+ <mirroringDevices>
+ <mirroringDevice address="mirror_bus_device_1"/>
+ <mirroringDevice address="mirror_bus_device_2"/>
+ </mirroringDevices>
+</carAudioConfiguration>
diff --git a/automotive/audiocontrol/aidl/default/converter/test/car_audio_configuration_without_configuration.xml b/automotive/audiocontrol/aidl/default/converter/test/car_audio_configuration_without_configuration.xml
new file mode 100644
index 0000000..4f50ca2
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/converter/test/car_audio_configuration_without_configuration.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 The Android Open Source Project
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<nonCarAudioConfiguration version="4">
+
+</nonCarAudioConfiguration>
diff --git a/automotive/audiocontrol/aidl/default/converter/test/car_audio_fade_configuration.xml b/automotive/audiocontrol/aidl/default/converter/test/car_audio_fade_configuration.xml
new file mode 100644
index 0000000..249f915
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/converter/test/car_audio_fade_configuration.xml
@@ -0,0 +1,191 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<carAudioFadeConfiguration version="1">
+ <configs>
+ <config name="relaxed fading" defaultFadeOutDurationInMillis="800" defaultFadeInDurationInMillis="500" defaultFadeInDelayForOffenders="10000" >
+ <fadeState value="1" />
+ <fadeableUsages>
+ <usage value="AUDIO_USAGE_MEDIA" />
+ <usage value="AUDIO_USAGE_GAME" />
+ <usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
+ <usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
+ <usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
+ <usage value="AUDIO_USAGE_ASSISTANT" />
+ <usage value="AUDIO_USAGE_NOTIFICATION" />
+ <usage value="AUDIO_USAGE_ANNOUNCEMENT"/>
+ </fadeableUsages>
+ <unfadeableContentTypes>
+ <contentType value="AUDIO_CONTENT_TYPE_SPEECH" />
+ <contentType value="AUDIO_CONTENT_TYPE_SONIFICATION" />
+ </unfadeableContentTypes>
+ <unfadeableAudioAttributes>
+ <audioAttributes>
+ <audioAttribute usage="AUDIO_USAGE_MEDIA" tags="oem_specific_tag1" />
+ </audioAttributes>
+ </unfadeableAudioAttributes>
+ <fadeOutConfigurations>
+ <fadeConfiguration fadeDurationMillis="500">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_MEDIA" />
+ <usage value="AUDIO_USAGE_GAME" />
+ <audioAttribute usage="AUDIO_USAGE_ASSISTANT" tags="oem_specific_tag2" />
+ </audioAttributes>
+ </fadeConfiguration>
+ <fadeConfiguration fadeDurationMillis="800">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
+ <usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
+ <usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
+ <usage value="AUDIO_USAGE_ASSISTANT" />
+ <usage value="AUDIO_USAGE_ANNOUNCEMENT"/>
+ </audioAttributes>
+ </fadeConfiguration>
+ </fadeOutConfigurations>
+ <fadeInConfigurations>
+ <fadeConfiguration fadeDurationMillis="1000">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_MEDIA" />
+ <usage value="AUDIO_USAGE_GAME" />
+ <audioAttribute usage="AUDIO_USAGE_ASSISTANT" tags="oem_specific_tag2" />
+ </audioAttributes>
+ </fadeConfiguration>
+ <fadeConfiguration fadeDurationMillis="800">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
+ <usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
+ <usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
+ <usage value="AUDIO_USAGE_ASSISTANT" />
+ <usage value="AUDIO_USAGE_ANNOUNCEMENT"/>
+ </audioAttributes>
+ </fadeConfiguration>
+ </fadeInConfigurations>
+ </config>
+ <config name="aggressive fading">
+ <fadeState value="FADE_STATE_ENABLED_DEFAULT" />
+ <fadeableUsages>
+ <usage value="AUDIO_USAGE_MEDIA" />
+ <usage value="AUDIO_USAGE_GAME" />
+ <usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
+ <usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
+ <usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
+ <usage value="AUDIO_USAGE_ASSISTANT" />
+ <usage value="AUDIO_USAGE_NOTIFICATION" />
+ <usage value="AUDIO_USAGE_ANNOUNCEMENT"/>
+ </fadeableUsages>
+ <unfadeableContentTypes>
+ <contentType value="AUDIO_CONTENT_TYPE_SPEECH" />
+ <contentType value="AUDIO_CONTENT_TYPE_MUSIC" />
+ </unfadeableContentTypes>
+ <unfadeableAudioAttributes>
+ <audioAttributes>
+ <audioAttribute usage="AUDIO_USAGE_MEDIA" tags="oem_specific_tag1" />
+ <audioAttribute usage="AUDIO_USAGE_ASSISTANT" tags="oem_projection_service" />
+ </audioAttributes>
+ </unfadeableAudioAttributes>
+ <fadeOutConfigurations>
+ <fadeConfiguration fadeDurationMillis="150">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_MEDIA" />
+ <usage value="AUDIO_USAGE_GAME" />
+ </audioAttributes>
+ </fadeConfiguration>
+ <fadeConfiguration fadeDurationMillis="400">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
+ <usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
+ <usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
+ <usage value="AUDIO_USAGE_ASSISTANT" />
+ <usage value="AUDIO_USAGE_ANNOUNCEMENT"/>
+ </audioAttributes>
+ </fadeConfiguration>
+ </fadeOutConfigurations>
+ <fadeInConfigurations>
+ <fadeConfiguration fadeDurationMillis="300">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_MEDIA" />
+ <usage value="AUDIO_USAGE_GAME" />
+ </audioAttributes>
+ </fadeConfiguration>
+ <fadeConfiguration fadeDurationMillis="550">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
+ <usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
+ <usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
+ <usage value="AUDIO_USAGE_ASSISTANT" />
+ <usage value="AUDIO_USAGE_ANNOUNCEMENT"/>
+ </audioAttributes>
+ </fadeConfiguration>
+ </fadeInConfigurations>
+ </config>
+ <config name="disabled fading">
+ <fadeState value="0" />
+ </config>
+ <config name="dynamic fading" defaultFadeOutDurationInMillis="800" defaultFadeInDurationInMillis="500">
+ <fadeState value="1" />
+ <fadeableUsages>
+ <usage value="AUDIO_USAGE_MEDIA" />
+ <usage value="AUDIO_USAGE_GAME" />
+ <usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
+ <usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
+ <usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
+ <usage value="AUDIO_USAGE_ASSISTANT" />
+ <usage value="AUDIO_USAGE_NOTIFICATION" />
+ <usage value="AUDIO_USAGE_ANNOUNCEMENT"/>
+ </fadeableUsages>
+ <unfadeableContentTypes>
+ <contentType value="AUDIO_CONTENT_TYPE_SPEECH" />
+ <contentType value="AUDIO_CONTENT_TYPE_MOVIE" />
+ </unfadeableContentTypes>
+ <unfadeableAudioAttributes>
+ <audioAttributes>
+ <audioAttribute usage="AUDIO_USAGE_MEDIA" tags="oem_specific_tag1" />
+ </audioAttributes>
+ </unfadeableAudioAttributes>
+ <fadeOutConfigurations>
+ <fadeConfiguration fadeDurationMillis="500">
+ <audioAttributes>
+ <audioAttribute usage="AUDIO_USAGE_ASSISTANT" tags="oem_specific_tag2" />
+ </audioAttributes>
+ </fadeConfiguration>
+ <fadeConfiguration fadeDurationMillis="800">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
+ <usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
+ <usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
+ <usage value="AUDIO_USAGE_ASSISTANT" />
+ <usage value="AUDIO_USAGE_ANNOUNCEMENT"/>
+ </audioAttributes>
+ </fadeConfiguration>
+ </fadeOutConfigurations>
+ <fadeInConfigurations>
+ <fadeConfiguration fadeDurationMillis="1000">
+ <audioAttributes>
+ <audioAttribute usage="AUDIO_USAGE_ASSISTANT" tags="oem_specific_tag2" />
+ </audioAttributes>
+ </fadeConfiguration>
+ <fadeConfiguration fadeDurationMillis="800">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
+ <usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
+ <usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
+ <usage value="AUDIO_USAGE_ASSISTANT" />
+ <usage value="AUDIO_USAGE_ANNOUNCEMENT"/>
+ </audioAttributes>
+ </fadeConfiguration>
+ </fadeInConfigurations>
+ </config>
+ </configs>
+</carAudioFadeConfiguration>
diff --git a/automotive/audiocontrol/aidl/default/converter/test/multi_zone_car_audio_configuration.xml b/automotive/audiocontrol/aidl/default/converter/test/multi_zone_car_audio_configuration.xml
new file mode 100644
index 0000000..f0c9081
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/converter/test/multi_zone_car_audio_configuration.xml
@@ -0,0 +1,196 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 The Android Open Source Project
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<carAudioConfiguration version="4">
+ <deviceConfigurations>
+ <deviceConfiguration name="useHalDuckingSignals" value="false" />
+ <deviceConfiguration name="useCoreAudioRouting" value="true" />
+ <deviceConfiguration name="useCoreAudioVolume" value="true" />
+ <deviceConfiguration name="useCarVolumeGroupMuting" value="false" />
+ </deviceConfigurations>
+ <oemContexts>
+ <oemContext name="oem_context">
+ <audioAttributes>
+ <audioAttribute usage="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"
+ contentType="AUDIO_CONTENT_TYPE_SPEECH"
+ tags="oem=extension_8675309" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_music">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_MEDIA" />
+ <usage value="AUDIO_USAGE_GAME" />
+ <usage value="AUDIO_USAGE_UNKNOWN" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_notification">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_NOTIFICATION" />
+ <usage value="AUDIO_USAGE_NOTIFICATION_EVENT" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_voice_command">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_ASSISTANT" />
+ <usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
+ <usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_call">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_VOICE_COMMUNICATION" />
+ <usage value="AUDIO_USAGE_CALL_ASSISTANT" />
+ <usage value="AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_call_ring">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_alarm">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_ALARM" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_system_sound">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
+ <usage value="AUDIO_USAGE_EMERGENCY" />
+ <usage value="AUDIO_USAGE_SAFETY" />
+ <usage value="AUDIO_USAGE_VEHICLE_STATUS" />
+ <usage value="AUDIO_USAGE_ANNOUNCEMENT" />
+ </audioAttributes>
+ </oemContext>
+ </oemContexts>
+ <activationVolumeConfigs>
+ <activationVolumeConfig name="on_boot_config">
+ <activationVolumeConfigEntry maxActivationVolumePercentage="80" invocationType="onBoot" />
+ </activationVolumeConfig>
+ <activationVolumeConfig name="on_source_changed_config">
+ <activationVolumeConfigEntry minActivationVolumePercentage="20" maxActivationVolumePercentage="80" invocationType="onSourceChanged" />
+ </activationVolumeConfig>
+ <activationVolumeConfig name="on_playback_changed_config">
+ <activationVolumeConfigEntry minActivationVolumePercentage="10" maxActivationVolumePercentage="90" invocationType="onPlaybackChanged" />
+ </activationVolumeConfig>
+ </activationVolumeConfigs>
+ <mirroringDevices>
+ <mirroringDevice address="mirror_bus_device_three"/>
+ <mirroringDevice address="mirror_bus_device_four"/>
+ </mirroringDevices>
+ <zones>
+ <zone name="driver zone" isPrimary="true" audioZoneId="0" occupantZoneId="0">
+ <zoneConfigs>
+ <zoneConfig name="driver zone config 0" isDefault="true">
+ <volumeGroups>
+ <group name="entertainment" activationConfig="on_boot_config">
+ <device address="BUS00_MEDIA">
+ <context context="oem_music"/>
+ </device>
+ </group>
+ <group name="navvoicecommand" activationConfig="on_source_changed_config">
+ <device address="BUS02_NAV_GUIDANCE">
+ <context context="oem_voice_command"/>
+ </device>
+ </group>
+ <group name="telringvol" activationConfig="on_playback_changed_config">
+ <device address="BUS03_PHONE">
+ <context context="oem_call"/>
+ <context context="oem_call_ring"/>
+ </device>
+ </group>
+ <group name="systemalarm" activationConfig="on_source_changed_config">
+ <device address="BUS01_SYS_NOTIFICATION">
+ <context context="oem_alarm"/>
+ <context context="oem_system_sound"/>
+ <context context="oem_notification"/>
+ </device>
+ </group>
+ </volumeGroups>
+ <applyFadeConfigs>
+ <fadeConfig name="relaxed fading" isDefault="true">
+ </fadeConfig>
+ <fadeConfig name="aggressive fading">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_VOICE_COMMUNICATION" />
+ <usage value="AUDIO_USAGE_ANNOUNCEMENT" />
+ <usage value="AUDIO_USAGE_VEHICLE_STATUS" />
+ <usage value="AUDIO_USAGE_SAFETY" />
+ </audioAttributes>
+ </fadeConfig>
+ <fadeConfig name="disabled fading">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_EMERGENCY" />
+ </audioAttributes>
+ </fadeConfig>
+ </applyFadeConfigs>
+ </zoneConfig>
+ </zoneConfigs>
+ </zone>
+ <zone name="front passenger zone" audioZoneId="1" occupantZoneId="1">
+ <zoneConfigs>
+ <zoneConfig name="front passenger config 0" isDefault="true">
+ <volumeGroups>
+ <group name="entertainment" activationConfig="on_boot_config">
+ <device address="BUS_FRONT">
+ <context context="oem_music"/>
+ <context context="oem_voice_command"/>
+ <context context="oem_call"/>
+ <context context="oem_call_ring"/>
+ <context context="oem_alarm"/>
+ <context context="oem_system_sound"/>
+ <context context="oem_notification"/>
+ </device>
+ </group>
+ </volumeGroups>
+ <applyFadeConfigs>
+ <fadeConfig name="relaxed fading" isDefault="true">
+ </fadeConfig>
+ <fadeConfig name="disabled fading">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_EMERGENCY" />
+ </audioAttributes>
+ </fadeConfig>
+ </applyFadeConfigs>
+ </zoneConfig>
+ </zoneConfigs>
+ </zone>
+ <zone name="rear seat zone" audioZoneId="2" occupantZoneId="2">
+ <zoneConfigs>
+ <zoneConfig name="rear seat config 0" isDefault="true">
+ <volumeGroups>
+ <group name="entertainment" activationConfig="on_boot_config">
+ <device address="BUS_REAR">
+ <context context="oem_music"/>
+ <context context="oem_voice_command"/>
+ <context context="oem_call"/>
+ <context context="oem_call_ring"/>
+ <context context="oem_alarm"/>
+ <context context="oem_system_sound"/>
+ <context context="oem_notification"/>
+ </device>
+ </group>
+ </volumeGroups>
+ <applyFadeConfigs>
+ <fadeConfig name="relaxed fading" isDefault="true">
+ </fadeConfig>
+ <fadeConfig name="disabled fading">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_EMERGENCY" />
+ </audioAttributes>
+ </fadeConfig>
+ </applyFadeConfigs>
+ </zoneConfig>
+ </zoneConfigs>
+ </zone>
+ </zones>
+</carAudioConfiguration>
diff --git a/automotive/audiocontrol/aidl/default/converter/test/simple_car_audio_configuration.xml b/automotive/audiocontrol/aidl/default/converter/test/simple_car_audio_configuration.xml
new file mode 100644
index 0000000..a6f5317
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/converter/test/simple_car_audio_configuration.xml
@@ -0,0 +1,233 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 The Android Open Source Project
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<carAudioConfiguration version="4">
+ <deviceConfigurations>
+ <deviceConfiguration name="useHalDuckingSignals" value="true" />
+ <deviceConfiguration name="useCoreAudioRouting" value="false" />
+ <deviceConfiguration name="useCoreAudioVolume" value="false" />
+ <deviceConfiguration name="useCarVolumeGroupMuting" value="true" />
+ </deviceConfigurations>
+ <oemContexts>
+ <oemContext name="oem_context">
+ <audioAttributes>
+ <audioAttribute usage="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"
+ contentType="AUDIO_CONTENT_TYPE_SPEECH"
+ tags="oem=extension_8675309" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_music">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_MEDIA" />
+ <usage value="AUDIO_USAGE_GAME" />
+ <usage value="AUDIO_USAGE_UNKNOWN" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_notification">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_NOTIFICATION" />
+ <usage value="AUDIO_USAGE_NOTIFICATION_EVENT" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_voice_command">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_ASSISTANT" />
+ <usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
+ <usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_call">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_VOICE_COMMUNICATION" />
+ <usage value="AUDIO_USAGE_CALL_ASSISTANT" />
+ <usage value="AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_call_ring">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_alarm">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_ALARM" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_system_sound">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
+ <usage value="AUDIO_USAGE_EMERGENCY" />
+ <usage value="AUDIO_USAGE_SAFETY" />
+ <usage value="AUDIO_USAGE_VEHICLE_STATUS" />
+ <usage value="AUDIO_USAGE_ANNOUNCEMENT" />
+ </audioAttributes>
+ </oemContext>
+ </oemContexts>
+ <activationVolumeConfigs>
+ <activationVolumeConfig name="on_boot_config">
+ <activationVolumeConfigEntry maxActivationVolumePercentage="80" invocationType="onBoot" />
+ </activationVolumeConfig>
+ <activationVolumeConfig name="on_source_changed_config">
+ <activationVolumeConfigEntry minActivationVolumePercentage="20" maxActivationVolumePercentage="80" invocationType="onSourceChanged" />
+ </activationVolumeConfig>
+ <activationVolumeConfig name="on_playback_changed_config">
+ <activationVolumeConfigEntry minActivationVolumePercentage="10" maxActivationVolumePercentage="90" invocationType="onPlaybackChanged" />
+ </activationVolumeConfig>
+ </activationVolumeConfigs>
+ <mirroringDevices>
+ <mirroringDevice address="mirror_bus_device_1"/>
+ <mirroringDevice address="mirror_bus_device_2"/>
+ </mirroringDevices>
+ <zones>
+ <zone name="primary zone" isPrimary="true" audioZoneId="0" occupantZoneId="0">
+ <inputDevices>
+ <inputDevice address="fm_tuner" type="AUDIO_DEVICE_IN_FM_TUNER" />
+ <inputDevice address="built_in_mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" />
+ <inputDevice address="in_bus_device" type="AUDIO_DEVICE_IN_BUS" />
+ </inputDevices>
+ <zoneConfigs>
+ <zoneConfig name="primary zone config 0" isDefault="true">
+ <volumeGroups>
+ <group name="entertainment" activationConfig="on_boot_config">
+ <device address="BUS00_MEDIA">
+ <context context="oem_music"/>
+ </device>
+ </group>
+ <group name="navvoicecommand" activationConfig="on_source_changed_config">
+ <device address="BUS02_NAV_GUIDANCE">
+ <context context="oem_voice_command"/>
+ </device>
+ </group>
+ <group name="telringvol" activationConfig="on_playback_changed_config">
+ <device address="BUS03_PHONE">
+ <context context="oem_call"/>
+ <context context="oem_call_ring"/>
+ </device>
+ </group>
+ <group name="systemalarm" activationConfig="on_source_changed_config">
+ <device address="BUS01_SYS_NOTIFICATION">
+ <context context="oem_alarm"/>
+ <context context="oem_system_sound"/>
+ <context context="oem_notification"/>
+ </device>
+ </group>
+ </volumeGroups>
+ <applyFadeConfigs>
+ <fadeConfig name="relaxed fading" isDefault="true">
+ </fadeConfig>
+ <fadeConfig name="aggressive fading">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_VOICE_COMMUNICATION" />
+ <usage value="AUDIO_USAGE_ANNOUNCEMENT" />
+ <usage value="AUDIO_USAGE_VEHICLE_STATUS" />
+ <usage value="AUDIO_USAGE_SAFETY" />
+ </audioAttributes>
+ </fadeConfig>
+ <fadeConfig name="disabled fading">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_EMERGENCY" />
+ </audioAttributes>
+ </fadeConfig>
+ </applyFadeConfigs>
+ </zoneConfig>
+ <zoneConfig name="primary zone BT media">
+ <volumeGroups>
+ <group name="entertainment" activationConfig="on_boot_config">
+ <device type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP" address="temp">
+ <context context="oem_music"/>
+ </device>
+ </group>
+ <group name="navvoicecommand" activationConfig="on_source_changed_config">
+ <device address="BUS02_NAV_GUIDANCE">
+ <context context="oem_voice_command"/>
+ </device>
+ </group>
+ <group name="telringvol" activationConfig="on_playback_changed_config">
+ <device address="BUS03_PHONE">
+ <context context="oem_call"/>
+ <context context="oem_call_ring"/>
+ </device>
+ </group>
+ <group name="systemalarm" activationConfig="on_source_changed_config">
+ <device address="BUS01_SYS_NOTIFICATION">
+ <context context="oem_alarm"/>
+ <context context="oem_system_sound"/>
+ <context context="oem_notification"/>
+ </device>
+ </group>
+ </volumeGroups>
+ <applyFadeConfigs>
+ <fadeConfig name="dynamic fading" isDefault="true">
+ </fadeConfig>
+ <fadeConfig name="aggressive fading">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_VOICE_COMMUNICATION" />
+ <usage value="AUDIO_USAGE_ANNOUNCEMENT" />
+ <usage value="AUDIO_USAGE_VEHICLE_STATUS" />
+ <usage value="AUDIO_USAGE_SAFETY" />
+ </audioAttributes>
+ </fadeConfig>
+ <fadeConfig name="disabled fading">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_EMERGENCY" />
+ </audioAttributes>
+ </fadeConfig>
+ </applyFadeConfigs>
+ </zoneConfig>
+ <zoneConfig name="primary zone USB media">
+ <volumeGroups>
+ <group name="entertainment" activationConfig="on_boot_config">
+ <device type="AUDIO_DEVICE_OUT_USB_HEADSET">
+ <context context="oem_music"/>
+ </device>
+ </group>
+ <group name="navvoicecommand" activationConfig="on_source_changed_config">
+ <device address="BUS02_NAV_GUIDANCE">
+ <context context="oem_voice_command"/>
+ </device>
+ </group>
+ <group name="telringvol" activationConfig="on_playback_changed_config">
+ <device address="BUS03_PHONE">
+ <context context="oem_call"/>
+ <context context="oem_call_ring"/>
+ </device>
+ </group>
+ <group name="systemalarm" activationConfig="on_source_changed_config">
+ <device address="BUS01_SYS_NOTIFICATION">
+ <context context="oem_alarm"/>
+ <context context="oem_system_sound"/>
+ <context context="oem_notification"/>
+ </device>
+ </group>
+ </volumeGroups>
+ <applyFadeConfigs>
+ <fadeConfig name="dynamic fading" isDefault="true">
+ </fadeConfig>
+ <fadeConfig name="aggressive fading">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_VOICE_COMMUNICATION" />
+ <usage value="AUDIO_USAGE_ANNOUNCEMENT" />
+ <usage value="AUDIO_USAGE_VEHICLE_STATUS" />
+ <usage value="AUDIO_USAGE_SAFETY" />
+ </audioAttributes>
+ </fadeConfig>
+ <fadeConfig name="disabled fading">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_EMERGENCY" />
+ </audioAttributes>
+ </fadeConfig>
+ </applyFadeConfigs>
+ </zoneConfig>
+ </zoneConfigs>
+ </zone>
+ </zones>
+</carAudioConfiguration>
diff --git a/automotive/audiocontrol/aidl/default/converter/test/simple_car_audio_configuration_with_device_type.xml b/automotive/audiocontrol/aidl/default/converter/test/simple_car_audio_configuration_with_device_type.xml
new file mode 100644
index 0000000..eec9db9
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/converter/test/simple_car_audio_configuration_with_device_type.xml
@@ -0,0 +1,233 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 The Android Open Source Project
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<carAudioConfiguration version="4">
+ <deviceConfigurations>
+ <deviceConfiguration name="useHalDuckingSignals" value="true" />
+ <deviceConfiguration name="useCoreAudioRouting" value="false" />
+ <deviceConfiguration name="useCoreAudioVolume" value="false" />
+ <deviceConfiguration name="useCarVolumeGroupMuting" value="true" />
+ </deviceConfigurations>
+ <oemContexts>
+ <oemContext name="oem_context">
+ <audioAttributes>
+ <audioAttribute usage="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"
+ contentType="AUDIO_CONTENT_TYPE_SPEECH"
+ tags="oem=extension_8675309" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_music">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_MEDIA" />
+ <usage value="AUDIO_USAGE_GAME" />
+ <usage value="AUDIO_USAGE_UNKNOWN" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_notification">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_NOTIFICATION" />
+ <usage value="AUDIO_USAGE_NOTIFICATION_EVENT" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_voice_command">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_ASSISTANT" />
+ <usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
+ <usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_call">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_VOICE_COMMUNICATION" />
+ <usage value="AUDIO_USAGE_CALL_ASSISTANT" />
+ <usage value="AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_call_ring">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_alarm">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_ALARM" />
+ </audioAttributes>
+ </oemContext>
+ <oemContext name="oem_system_sound">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
+ <usage value="AUDIO_USAGE_EMERGENCY" />
+ <usage value="AUDIO_USAGE_SAFETY" />
+ <usage value="AUDIO_USAGE_VEHICLE_STATUS" />
+ <usage value="AUDIO_USAGE_ANNOUNCEMENT" />
+ </audioAttributes>
+ </oemContext>
+ </oemContexts>
+ <activationVolumeConfigs>
+ <activationVolumeConfig name="on_boot_config">
+ <activationVolumeConfigEntry maxActivationVolumePercentage="80" invocationType="onBoot" />
+ </activationVolumeConfig>
+ <activationVolumeConfig name="on_source_changed_config">
+ <activationVolumeConfigEntry minActivationVolumePercentage="20" maxActivationVolumePercentage="80" invocationType="onSourceChanged" />
+ </activationVolumeConfig>
+ <activationVolumeConfig name="on_playback_changed_config">
+ <activationVolumeConfigEntry minActivationVolumePercentage="10" maxActivationVolumePercentage="90" invocationType="onPlaybackChanged" />
+ </activationVolumeConfig>
+ </activationVolumeConfigs>
+ <mirroringDevices>
+ <mirroringDevice address="mirror_bus_device_1"/>
+ <mirroringDevice address="mirror_bus_device_2"/>
+ </mirroringDevices>
+ <zones>
+ <zone name="primary zone" isPrimary="true" audioZoneId="0" occupantZoneId="0">
+ <inputDevices>
+ <inputDevice address="fm_tuner" type="AUDIO_DEVICE_IN_FM_TUNER" />
+ <inputDevice address="built_in_mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" />
+ <inputDevice address="in_bus_device" type="AUDIO_DEVICE_IN_BUS" />
+ </inputDevices>
+ <zoneConfigs>
+ <zoneConfig name="primary zone config 0" isDefault="true">
+ <volumeGroups>
+ <group name="entertainment" activationConfig="on_boot_config">
+ <device address="BUS00_MEDIA">
+ <context context="oem_music"/>
+ </device>
+ </group>
+ <group name="navvoicecommand" activationConfig="on_source_changed_config">
+ <device address="BUS02_NAV_GUIDANCE">
+ <context context="oem_voice_command"/>
+ </device>
+ </group>
+ <group name="telringvol" activationConfig="on_playback_changed_config">
+ <device address="BUS03_PHONE">
+ <context context="oem_call"/>
+ <context context="oem_call_ring"/>
+ </device>
+ </group>
+ <group name="systemalarm" activationConfig="on_source_changed_config">
+ <device address="BUS01_SYS_NOTIFICATION">
+ <context context="oem_alarm"/>
+ <context context="oem_system_sound"/>
+ <context context="oem_notification"/>
+ </device>
+ </group>
+ </volumeGroups>
+ <applyFadeConfigs>
+ <fadeConfig name="relaxed fading" isDefault="true">
+ </fadeConfig>
+ <fadeConfig name="aggressive fading">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_VOICE_COMMUNICATION" />
+ <usage value="AUDIO_USAGE_ANNOUNCEMENT" />
+ <usage value="AUDIO_USAGE_VEHICLE_STATUS" />
+ <usage value="AUDIO_USAGE_SAFETY" />
+ </audioAttributes>
+ </fadeConfig>
+ <fadeConfig name="disabled fading">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_EMERGENCY" />
+ </audioAttributes>
+ </fadeConfig>
+ </applyFadeConfigs>
+ </zoneConfig>
+ <zoneConfig name="primary zone BT media">
+ <volumeGroups>
+ <group name="entertainment" activationConfig="on_boot_config">
+ <device type="TYPE_BLUETOOTH_A2DP" address="temp">
+ <context context="oem_music"/>
+ </device>
+ </group>
+ <group name="navvoicecommand" activationConfig="on_source_changed_config">
+ <device address="BUS02_NAV_GUIDANCE">
+ <context context="oem_voice_command"/>
+ </device>
+ </group>
+ <group name="telringvol" activationConfig="on_playback_changed_config">
+ <device address="BUS03_PHONE">
+ <context context="oem_call"/>
+ <context context="oem_call_ring"/>
+ </device>
+ </group>
+ <group name="systemalarm" activationConfig="on_source_changed_config">
+ <device address="BUS01_SYS_NOTIFICATION">
+ <context context="oem_alarm"/>
+ <context context="oem_system_sound"/>
+ <context context="oem_notification"/>
+ </device>
+ </group>
+ </volumeGroups>
+ <applyFadeConfigs>
+ <fadeConfig name="dynamic fading" isDefault="true">
+ </fadeConfig>
+ <fadeConfig name="aggressive fading">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_VOICE_COMMUNICATION" />
+ <usage value="AUDIO_USAGE_ANNOUNCEMENT" />
+ <usage value="AUDIO_USAGE_VEHICLE_STATUS" />
+ <usage value="AUDIO_USAGE_SAFETY" />
+ </audioAttributes>
+ </fadeConfig>
+ <fadeConfig name="disabled fading">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_EMERGENCY" />
+ </audioAttributes>
+ </fadeConfig>
+ </applyFadeConfigs>
+ </zoneConfig>
+ <zoneConfig name="primary zone USB media">
+ <volumeGroups>
+ <group name="entertainment" activationConfig="on_boot_config">
+ <device type="TYPE_USB_HEADSET">
+ <context context="oem_music"/>
+ </device>
+ </group>
+ <group name="navvoicecommand" activationConfig="on_source_changed_config">
+ <device address="BUS02_NAV_GUIDANCE">
+ <context context="oem_voice_command"/>
+ </device>
+ </group>
+ <group name="telringvol" activationConfig="on_playback_changed_config">
+ <device address="BUS03_PHONE">
+ <context context="oem_call"/>
+ <context context="oem_call_ring"/>
+ </device>
+ </group>
+ <group name="systemalarm" activationConfig="on_source_changed_config">
+ <device address="BUS01_SYS_NOTIFICATION">
+ <context context="oem_alarm"/>
+ <context context="oem_system_sound"/>
+ <context context="oem_notification"/>
+ </device>
+ </group>
+ </volumeGroups>
+ <applyFadeConfigs>
+ <fadeConfig name="dynamic fading" isDefault="true">
+ </fadeConfig>
+ <fadeConfig name="aggressive fading">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_VOICE_COMMUNICATION" />
+ <usage value="AUDIO_USAGE_ANNOUNCEMENT" />
+ <usage value="AUDIO_USAGE_VEHICLE_STATUS" />
+ <usage value="AUDIO_USAGE_SAFETY" />
+ </audioAttributes>
+ </fadeConfig>
+ <fadeConfig name="disabled fading">
+ <audioAttributes>
+ <usage value="AUDIO_USAGE_EMERGENCY" />
+ </audioAttributes>
+ </fadeConfig>
+ </applyFadeConfigs>
+ </zoneConfig>
+ </zoneConfigs>
+ </zone>
+ </zones>
+</carAudioConfiguration>
diff --git a/automotive/audiocontrol/aidl/default/loaders/config/Android.bp b/automotive/audiocontrol/aidl/default/loaders/config/Android.bp
new file mode 100644
index 0000000..0d5eb81
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/loaders/config/Android.bp
@@ -0,0 +1,45 @@
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+xsd_config {
+ name: "car_audio_configuration_xsd",
+ srcs: ["car_audio_configuration.xsd"],
+ package_name: "android.hardware.automotive.audiocontrol",
+ nullability: true,
+}
+
+cc_defaults {
+ name: "car.audio.configuration.xsd.default",
+ static_libs: [
+ "libxml2",
+ ],
+ generated_sources: [
+ "car_audio_configuration_xsd",
+ ],
+ generated_headers: [
+ "car_audio_configuration_xsd",
+ ],
+ header_libs: [
+ "libxsdc-utils",
+ ],
+}
diff --git a/automotive/audiocontrol/aidl/default/loaders/config/api/current.txt b/automotive/audiocontrol/aidl/default/loaders/config/api/current.txt
new file mode 100644
index 0000000..c87b8c6
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/loaders/config/api/current.txt
@@ -0,0 +1,331 @@
+// Signature format: 2.0
+package android.hardware.automotive.audiocontrol {
+
+ public enum ActivationType {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.hardware.automotive.audiocontrol.ActivationType onBoot;
+ enum_constant public static final android.hardware.automotive.audiocontrol.ActivationType onPlaybackChanged;
+ enum_constant public static final android.hardware.automotive.audiocontrol.ActivationType onSourceChanged;
+ }
+
+ public class ActivationVolumeConfigEntryType {
+ ctor public ActivationVolumeConfigEntryType();
+ method @Nullable public android.hardware.automotive.audiocontrol.ActivationType getInvocationType();
+ method @Nullable public String getMaxActivationVolumePercentage();
+ method @Nullable public String getMinActivationVolumePercentage();
+ method public void setInvocationType(@Nullable android.hardware.automotive.audiocontrol.ActivationType);
+ method public void setMaxActivationVolumePercentage(@Nullable String);
+ method public void setMinActivationVolumePercentage(@Nullable String);
+ }
+
+ public class ActivationVolumeConfigType {
+ ctor public ActivationVolumeConfigType();
+ method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.ActivationVolumeConfigEntryType> getActivationVolumeConfigEntry();
+ method @Nullable public String getName();
+ method public void setName(@Nullable String);
+ }
+
+ public class ActivationVolumeConfigsType {
+ ctor public ActivationVolumeConfigsType();
+ method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.ActivationVolumeConfigType> getActivationVolumeConfig();
+ }
+
+ public class ApplyFadeConfigType {
+ ctor public ApplyFadeConfigType();
+ method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.AudioAttributeUsagesType> getAudioAttributes();
+ method @Nullable public boolean getIsDefault();
+ method @Nullable public String getName();
+ method public void setIsDefault(@Nullable boolean);
+ method public void setName(@Nullable String);
+ }
+
+ public class ApplyFadeConfigsType {
+ ctor public ApplyFadeConfigsType();
+ method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.ApplyFadeConfigType> getFadeConfig();
+ }
+
+ public class AttributesType {
+ ctor public AttributesType();
+ method @Nullable public android.hardware.automotive.audiocontrol.ContentTypeEnum getContentType();
+ method @Nullable public String getTags();
+ method @Nullable public android.hardware.automotive.audiocontrol.UsageEnumType getUsage();
+ method public void setContentType(@Nullable android.hardware.automotive.audiocontrol.ContentTypeEnum);
+ method public void setTags(@Nullable String);
+ method public void setUsage(@Nullable android.hardware.automotive.audiocontrol.UsageEnumType);
+ }
+
+ public class AudioAttributeUsagesType {
+ ctor public AudioAttributeUsagesType();
+ method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.UsageType> getUsage();
+ }
+
+ public class AudioAttributesUsagesType {
+ ctor public AudioAttributesUsagesType();
+ method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.AttributesType> getAudioAttribute_optional();
+ method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.UsageType> getUsage_optional();
+ }
+
+ public class CarAudioConfigurationType {
+ ctor public CarAudioConfigurationType();
+ method @Nullable public android.hardware.automotive.audiocontrol.ActivationVolumeConfigsType getActivationVolumeConfigs();
+ method @Nullable public android.hardware.automotive.audiocontrol.DeviceConfigurationsType getDeviceConfigurations();
+ method @Nullable public android.hardware.automotive.audiocontrol.MirroringDevicesType getMirroringDevices();
+ method @Nullable public android.hardware.automotive.audiocontrol.OemContextsType getOemContexts();
+ method @Nullable public String getVersion();
+ method @Nullable public android.hardware.automotive.audiocontrol.ZonesType getZones();
+ method public void setActivationVolumeConfigs(@Nullable android.hardware.automotive.audiocontrol.ActivationVolumeConfigsType);
+ method public void setDeviceConfigurations(@Nullable android.hardware.automotive.audiocontrol.DeviceConfigurationsType);
+ method public void setMirroringDevices(@Nullable android.hardware.automotive.audiocontrol.MirroringDevicesType);
+ method public void setOemContexts(@Nullable android.hardware.automotive.audiocontrol.OemContextsType);
+ method public void setVersion(@Nullable String);
+ method public void setZones(@Nullable android.hardware.automotive.audiocontrol.ZonesType);
+ }
+
+ public class ContentType {
+ ctor public ContentType();
+ method @Nullable public android.hardware.automotive.audiocontrol.ContentTypeEnum getValue();
+ method public void setValue(@Nullable android.hardware.automotive.audiocontrol.ContentTypeEnum);
+ }
+
+ public enum ContentTypeEnum {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.hardware.automotive.audiocontrol.ContentTypeEnum AUDIO_CONTENT_TYPE_MOVIE;
+ enum_constant public static final android.hardware.automotive.audiocontrol.ContentTypeEnum AUDIO_CONTENT_TYPE_MUSIC;
+ enum_constant public static final android.hardware.automotive.audiocontrol.ContentTypeEnum AUDIO_CONTENT_TYPE_SONIFICATION;
+ enum_constant public static final android.hardware.automotive.audiocontrol.ContentTypeEnum AUDIO_CONTENT_TYPE_SPEECH;
+ enum_constant public static final android.hardware.automotive.audiocontrol.ContentTypeEnum AUDIO_CONTENT_TYPE_UNKNOWN;
+ }
+
+ public class ContextNameType {
+ ctor public ContextNameType();
+ method @Nullable public String getContext();
+ method public void setContext(@Nullable String);
+ }
+
+ public class DeviceConfigurationType {
+ ctor public DeviceConfigurationType();
+ method @Nullable public String getName();
+ method @Nullable public String getValue();
+ method public void setName(@Nullable String);
+ method public void setValue(@Nullable String);
+ }
+
+ public class DeviceConfigurationsType {
+ ctor public DeviceConfigurationsType();
+ method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.DeviceConfigurationType> getDeviceConfiguration();
+ }
+
+ public class DeviceRoutesType {
+ ctor public DeviceRoutesType();
+ method @Nullable public String getAddress();
+ method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.ContextNameType> getContext();
+ method @Nullable public android.hardware.automotive.audiocontrol.OutDeviceType getType();
+ method public void setAddress(@Nullable String);
+ method public void setType(@Nullable android.hardware.automotive.audiocontrol.OutDeviceType);
+ }
+
+ public enum InDeviceType {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_AMBIENT;
+ enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET;
+ enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_AUX_DIGITAL;
+ enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_BACK_MIC;
+ enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_BLUETOOTH_A2DP;
+ enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_BLUETOOTH_BLE;
+ enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
+ enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_BUILTIN_MIC;
+ enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_BUS;
+ enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_COMMUNICATION;
+ enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_DEFAULT;
+ enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET;
+ enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_ECHO_REFERENCE;
+ enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_FM_TUNER;
+ enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_HDMI;
+ enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_HDMI_ARC;
+ enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_IP;
+ enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_LINE;
+ enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_LOOPBACK;
+ enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_PROXY;
+ enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_REMOTE_SUBMIX;
+ enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_SPDIF;
+ enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_STUB;
+ enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_TELEPHONY_RX;
+ enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_TV_TUNER;
+ enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_USB_ACCESSORY;
+ enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_USB_DEVICE;
+ enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_USB_HEADSET;
+ enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_VOICE_CALL;
+ enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_WIRED_HEADSET;
+ }
+
+ public class InputDeviceType {
+ ctor public InputDeviceType();
+ method @Nullable public String getAddress();
+ method @Nullable public android.hardware.automotive.audiocontrol.InDeviceType getType();
+ method public void setAddress(@Nullable String);
+ method public void setType(@Nullable android.hardware.automotive.audiocontrol.InDeviceType);
+ }
+
+ public class InputDevicesType {
+ ctor public InputDevicesType();
+ method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.InputDeviceType> getInputDevice();
+ }
+
+ public class MirroringDevice {
+ ctor public MirroringDevice();
+ method @Nullable public String getAddress();
+ method public void setAddress(@Nullable String);
+ }
+
+ public class MirroringDevicesType {
+ ctor public MirroringDevicesType();
+ method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.MirroringDevice> getMirroringDevice();
+ }
+
+ public class OemContextType {
+ ctor public OemContextType();
+ method @Nullable public android.hardware.automotive.audiocontrol.AudioAttributesUsagesType getAudioAttributes();
+ method @Nullable public String getId();
+ method @Nullable public String getName();
+ method public void setAudioAttributes(@Nullable android.hardware.automotive.audiocontrol.AudioAttributesUsagesType);
+ method public void setId(@Nullable String);
+ method public void setName(@Nullable String);
+ }
+
+ public class OemContextsType {
+ ctor public OemContextsType();
+ method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.OemContextType> getOemContext();
+ }
+
+ public enum OutDeviceType {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_AUX_DIGITAL;
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_AUX_LINE;
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_BLE_BROADCAST;
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_BLE_HEADSET;
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_BLE_SPEAKER;
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_BUS;
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_DEFAULT;
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_HDMI;
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_HDMI_ARC;
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_HDMI_EARC;
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_LINE;
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_SPEAKER;
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_SPEAKER_SAFE;
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_USB_ACCESSORY;
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_USB_DEVICE;
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_USB_HEADSET;
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_WIRED_HEADSET;
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType TYPE_AUX_LINE;
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType TYPE_BLE_BROADCAST;
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType TYPE_BLE_HEADSET;
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType TYPE_BLE_SPEAKER;
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType TYPE_BLUETOOTH_A2DP;
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType TYPE_BUILTIN_SPEAKER;
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType TYPE_BUS;
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType TYPE_HDMI;
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType TYPE_USB_ACCESSORY;
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType TYPE_USB_DEVICE;
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType TYPE_USB_HEADSET;
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType TYPE_WIRED_HEADPHONES;
+ enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType TYPE_WIRED_HEADSET;
+ }
+
+ public enum UsageEnumType {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_ALARM;
+ enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_ANNOUNCEMENT;
+ enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY;
+ enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE;
+ enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_ASSISTANCE_SONIFICATION;
+ enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_ASSISTANT;
+ enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_CALL_ASSISTANT;
+ enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_EMERGENCY;
+ enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_GAME;
+ enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_MEDIA;
+ enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_NOTIFICATION;
+ enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED;
+ enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT;
+ enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST;
+ enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_NOTIFICATION_EVENT;
+ enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE;
+ enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_SAFETY;
+ enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_UNKNOWN;
+ enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_VEHICLE_STATUS;
+ enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_VIRTUAL_SOURCE;
+ enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_VOICE_COMMUNICATION;
+ enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING;
+ }
+
+ public class UsageType {
+ ctor public UsageType();
+ method @Nullable public android.hardware.automotive.audiocontrol.UsageEnumType getValue();
+ method public void setValue(@Nullable android.hardware.automotive.audiocontrol.UsageEnumType);
+ }
+
+ public class VolumeGroupType {
+ ctor public VolumeGroupType();
+ method @Nullable public String getActivationConfig();
+ method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.DeviceRoutesType> getDevice();
+ method @Nullable public String getName();
+ method public void setActivationConfig(@Nullable String);
+ method public void setName(@Nullable String);
+ }
+
+ public class VolumeGroupsType {
+ ctor public VolumeGroupsType();
+ method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.VolumeGroupType> getGroup();
+ }
+
+ public class XmlParser {
+ ctor public XmlParser();
+ method @Nullable public static android.hardware.automotive.audiocontrol.CarAudioConfigurationType read(@NonNull java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method @Nullable public static String readText(@NonNull org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public static void skip(@NonNull org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ }
+
+ public class ZoneConfigType {
+ ctor public ZoneConfigType();
+ method @Nullable public android.hardware.automotive.audiocontrol.ApplyFadeConfigsType getApplyFadeConfigs();
+ method @Nullable public boolean getIsDefault();
+ method @Nullable public String getName();
+ method @Nullable public android.hardware.automotive.audiocontrol.VolumeGroupsType getVolumeGroups();
+ method public void setApplyFadeConfigs(@Nullable android.hardware.automotive.audiocontrol.ApplyFadeConfigsType);
+ method public void setIsDefault(@Nullable boolean);
+ method public void setName(@Nullable String);
+ method public void setVolumeGroups(@Nullable android.hardware.automotive.audiocontrol.VolumeGroupsType);
+ }
+
+ public class ZoneConfigsType {
+ ctor public ZoneConfigsType();
+ method @Nullable public android.hardware.automotive.audiocontrol.ZoneConfigType getZoneConfig();
+ method public void setZoneConfig(@Nullable android.hardware.automotive.audiocontrol.ZoneConfigType);
+ }
+
+ public class ZoneType {
+ ctor public ZoneType();
+ method @Nullable public String getAudioZoneId();
+ method @Nullable public android.hardware.automotive.audiocontrol.InputDevicesType getInputDevices();
+ method @Nullable public boolean getIsPrimary();
+ method @Nullable public String getName();
+ method @Nullable public String getOccupantZoneId();
+ method @Nullable public android.hardware.automotive.audiocontrol.ZoneConfigsType getZoneConfigs();
+ method public void setAudioZoneId(@Nullable String);
+ method public void setInputDevices(@Nullable android.hardware.automotive.audiocontrol.InputDevicesType);
+ method public void setIsPrimary(@Nullable boolean);
+ method public void setName(@Nullable String);
+ method public void setOccupantZoneId(@Nullable String);
+ method public void setZoneConfigs(@Nullable android.hardware.automotive.audiocontrol.ZoneConfigsType);
+ }
+
+ public class ZonesType {
+ ctor public ZonesType();
+ method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.ZoneType> getZone();
+ }
+
+}
+
diff --git a/automotive/audiocontrol/aidl/default/loaders/config/api/last_current.txt b/automotive/audiocontrol/aidl/default/loaders/config/api/last_current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/loaders/config/api/last_current.txt
diff --git a/automotive/audiocontrol/aidl/default/loaders/config/api/last_removed.txt b/automotive/audiocontrol/aidl/default/loaders/config/api/last_removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/loaders/config/api/last_removed.txt
diff --git a/automotive/audiocontrol/aidl/default/loaders/config/api/removed.txt b/automotive/audiocontrol/aidl/default/loaders/config/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/loaders/config/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/automotive/audiocontrol/aidl/default/loaders/config/car_audio_configuration.xsd b/automotive/audiocontrol/aidl/default/loaders/config/car_audio_configuration.xsd
new file mode 100644
index 0000000..634aeda
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/loaders/config/car_audio_configuration.xsd
@@ -0,0 +1,248 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<xs:schema version="2.0" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:element name="carAudioConfiguration" type="CarAudioConfigurationType" minOccurs="1" maxOccurs="1" />
+ <xs:complexType name="CarAudioConfigurationType">
+ <xs:attribute name="version" type="xs:string" use="required" />
+ <xs:sequence>
+ <xs:element name="mirroringDevices" type="MirroringDevicesType" minOccurs="0" />
+ <xs:element name="deviceConfigurations" type="DeviceConfigurationsType" minOccurs="0" />
+ <xs:element name="oemContexts" type="OemContextsType" />
+ <xs:element name="activationVolumeConfigs" type="ActivationVolumeConfigsType" minOccurs="0" />
+ <xs:element name="zones" type="ZonesType" />
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="ZonesType">
+ <xs:element name="zone" type="ZoneType" minOccurs="1" maxOccurs="unbounded" />
+ </xs:complexType>
+ <xs:complexType name="ActivationVolumeConfigsType">
+ <xs:element name="activationVolumeConfig" type="ActivationVolumeConfigType" maxOccurs="unbounded" />
+ </xs:complexType>
+ <xs:complexType name="OemContextsType">
+ <xs:element name="oemContext" type="OemContextType" minOccurs="1" maxOccurs="unbounded" />
+ </xs:complexType>
+ <xs:complexType name="DeviceConfigurationsType">
+ <xs:element name="deviceConfiguration" type="DeviceConfigurationType" minOccurs="0" maxOccurs="unbounded" />
+ </xs:complexType>
+ <xs:complexType name="ZoneType">
+ <xs:attribute name="name" type="xs:string" />
+ <xs:attribute name="audioZoneId" type="xs:string" use="required" />
+ <xs:attribute name="isPrimary" type="xs:boolean" />
+ <xs:attribute name="occupantZoneId" type="xs:string" />
+ <xs:element name="inputDevices" type="InputDevicesType" />
+ <xs:element name="zoneConfigs" type="ZoneConfigsType" />
+ </xs:complexType>
+ <xs:complexType name="ZoneConfigsType">
+ <xs:element name="zoneConfig" type="ZoneConfigType"/>
+ </xs:complexType>
+ <xs:complexType name="ZoneConfigType">
+ <xs:attribute name="name" type="xs:string" />
+ <xs:attribute name="isDefault" type="xs:boolean" />
+ <xs:element name="volumeGroups" type="VolumeGroupsType" />
+ <xs:element name="applyFadeConfigs" type="ApplyFadeConfigsType" />
+ </xs:complexType>
+ <xs:complexType name="ApplyFadeConfigsType">
+ <xs:element name="fadeConfig" type="ApplyFadeConfigType" minOccurs="0" maxOccurs="unbounded" />
+ </xs:complexType>
+ <xs:complexType name="ApplyFadeConfigType">
+ <xs:attribute name="name" type="xs:string" />
+ <xs:attribute name="isDefault" type="xs:boolean" />
+ <xs:element name="audioAttributes" type="AudioAttributeUsagesType" minOccurs="0" maxOccurs="unbounded" />
+ </xs:complexType>
+ <xs:complexType name="AudioAttributeUsagesType">
+ <xs:element name="usage" type="UsageType" maxOccurs="unbounded" />
+ </xs:complexType>
+ <xs:complexType name="VolumeGroupsType">
+ <xs:element name="group" type="VolumeGroupType" minOccurs="1" maxOccurs="unbounded" />
+ </xs:complexType>
+ <xs:complexType name="VolumeGroupType">
+ <xs:attribute name="name" type="xs:string" />
+ <xs:attribute name="activationConfig" type="xs:string" />
+ <xs:element name="device" type="DeviceRoutesType" minOccurts="1" maxOccurs="unbounded" />
+ </xs:complexType>
+ <xs:complexType name="DeviceRoutesType" >
+ <xs:attribute name="address" type="xs:string" />
+ <xs:attribute name="type" type="OutDeviceType" />
+ <xs:element name="context" type="ContextNameType" mixOccurs="1" maxOccurs="unbounded" />
+ </xs:complexType>
+ <xs:complexType name="ContextNameType">
+ <xs:attribute name="context" type="xs:string"/>
+ </xs:complexType>
+ <xs:complexType name="OemContextType">
+ <xs:attribute name="name" type="xs:string" />
+ <xs:attribute name="id" type="xs:string" />
+ <xs:element name="audioAttributes" type="AudioAttributesUsagesType" minOccurs="1" maxOccurs="1" />
+ </xs:complexType>
+ <xs:complexType name="AudioAttributesUsagesType" >
+ <xs:choice minOccurs="0" maxOccurs="unbounded" >
+ <xs:element name="audioAttribute" type="AttributesType" />
+ <xs:element name="usage" type="UsageType" />
+ </xs:choice>
+ </xs:complexType>
+ <xs:complexType name="AttributesType">
+ <xs:attribute name="contentType" type="contentTypeEnum" />
+ <xs:attribute name="usage" type="usageEnumType" />
+ <xs:attribute name="tags" type="xs:string" />
+ </xs:complexType>
+ <xs:complexType name="DeviceConfigurationType">
+ <xs:attribute name="name" type="xs:string" />
+ <xs:attribute name="value" type="xs:string" />
+ </xs:complexType>
+ <xs:complexType name="ContentType" >
+ <xs:attribute name="value" type="contentTypeEnum" use="required" />
+ </xs:complexType>
+ <xs:complexType name="UsageType">
+ <xs:attribute name="value" type="usageEnumType" use="required" />
+ </xs:complexType>
+ <xs:simpleType name="contentTypeEnum">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="AUDIO_CONTENT_TYPE_UNKNOWN"/>
+ <xs:enumeration value="AUDIO_CONTENT_TYPE_SPEECH"/>
+ <xs:enumeration value="AUDIO_CONTENT_TYPE_MUSIC"/>
+ <xs:enumeration value="AUDIO_CONTENT_TYPE_MOVIE"/>
+ <xs:enumeration value="AUDIO_CONTENT_TYPE_SONIFICATION"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="usageEnumType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="AUDIO_USAGE_UNKNOWN"/>
+ <xs:enumeration value="AUDIO_USAGE_MEDIA"/>
+ <xs:enumeration value="AUDIO_USAGE_VOICE_COMMUNICATION"/>
+ <xs:enumeration value="AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING"/>
+ <xs:enumeration value="AUDIO_USAGE_ALARM"/>
+ <xs:enumeration value="AUDIO_USAGE_NOTIFICATION"/>
+ <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE"/>
+ <!-- Note: the following 3 values were deprecated in Android T (13) SDK -->
+ <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST"/>
+ <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT"/>
+ <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED"/>
+ <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_EVENT"/>
+ <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY"/>
+ <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
+ <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_SONIFICATION"/>
+ <xs:enumeration value="AUDIO_USAGE_GAME"/>
+ <xs:enumeration value="AUDIO_USAGE_VIRTUAL_SOURCE"/>
+ <xs:enumeration value="AUDIO_USAGE_ASSISTANT"/>
+ <xs:enumeration value="AUDIO_USAGE_CALL_ASSISTANT"/>
+ <xs:enumeration value="AUDIO_USAGE_EMERGENCY" />
+ <xs:enumeration value="AUDIO_USAGE_SAFETY" />
+ <xs:enumeration value="AUDIO_USAGE_VEHICLE_STATUS" />
+ <xs:enumeration value="AUDIO_USAGE_ANNOUNCEMENT" />
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:complexType name="ActivationVolumeConfigType">
+ <xs:attribute name="name" type="xs:string" />
+ <xs:element name="activationVolumeConfigEntry" type="ActivationVolumeConfigEntryType" maxOccurs="unbounded" />
+ </xs:complexType>
+ <xs:complexType name="ActivationVolumeConfigEntryType">
+ <xs:attribute name="maxActivationVolumePercentage" type="xs:string" />
+ <xs:attribute name="minActivationVolumePercentage" type="xs:string" />
+ <xs:attribute name="invocationType" type="ActivationType" />
+ </xs:complexType>
+ <xs:simpleType name="ActivationType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="onBoot"/>
+ <xs:enumeration value="onSourceChanged"/>
+ <xs:enumeration value="onPlaybackChanged"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name="OutDeviceType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="AUDIO_DEVICE_OUT_SPEAKER"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_WIRED_HEADSET"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_WIRED_HEADPHONE"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_HDMI"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_HDMI_EARC"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_AUX_DIGITAL"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_USB_ACCESSORY"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_USB_DEVICE"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_LINE"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_HDMI_ARC"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_AUX_LINE"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_SPEAKER_SAFE"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_BUS"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_USB_HEADSET"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_BLE_HEADSET"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_BLE_SPEAKER"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_BLE_BROADCAST"/>
+ <xs:enumeration value="AUDIO_DEVICE_OUT_DEFAULT"/>
+ <!-- Added to support legacy files -->
+ <xs:enumeration value="TYPE_BUILTIN_SPEAKER"/>
+ <xs:enumeration value="TYPE_WIRED_HEADSET"/>
+ <xs:enumeration value="TYPE_WIRED_HEADPHONES"/>
+ <xs:enumeration value="TYPE_BLUETOOTH_A2DP"/>
+ <xs:enumeration value="TYPE_HDMI"/>
+ <xs:enumeration value="TYPE_USB_ACCESSORY"/>
+ <xs:enumeration value="TYPE_USB_DEVICE"/>
+ <xs:enumeration value="TYPE_USB_HEADSET"/>
+ <xs:enumeration value="TYPE_AUX_LINE"/>
+ <xs:enumeration value="TYPE_BUS"/>
+ <xs:enumeration value="TYPE_BLE_HEADSET"/>
+ <xs:enumeration value="TYPE_BLE_SPEAKER"/>
+ <xs:enumeration value="TYPE_BLE_BROADCAST"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:complexType name="MirroringDevicesType">
+ <xs:element name="mirroringDevice" type="MirroringDevice" maxOccurs="unbounded" />
+ </xs:complexType>
+ <xs:complexType name="MirroringDevice">
+ <xs:attribute name="address" type="xs:string" />
+ </xs:complexType>
+ <xs:complexType name="InputDevicesType">
+ <xs:element name="inputDevice" type="InputDeviceType" maxOccurs="unbounded" />
+ </xs:complexType>
+ <xs:complexType name="InputDeviceType">
+ <xs:attribute name="address" type="xs:string" />
+ <xs:attribute name="type" type="InDeviceType" />
+ </xs:complexType>
+ <xs:simpleType name="InDeviceType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="AUDIO_DEVICE_IN_COMMUNICATION"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_AMBIENT"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_BUILTIN_MIC"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_WIRED_HEADSET"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_AUX_DIGITAL"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_HDMI"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_VOICE_CALL"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_TELEPHONY_RX"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_BACK_MIC"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_REMOTE_SUBMIX"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_USB_ACCESSORY"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_USB_DEVICE"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_FM_TUNER"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_TV_TUNER"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_LINE"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_SPDIF"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_BLUETOOTH_A2DP"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_LOOPBACK"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_IP"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_BUS"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_PROXY"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_USB_HEADSET"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_BLUETOOTH_BLE"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_HDMI_ARC"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_ECHO_REFERENCE"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_DEFAULT"/>
+ <xs:enumeration value="AUDIO_DEVICE_IN_STUB"/>
+ </xs:restriction>
+ </xs:simpleType>
+</xs:schema>
diff --git a/automotive/audiocontrol/aidl/default/loaders/fade/Android.bp b/automotive/audiocontrol/aidl/default/loaders/fade/Android.bp
new file mode 100644
index 0000000..3dbc2f1
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/loaders/fade/Android.bp
@@ -0,0 +1,45 @@
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+xsd_config {
+ name: "car_fade_audio_configuration_xsd",
+ srcs: ["car_fade_audio_configuration.xsd"],
+ package_name: "android.hardware.automotive.audiocontrol.fade",
+ nullability: true,
+}
+
+cc_defaults {
+ name: "car.fade.configuration.xsd.default",
+ static_libs: [
+ "libxml2",
+ ],
+ generated_sources: [
+ "car_fade_audio_configuration_xsd",
+ ],
+ generated_headers: [
+ "car_fade_audio_configuration_xsd",
+ ],
+ header_libs: [
+ "libxsdc-utils",
+ ],
+}
diff --git a/automotive/audiocontrol/aidl/default/loaders/fade/api/current.txt b/automotive/audiocontrol/aidl/default/loaders/fade/api/current.txt
new file mode 100644
index 0000000..f40f1be
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/loaders/fade/api/current.txt
@@ -0,0 +1,160 @@
+// Signature format: 2.0
+package android.hardware.automotive.audiocontrol.fade {
+
+ public class AttributesType {
+ ctor public AttributesType();
+ method @Nullable public android.hardware.automotive.audiocontrol.fade.ContentTypeEnum getContentType();
+ method @Nullable public String getTags();
+ method @Nullable public android.hardware.automotive.audiocontrol.fade.UsageEnumType getUsage();
+ method public void setContentType(@Nullable android.hardware.automotive.audiocontrol.fade.ContentTypeEnum);
+ method public void setTags(@Nullable String);
+ method public void setUsage(@Nullable android.hardware.automotive.audiocontrol.fade.UsageEnumType);
+ }
+
+ public class AudioAttributesUsagesType {
+ ctor public AudioAttributesUsagesType();
+ method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.fade.AttributesType> getAudioAttribute_optional();
+ method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.fade.UsageType> getUsage_optional();
+ }
+
+ public class CarAudioFadeConfigurationType {
+ ctor public CarAudioFadeConfigurationType();
+ method @Nullable public android.hardware.automotive.audiocontrol.fade.FadeConfigurationConfigs getConfigs();
+ method public void setConfigs(@Nullable android.hardware.automotive.audiocontrol.fade.FadeConfigurationConfigs);
+ }
+
+ public class ContentType {
+ ctor public ContentType();
+ method @Nullable public android.hardware.automotive.audiocontrol.fade.ContentTypeEnum getValue();
+ method public void setValue(@Nullable android.hardware.automotive.audiocontrol.fade.ContentTypeEnum);
+ }
+
+ public enum ContentTypeEnum {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.hardware.automotive.audiocontrol.fade.ContentTypeEnum AUDIO_CONTENT_TYPE_MOVIE;
+ enum_constant public static final android.hardware.automotive.audiocontrol.fade.ContentTypeEnum AUDIO_CONTENT_TYPE_MUSIC;
+ enum_constant public static final android.hardware.automotive.audiocontrol.fade.ContentTypeEnum AUDIO_CONTENT_TYPE_SONIFICATION;
+ enum_constant public static final android.hardware.automotive.audiocontrol.fade.ContentTypeEnum AUDIO_CONTENT_TYPE_SPEECH;
+ enum_constant public static final android.hardware.automotive.audiocontrol.fade.ContentTypeEnum AUDIO_CONTENT_TYPE_UNKNOWN;
+ }
+
+ public class FadeConfigurationConfig {
+ ctor public FadeConfigurationConfig();
+ method @Nullable public String getDefaultFadeInDelayForOffenders();
+ method @Nullable public String getDefaultFadeInDurationInMillis();
+ method @Nullable public String getDefaultFadeOutDurationInMillis();
+ method @Nullable public android.hardware.automotive.audiocontrol.fade.FadeInConfigurationsType getFadeInConfigurations();
+ method @Nullable public android.hardware.automotive.audiocontrol.fade.FadeOutConfigurationsType getFadeOutConfigurations();
+ method @Nullable public android.hardware.automotive.audiocontrol.fade.FadeStateType getFadeState();
+ method @Nullable public android.hardware.automotive.audiocontrol.fade.FadeableUsagesType getFadeableUsages();
+ method @Nullable public String getName();
+ method @Nullable public android.hardware.automotive.audiocontrol.fade.UnfadeableAudioAttributesType getUnfadeableAudioAttributes();
+ method @Nullable public android.hardware.automotive.audiocontrol.fade.UnfadeableContentTypesType getUnfadeableContentTypes();
+ method public void setDefaultFadeInDelayForOffenders(@Nullable String);
+ method public void setDefaultFadeInDurationInMillis(@Nullable String);
+ method public void setDefaultFadeOutDurationInMillis(@Nullable String);
+ method public void setFadeInConfigurations(@Nullable android.hardware.automotive.audiocontrol.fade.FadeInConfigurationsType);
+ method public void setFadeOutConfigurations(@Nullable android.hardware.automotive.audiocontrol.fade.FadeOutConfigurationsType);
+ method public void setFadeState(@Nullable android.hardware.automotive.audiocontrol.fade.FadeStateType);
+ method public void setFadeableUsages(@Nullable android.hardware.automotive.audiocontrol.fade.FadeableUsagesType);
+ method public void setName(@Nullable String);
+ method public void setUnfadeableAudioAttributes(@Nullable android.hardware.automotive.audiocontrol.fade.UnfadeableAudioAttributesType);
+ method public void setUnfadeableContentTypes(@Nullable android.hardware.automotive.audiocontrol.fade.UnfadeableContentTypesType);
+ }
+
+ public class FadeConfigurationConfigs {
+ ctor public FadeConfigurationConfigs();
+ method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.fade.FadeConfigurationConfig> getConfig();
+ }
+
+ public class FadeConfigurationType {
+ ctor public FadeConfigurationType();
+ method @Nullable public android.hardware.automotive.audiocontrol.fade.AudioAttributesUsagesType getAudioAttributes();
+ method @Nullable public String getFadeDurationMillis();
+ method public void setAudioAttributes(@Nullable android.hardware.automotive.audiocontrol.fade.AudioAttributesUsagesType);
+ method public void setFadeDurationMillis(@Nullable String);
+ }
+
+ public class FadeInConfigurationsType {
+ ctor public FadeInConfigurationsType();
+ method @Nullable public android.hardware.automotive.audiocontrol.fade.FadeConfigurationType getFadeConfiguration();
+ method public void setFadeConfiguration(@Nullable android.hardware.automotive.audiocontrol.fade.FadeConfigurationType);
+ }
+
+ public class FadeOutConfigurationsType {
+ ctor public FadeOutConfigurationsType();
+ method @Nullable public android.hardware.automotive.audiocontrol.fade.FadeConfigurationType getFadeConfiguration();
+ method public void setFadeConfiguration(@Nullable android.hardware.automotive.audiocontrol.fade.FadeConfigurationType);
+ }
+
+ public enum FadeStateEnumType {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.hardware.automotive.audiocontrol.fade.FadeStateEnumType FADE_STATE_DISABLED;
+ enum_constant public static final android.hardware.automotive.audiocontrol.fade.FadeStateEnumType FADE_STATE_ENABLED_DEFAULT;
+ enum_constant public static final android.hardware.automotive.audiocontrol.fade.FadeStateEnumType _0;
+ enum_constant public static final android.hardware.automotive.audiocontrol.fade.FadeStateEnumType _1;
+ }
+
+ public class FadeStateType {
+ ctor public FadeStateType();
+ method @Nullable public android.hardware.automotive.audiocontrol.fade.FadeStateEnumType getValue();
+ method public void setValue(@Nullable android.hardware.automotive.audiocontrol.fade.FadeStateEnumType);
+ }
+
+ public class FadeableUsagesType {
+ ctor public FadeableUsagesType();
+ method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.fade.UsageType> getUsage();
+ }
+
+ public class UnfadeableAudioAttributesType {
+ ctor public UnfadeableAudioAttributesType();
+ method @Nullable public android.hardware.automotive.audiocontrol.fade.AudioAttributesUsagesType getAudioAttributes();
+ method public void setAudioAttributes(@Nullable android.hardware.automotive.audiocontrol.fade.AudioAttributesUsagesType);
+ }
+
+ public class UnfadeableContentTypesType {
+ ctor public UnfadeableContentTypesType();
+ method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.fade.ContentType> getContentType();
+ }
+
+ public enum UsageEnumType {
+ method @NonNull public String getRawName();
+ enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_ALARM;
+ enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_ANNOUNCEMENT;
+ enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY;
+ enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE;
+ enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_ASSISTANCE_SONIFICATION;
+ enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_ASSISTANT;
+ enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_CALL_ASSISTANT;
+ enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_EMERGENCY;
+ enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_GAME;
+ enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_MEDIA;
+ enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_NOTIFICATION;
+ enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED;
+ enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT;
+ enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST;
+ enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_NOTIFICATION_EVENT;
+ enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE;
+ enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_SAFETY;
+ enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_UNKNOWN;
+ enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_VEHICLE_STATUS;
+ enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_VIRTUAL_SOURCE;
+ enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_VOICE_COMMUNICATION;
+ enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING;
+ }
+
+ public class UsageType {
+ ctor public UsageType();
+ method @Nullable public android.hardware.automotive.audiocontrol.fade.UsageEnumType getValue();
+ method public void setValue(@Nullable android.hardware.automotive.audiocontrol.fade.UsageEnumType);
+ }
+
+ public class XmlParser {
+ ctor public XmlParser();
+ method @Nullable public static android.hardware.automotive.audiocontrol.fade.CarAudioFadeConfigurationType read(@NonNull java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method @Nullable public static String readText(@NonNull org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public static void skip(@NonNull org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ }
+
+}
+
diff --git a/automotive/audiocontrol/aidl/default/loaders/fade/api/last_current.txt b/automotive/audiocontrol/aidl/default/loaders/fade/api/last_current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/loaders/fade/api/last_current.txt
diff --git a/automotive/audiocontrol/aidl/default/loaders/fade/api/last_removed.txt b/automotive/audiocontrol/aidl/default/loaders/fade/api/last_removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/loaders/fade/api/last_removed.txt
diff --git a/automotive/audiocontrol/aidl/default/loaders/fade/api/removed.txt b/automotive/audiocontrol/aidl/default/loaders/fade/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/loaders/fade/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/automotive/audiocontrol/aidl/default/loaders/fade/car_fade_audio_configuration.xsd b/automotive/audiocontrol/aidl/default/loaders/fade/car_fade_audio_configuration.xsd
new file mode 100644
index 0000000..051be7e
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/loaders/fade/car_fade_audio_configuration.xsd
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" version="2.0">
+ <xs:element name="carAudioFadeConfiguration" type="CarAudioFadeConfigurationType" />
+ <xs:complexType name="CarAudioFadeConfigurationType">
+ <xs:element name="configs" type="FadeConfigurationConfigs" />
+ </xs:complexType>
+ <xs:complexType name="FadeConfigurationConfigs">
+ <xs:element name="config" type="FadeConfigurationConfig" maxOccurs="unbounded" />
+ </xs:complexType>
+ <xs:complexType name="FadeConfigurationConfig">
+ <xs:attribute name="name" type="xs:string" />
+ <xs:attribute name="defaultFadeOutDurationInMillis" type="xs:string" />
+ <xs:attribute name="defaultFadeInDurationInMillis" type="xs:string" />
+ <xs:attribute name="defaultFadeInDelayForOffenders" type="xs:string" />
+ <xs:element name="fadeState" type="FadeStateType" />
+ <xs:element name="fadeableUsages" type="FadeableUsagesType" />
+ <xs:element name="unfadeableContentTypes" type="UnfadeableContentTypesType" />
+ <xs:element name="unfadeableAudioAttributes" type="UnfadeableAudioAttributesType" />
+ <xs:element name="fadeOutConfigurations" type="FadeOutConfigurationsType" />
+ <xs:element name="fadeInConfigurations" type="FadeInConfigurationsType" />
+ </xs:complexType>
+ <xs:complexType name="FadeStateType">
+ <xs:attribute name="value" type="fadeStateEnumType" />
+ </xs:complexType>
+ <xs:simpleType name="fadeStateEnumType" >
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="0" />
+ <xs:enumeration value="1" />
+ <xs:enumeration value="FADE_STATE_DISABLED" />
+ <xs:enumeration value="FADE_STATE_ENABLED_DEFAULT" />
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:complexType name="FadeableUsagesType">
+ <xs:element name="usage" type="UsageType" maxOccurs="unbounded" />
+ </xs:complexType>
+ <xs:complexType name="UsageType">
+ <xs:attribute name="value" type="usageEnumType" />
+ </xs:complexType>
+ <xs:simpleType name="usageEnumType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="AUDIO_USAGE_UNKNOWN"/>
+ <xs:enumeration value="AUDIO_USAGE_MEDIA"/>
+ <xs:enumeration value="AUDIO_USAGE_VOICE_COMMUNICATION"/>
+ <xs:enumeration value="AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING"/>
+ <xs:enumeration value="AUDIO_USAGE_ALARM"/>
+ <xs:enumeration value="AUDIO_USAGE_NOTIFICATION"/>
+ <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE"/>
+ <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST"/>
+ <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT"/>
+ <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED"/>
+ <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_EVENT"/>
+ <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY"/>
+ <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
+ <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_SONIFICATION"/>
+ <xs:enumeration value="AUDIO_USAGE_GAME"/>
+ <xs:enumeration value="AUDIO_USAGE_VIRTUAL_SOURCE"/>
+ <xs:enumeration value="AUDIO_USAGE_ASSISTANT"/>
+ <xs:enumeration value="AUDIO_USAGE_CALL_ASSISTANT"/>
+ <xs:enumeration value="AUDIO_USAGE_EMERGENCY" />
+ <xs:enumeration value="AUDIO_USAGE_SAFETY" />
+ <xs:enumeration value="AUDIO_USAGE_VEHICLE_STATUS" />
+ <xs:enumeration value="AUDIO_USAGE_ANNOUNCEMENT" />
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:complexType name="UnfadeableContentTypesType">
+ <xs:element name="contentType" type="ContentType" maxOccurs="unbounded" />
+ </xs:complexType>
+ <xs:complexType name="ContentType">
+ <xs:attribute name="value" type="contentTypeEnum" />
+ </xs:complexType>
+ <xs:simpleType name="contentTypeEnum">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="AUDIO_CONTENT_TYPE_UNKNOWN"/>
+ <xs:enumeration value="AUDIO_CONTENT_TYPE_SPEECH"/>
+ <xs:enumeration value="AUDIO_CONTENT_TYPE_MUSIC"/>
+ <xs:enumeration value="AUDIO_CONTENT_TYPE_MOVIE"/>
+ <xs:enumeration value="AUDIO_CONTENT_TYPE_SONIFICATION"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:complexType name="UnfadeableAudioAttributesType">
+ <xs:element name="audioAttributes" type="AudioAttributesUsagesType" />
+ </xs:complexType>
+ <xs:complexType name="AudioAttributesUsagesType" >
+ <xs:choice minOccurs="0" maxOccurs="unbounded" >
+ <xs:element name="audioAttribute" type="AttributesType" />
+ <xs:element name="usage" type="UsageType" />
+ </xs:choice>
+ </xs:complexType>
+ <xs:complexType name="AttributesType">
+ <xs:attribute name="contentType" type="contentTypeEnum" />
+ <xs:attribute name="usage" type="usageEnumType" />
+ <xs:attribute name="tags" type="xs:string" />
+ </xs:complexType>
+ <xs:complexType name="FadeOutConfigurationsType">
+ <xs:element name="fadeConfiguration" type="FadeConfigurationType" />
+ </xs:complexType>
+ <xs:complexType name="FadeConfigurationType">
+ <xs:attribute name="fadeDurationMillis" type="xs:string" />
+ <xs:element name="audioAttributes" type="AudioAttributesUsagesType" />
+ </xs:complexType>
+ <xs:complexType name="FadeInConfigurationsType">
+ <xs:element name="fadeConfiguration" type="FadeConfigurationType" />
+ </xs:complexType>
+</xs:schema>
diff --git a/automotive/audiocontrol/aidl/rust_impl/Android.bp b/automotive/audiocontrol/aidl/rust_impl/Android.bp
index 062d989..f9d07b2 100644
--- a/automotive/audiocontrol/aidl/rust_impl/Android.bp
+++ b/automotive/audiocontrol/aidl/rust_impl/Android.bp
@@ -15,7 +15,7 @@
*/
rust_binary {
- name: "android.hardware.automotive.audiocontrol-V4-rust-service",
+ name: "android.hardware.automotive.audiocontrol-rust-service",
relative_install_path: "hw",
vendor: true,
srcs: ["src/*.rs"],
@@ -23,6 +23,7 @@
defaults: [
"latest_android_hardware_automotive_audiocontrol_rust",
"latest_android_hardware_audio_common_rust",
+ "latest_android_media_audio_common_types_rust",
],
vintf_fragments: ["audiocontrol-rust-service.xml"],
init_rc: ["audiocontrol-rust-service.rc"],
diff --git a/automotive/audiocontrol/aidl/rust_impl/README.md b/automotive/audiocontrol/aidl/rust_impl/README.md
index ed22356..b68daf3 100644
--- a/automotive/audiocontrol/aidl/rust_impl/README.md
+++ b/automotive/audiocontrol/aidl/rust_impl/README.md
@@ -6,7 +6,7 @@
This folder contains a skeleton audio control HAL implementation in Rust to
demonstrate how vendor may implement a Rust audio control HAL. To run this
audio control HAL, include
-`android.hardware.automotive.audiocontrol-V4-rust-service` in your image.
+`android.hardware.automotive.audiocontrol-rust-service` in your image.
This implementation returns `StatusCode::UNKNOWN_ERROR` for all operations
and does not pass VTS/CTS. Vendor must replace the logic in
diff --git a/automotive/audiocontrol/aidl/rust_impl/src/default_audio_control_hal.rs b/automotive/audiocontrol/aidl/rust_impl/src/default_audio_control_hal.rs
index ba0ca23..8184c43 100644
--- a/automotive/audiocontrol/aidl/rust_impl/src/default_audio_control_hal.rs
+++ b/automotive/audiocontrol/aidl/rust_impl/src/default_audio_control_hal.rs
@@ -23,8 +23,15 @@
IModuleChangeCallback::IModuleChangeCallback,
MutingInfo::MutingInfo,
Reasons::Reasons,
+ AudioDeviceConfiguration::AudioDeviceConfiguration,
+ AudioZone::AudioZone
};
-use android_hardware_audio_common::aidl::android::hardware::audio::common::PlaybackTrackMetadata::PlaybackTrackMetadata;
+use android_hardware_audio_common::aidl::android::hardware::audio::common::{
+ PlaybackTrackMetadata::PlaybackTrackMetadata,
+};
+use android_media_audio_common_types::aidl::android::media::audio::common::{
+ AudioPort::AudioPort,
+};
use binder::{Interface, Result as BinderResult, StatusCode, Strong};
/// This struct is defined to implement IAudioControl AIDL interface.
@@ -81,4 +88,16 @@
fn clearModuleChangeCallback(&self) -> BinderResult<()> {
Err(StatusCode::UNKNOWN_ERROR.into())
}
+
+ fn getAudioDeviceConfiguration(&self) -> std::result::Result<AudioDeviceConfiguration, binder::Status> {
+ Err(binder::StatusCode::UNKNOWN_ERROR.into())
+ }
+
+ fn getOutputMirroringDevices(&self) -> std::result::Result<std::vec::Vec<AudioPort>, binder::Status> {
+ Err(binder::StatusCode::UNKNOWN_ERROR.into())
+ }
+
+ fn getCarAudioZones(&self) -> std::result::Result<std::vec::Vec<AudioZone>, binder::Status> {
+ Err(binder::StatusCode::UNKNOWN_ERROR.into())
+ }
}
diff --git a/automotive/audiocontrol/aidl/vts/Android.bp b/automotive/audiocontrol/aidl/vts/Android.bp
index d94ad55..57c6ae4 100644
--- a/automotive/audiocontrol/aidl/vts/Android.bp
+++ b/automotive/audiocontrol/aidl/vts/Android.bp
@@ -22,6 +22,25 @@
default_applicable_licenses: ["hardware_interfaces_license"],
}
+cc_library {
+ name: "AudioControlHalTestUtils",
+ srcs: [
+ "src/AudioControlTestUtils.cpp",
+ ],
+ export_include_dirs: [
+ "include",
+ ],
+ defaults: [
+ "latest_android_hardware_audio_common_cpp_static",
+ "latest_android_hardware_automotive_audiocontrol_cpp_static",
+ "latest_android_media_audio_common_types_cpp_static",
+ ],
+ shared_libs: [
+ "libbase",
+ "libutils",
+ ],
+}
+
cc_test {
name: "VtsAidlHalAudioControlTest",
defaults: [
@@ -39,9 +58,11 @@
"libbinder",
"libbase",
"libxml2",
+ "libutils",
],
static_libs: [
"libgmock",
+ "AudioControlHalTestUtils",
],
test_suites: [
"general-tests",
diff --git a/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp b/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp
index 4e7e963..6e646a6 100644
--- a/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp
+++ b/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp
@@ -18,6 +18,8 @@
#include <aidl/Gtest.h>
#include <aidl/Vintf.h>
#include <gmock/gmock.h>
+#include <utils/String16.h>
+#include <set>
#include <android/hardware/automotive/audiocontrol/BnAudioGainCallback.h>
#include <android/hardware/automotive/audiocontrol/BnFocusListener.h>
@@ -26,24 +28,49 @@
#include <android/log.h>
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
+#include <include/AudioControlTestUtils.h>
using android::ProcessState;
using android::sp;
using android::String16;
using android::binder::Status;
+using android::hardware::automotive::audiocontrol::AudioDeviceConfiguration;
+using android::hardware::automotive::audiocontrol::AudioFadeConfiguration;
using android::hardware::automotive::audiocontrol::AudioFocusChange;
using android::hardware::automotive::audiocontrol::AudioGainConfigInfo;
+using android::hardware::automotive::audiocontrol::AudioZone;
+using android::hardware::automotive::audiocontrol::AudioZoneConfig;
+using android::hardware::automotive::audiocontrol::AudioZoneContextInfo;
+using android::hardware::automotive::audiocontrol::AudioZoneFadeConfiguration;
using android::hardware::automotive::audiocontrol::BnAudioGainCallback;
using android::hardware::automotive::audiocontrol::BnFocusListener;
using android::hardware::automotive::audiocontrol::BnModuleChangeCallback;
+using android::hardware::automotive::audiocontrol::DeviceToContextEntry;
using android::hardware::automotive::audiocontrol::DuckingInfo;
+using android::hardware::automotive::audiocontrol::FadeConfiguration;
using android::hardware::automotive::audiocontrol::IAudioControl;
using android::hardware::automotive::audiocontrol::IModuleChangeCallback;
using android::hardware::automotive::audiocontrol::MutingInfo;
using android::hardware::automotive::audiocontrol::Reasons;
+using android::hardware::automotive::audiocontrol::VolumeActivationConfiguration;
+using android::hardware::automotive::audiocontrol::VolumeActivationConfigurationEntry;
+using android::hardware::automotive::audiocontrol::VolumeGroupConfig;
+using android::hardware::automotive::audiocontrol::RoutingDeviceConfiguration::
+ CONFIGURABLE_AUDIO_ENGINE_ROUTING;
+using android::hardware::automotive::audiocontrol::RoutingDeviceConfiguration::
+ DEFAULT_AUDIO_ROUTING;
+using android::hardware::automotive::audiocontrol::VolumeActivationConfigurationEntry::
+ DEFAULT_MAX_ACTIVATION_VALUE;
+using android::hardware::automotive::audiocontrol::VolumeActivationConfigurationEntry::
+ DEFAULT_MIN_ACTIVATION_VALUE;
using ::testing::AnyOf;
using ::testing::Eq;
+using ::testing::Not;
+using ::testing::UnorderedElementsAreArray;
+
+using android::internal::ToString;
+
#include "android_audio_policy_configuration_V7_0.h"
namespace xsd {
@@ -52,11 +79,218 @@
namespace audiohalcommon = android::hardware::audio::common;
namespace audiomediacommon = android::media::audio::common;
+namespace testutils = android::hardware::audiocontrol::testutils;
namespace {
constexpr int32_t kAidlVersionThree = 3;
+constexpr int32_t kAidlVersionFive = 5;
+
+bool hasValidVolumeGroupActivation(const VolumeActivationConfiguration& activation,
+ std::string& message) {
+ if (activation.volumeActivationEntries.empty()) {
+ message = "Volume group activation must have at least one volume activation entry";
+ return false;
+ }
+ for (const auto& entry : activation.volumeActivationEntries) {
+ int32_t max = entry.maxActivationVolumePercentage;
+ int32_t min = entry.minActivationVolumePercentage;
+ if (min > DEFAULT_MAX_ACTIVATION_VALUE || min < DEFAULT_MIN_ACTIVATION_VALUE) {
+ message = "Invalid minActivationVolumePercentage, must be between " +
+ std::to_string(DEFAULT_MIN_ACTIVATION_VALUE) + " and " +
+ std::to_string(DEFAULT_MAX_ACTIVATION_VALUE);
+ return false;
+ }
+ if (max > DEFAULT_MAX_ACTIVATION_VALUE || max < DEFAULT_MIN_ACTIVATION_VALUE) {
+ message = "Invalid maxActivationVolumePercentage, must be between " +
+ std::to_string(DEFAULT_MIN_ACTIVATION_VALUE) + " and " +
+ std::to_string(DEFAULT_MAX_ACTIVATION_VALUE);
+ return false;
+ }
+ if (min >= max) {
+ message =
+ "Invalid maxActivationVolumePercentage and minActivationVolumePercentage "
+ "combination, minActivationVolumePercentage must be less than "
+ "maxActivationVolumePercentage";
+ return false;
+ }
+ }
+ return true;
}
+bool hasValidAudioRoute(const DeviceToContextEntry& entry, std::string& message,
+ std::set<std::string>& groupDevices) {
+ if (entry.contextNames.empty()) {
+ message = " Contexts can not be empty for DeviceToContextEntry";
+ return false;
+ }
+ std::set<std::string> contextInRoute;
+ for (const auto& context : entry.contextNames) {
+ if (!contextInRoute.contains(ToString(context))) {
+ continue;
+ }
+ message = " Context can not repeat for the same DeviceToContextEntry";
+ return false;
+ }
+ audiomediacommon::AudioDeviceDescription description;
+ if (!testutils::getAudioPortDeviceDescriptor(entry.device, description)) {
+ message = " DeviceToContextEntry must have a valid device port";
+ return false;
+ }
+ // BUS type also has empty connection
+ // Note: OUT_BUS is also mapped to OUT_DEVICE
+ if (description.type != audiomediacommon::AudioDeviceType::OUT_BUS &&
+ !description.connection.empty()) {
+ return true;
+ }
+ std::string address;
+ if (!testutils::getAddressForAudioPort(entry.device, address) || address.empty()) {
+ message = " Address can not be empty for BUS devices";
+ return false;
+ }
+ if (groupDevices.contains(address)) {
+ message = " Audio device address can not repeat in the same volume group";
+ return false;
+ }
+ groupDevices.insert(address);
+ return true;
+}
+
+inline bool hasValidTimeout(int64_t timeout) {
+ return timeout > 0;
+}
+bool hasValidFadeConfiguration(const FadeConfiguration& fadeConfiguration,
+ const std::string& prefix, std::string& message) {
+ if (!hasValidTimeout(fadeConfiguration.fadeDurationMillis)) {
+ message = prefix + " duration must be greater than 0";
+ return false;
+ }
+ return true;
+}
+bool hadValidAudioFadeConfiguration(const AudioFadeConfiguration& fadeConfiguration,
+ std::string& message) {
+ if (!hasValidTimeout(fadeConfiguration.fadeInDurationMs)) {
+ message = "Fade-in duration must be greater than 0";
+ return false;
+ }
+ if (!hasValidTimeout(fadeConfiguration.fadeOutDurationMs)) {
+ message = "Fade-out duration must be greater than 0";
+ return false;
+ }
+ if (!hasValidTimeout(fadeConfiguration.fadeInDelayedForOffendersMs)) {
+ message = "Fade-in delayed for offenders duration must be greater than 0";
+ return false;
+ }
+ for (const auto& fadeOutConfig : fadeConfiguration.fadeOutConfigurations) {
+ if (!hasValidFadeConfiguration(fadeOutConfig, "Fade-out", message)) {
+ return false;
+ }
+ }
+ for (const auto& fadeOutConfig : fadeConfiguration.fadeInConfigurations) {
+ if (!hasValidFadeConfiguration(fadeOutConfig, "Fade-in", message)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+void validateVolumeGroupInfo(const AudioZoneConfig& audioZoneConfig,
+ const VolumeGroupConfig& volumeGroupConfig,
+ const AudioDeviceConfiguration& deviceConfig) {
+ std::string zoneConfigName = testutils::toAlphaNumeric(ToString(audioZoneConfig.name));
+ std::string volumeGroupName = testutils::toAlphaNumeric(ToString(volumeGroupConfig.name));
+ std::string volumeGroupInfo =
+ "Audio zone config " + zoneConfigName + " volume group " + volumeGroupName;
+ ALOGI("%s test", volumeGroupInfo.c_str());
+
+ EXPECT_FALSE(volumeGroupConfig.carAudioRoutes.empty())
+ << volumeGroupInfo << " must have at least one audio route";
+ if (deviceConfig.routingConfig == CONFIGURABLE_AUDIO_ENGINE_ROUTING) {
+ EXPECT_FALSE(volumeGroupConfig.name.empty())
+ << volumeGroupInfo << " must have a non-empty volume name";
+ }
+ std::set<std::string> groupDevices;
+ for (const auto& audioRoute : volumeGroupConfig.carAudioRoutes) {
+ std::string routeMessage;
+ EXPECT_TRUE(hasValidAudioRoute(audioRoute, routeMessage, groupDevices))
+ << volumeGroupInfo << " Volume route message: " << routeMessage;
+ }
+ if (volumeGroupConfig.activationConfiguration.has_value()) {
+ std::string activationMessage;
+ EXPECT_TRUE(hasValidVolumeGroupActivation(volumeGroupConfig.activationConfiguration.value(),
+ activationMessage))
+ << volumeGroupInfo << " Activation message: " << activationMessage;
+ }
+}
+
+void validateAudioZoneFadeConfiguration(const AudioZoneFadeConfiguration& fadeConfiguration) {
+ ALOGI("Fade configuration test");
+ std::set<audiomediacommon::AudioUsage> usages;
+ std::string defaultValidationMessage;
+ EXPECT_TRUE(hadValidAudioFadeConfiguration(fadeConfiguration.defaultConfiguration,
+ defaultValidationMessage))
+ << "Default configuration validation failed: " << defaultValidationMessage;
+ for (const auto& entry : fadeConfiguration.transientConfiguration) {
+ ALOGI("Transient fade configuration test");
+ std::string transientFadeConfigurationMessage;
+ EXPECT_TRUE(hadValidAudioFadeConfiguration(entry.transientFadeConfiguration,
+ transientFadeConfigurationMessage))
+ << "Transient fade configuration validation failed: "
+ << transientFadeConfigurationMessage;
+ EXPECT_FALSE(entry.transientUsages.empty())
+ << "Transient fade configuration must have at least one audio usage";
+ for (const auto& usage : entry.transientUsages) {
+ EXPECT_FALSE(usages.contains(usage)) << "Audio usages " << ToString(usage)
+ << " repeat in transient fade configuration";
+ }
+ }
+}
+
+void validateAudioZoneConfiguration(const AudioZone& carAudioZone,
+ const AudioZoneConfig& audioZoneConfig,
+ const AudioDeviceConfiguration& deviceConfig) {
+ std::string zoneConfigName = testutils::toAlphaNumeric(ToString(audioZoneConfig.name));
+ ALOGI("Zone config name %s test", zoneConfigName.c_str());
+ std::set<std::string> contextInfoNames;
+ EXPECT_FALSE(audioZoneConfig.volumeGroups.empty())
+ << "Volume groups for zone config " << zoneConfigName.c_str();
+ for (const auto& volumeGroup : audioZoneConfig.volumeGroups) {
+ ALOGI("Zone config name %s volume group test %s", zoneConfigName.c_str(),
+ ToString(volumeGroup.name).c_str());
+ std::vector<std::string> groupContexts =
+ testutils::getContextInfoNamesForVolumeGroup(volumeGroup);
+ for (const auto& context : groupContexts) {
+ EXPECT_FALSE(contextInfoNames.contains(context))
+ << "Context " << context << " repeats in zone config " << zoneConfigName;
+ contextInfoNames.insert(context);
+ }
+ validateVolumeGroupInfo(audioZoneConfig, volumeGroup, deviceConfig);
+ }
+ const auto& audioZoneContexts = carAudioZone.audioZoneContext.audioContextInfos;
+ std::map<std::string, AudioZoneContextInfo> infoNameToInfo;
+ std::transform(audioZoneContexts.begin(), audioZoneContexts.end(),
+ std::inserter(infoNameToInfo, infoNameToInfo.end()),
+ [&](const AudioZoneContextInfo& context) {
+ return std::make_pair(ToString(context.name), context);
+ });
+ std::vector<AudioZoneContextInfo> configContextInfos;
+ for (const auto& contextName : contextInfoNames) {
+ const auto& pair = infoNameToInfo.find(contextName);
+ if (pair == infoNameToInfo.end()) {
+ continue;
+ }
+ configContextInfos.push_back(pair->second);
+ }
+ std::string message;
+ EXPECT_TRUE(testutils::contextInfosContainAllAudioAttributeUsages(configContextInfos, message))
+ << "Config " << zoneConfigName << " message: " << message;
+
+ if (audioZoneConfig.fadeConfiguration.has_value()) {
+ validateAudioZoneFadeConfiguration(audioZoneConfig.fadeConfiguration.value());
+ }
+}
+
+} // namespace
+
class AudioControlAidl : public testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
@@ -292,12 +526,193 @@
AnyOf(Eq(Status::EX_ILLEGAL_ARGUMENT), Eq(Status::EX_UNSUPPORTED_OPERATION)));
}
+class AudioControlVersionFiveAndAbove : public AudioControlAidl {
+ public:
+ virtual void SetUp() override {
+ AudioControlAidl::SetUp();
+ if (isAidlVersionAtleast(kAidlVersionFive)) {
+ return;
+ }
+ GTEST_SKIP() << " Version is lower than " << std::to_string(kAidlVersionFive);
+ }
+};
+
+class AudioControlWithAudioConfiguration : public AudioControlVersionFiveAndAbove {
+ public:
+ virtual void SetUp() override {
+ AudioControlVersionFiveAndAbove::SetUp();
+
+ if (IsSkipped()) {
+ return;
+ }
+
+ const auto& configStatus =
+ audioControl->getAudioDeviceConfiguration(&audioDeviceConfiguration);
+
+ EXPECT_THAT(configStatus.exceptionCode(),
+ AnyOf(Eq(Status::EX_NONE), Eq(Status::EX_UNSUPPORTED_OPERATION)));
+ if (!configStatus.isOk()) {
+ GTEST_SKIP() << "Device does not support audio configurations APIs";
+ }
+ ALOGD("Audio device info: %s", audioDeviceConfiguration.toString().c_str());
+ }
+
+ AudioDeviceConfiguration audioDeviceConfiguration;
+};
+
+TEST_P(AudioControlWithAudioConfiguration, DefaultAudioRoutingConfiguration) {
+ if (audioDeviceConfiguration.routingConfig != DEFAULT_AUDIO_ROUTING) {
+ GTEST_SKIP() << "Default audio routing not supported";
+ }
+ std::vector<AudioZone> zones;
+
+ const auto& zoneStatus = audioControl->getCarAudioZones(&zones);
+
+ EXPECT_THAT(zoneStatus.exceptionCode(),
+ AnyOf(Eq(Status::EX_NONE), Eq(Status::EX_UNSUPPORTED_OPERATION)))
+ << "Default routing can be implemented or unsupported";
+ if (!zoneStatus.isOk()) return;
+ EXPECT_TRUE(zones.empty()) << "Zones must be empty for default routing";
+}
+
+class AudioControlWithDynamicConfiguration : public AudioControlWithAudioConfiguration {
+ public:
+ virtual void SetUp() override {
+ AudioControlWithAudioConfiguration::SetUp();
+ if (IsSkipped()) {
+ return;
+ }
+ if (audioDeviceConfiguration.routingConfig == DEFAULT_AUDIO_ROUTING) {
+ GTEST_SKIP() << "Dynamic/core audio routing not supported";
+ }
+ const auto& zoneStatus = audioControl->getCarAudioZones(&audioZones);
+ EXPECT_EQ(zoneStatus.exceptionCode(), Status::EX_NONE)
+ << "Zones API must be supported for core/dynamic routing";
+ }
+
+ std::vector<AudioZone> audioZones;
+};
+
+TEST_P(AudioControlWithDynamicConfiguration, DynamicAudioRoutingConfiguration) {
+ EXPECT_FALSE(audioZones.empty()) << "Zones must not be empty for core/dynamic routing";
+}
+
+class AudioControlWithAudioZoneInfo : public AudioControlWithDynamicConfiguration {
+ public:
+ virtual void SetUp() override {
+ AudioControlWithDynamicConfiguration::SetUp();
+ if (IsSkipped()) {
+ return;
+ }
+ EXPECT_TRUE(!audioZones.empty()) << "Zones must exist for core/dynamic routing";
+ }
+};
+
+TEST_P(AudioControlWithAudioZoneInfo, AudioZonesRequirements) {
+ bool primaryZoneFound = false;
+ std::set<int> zoneIds;
+ std::set<int> occupantIds;
+ std::set<android::String16> zoneNames;
+ std::set<std::string> deviceAddresses;
+ for (const auto& zone : audioZones) {
+ if (zone.id == AudioZone::PRIMARY_AUDIO_ZONE) {
+ EXPECT_FALSE(primaryZoneFound) << "There can only be one primary zone";
+ primaryZoneFound = true;
+ }
+ EXPECT_FALSE(zoneIds.contains(zone.id)) << "Zone " << std::to_string(zone.id) << " repeats";
+ zoneIds.insert(zone.id);
+ if (!zone.name.empty()) {
+ EXPECT_FALSE(zoneNames.contains(zone.name)) << "Zone " << zone.name << " repeats";
+ zoneNames.insert(zone.name);
+ }
+ if (zone.occupantZoneId != AudioZone::UNASSIGNED_OCCUPANT) {
+ EXPECT_FALSE(occupantIds.contains(zone.occupantZoneId))
+ << "Occupant zone id " << zone.occupantZoneId << " repeats";
+ occupantIds.insert(zone.occupantZoneId);
+ }
+ const auto& zoneAddresses = testutils::getDeviceAddressesForZone(zone);
+ for (const auto& address : zoneAddresses) {
+ EXPECT_FALSE(deviceAddresses.contains(address))
+ << "Device address " << address << " in zone " << zone.name << " repeats";
+ }
+ // Add after zone comparison is done since devices may repeat within a zone for different
+ // configurations
+ deviceAddresses.insert(zoneAddresses.begin(), zoneAddresses.end());
+ }
+ EXPECT_TRUE(primaryZoneFound) << "Primary zone must exist";
+}
+
+TEST_P(AudioControlWithAudioZoneInfo, AudioZoneInfoRequirements) {
+ for (const auto& carAudioZone : audioZones) {
+ ALOGI("Zone id %d test", carAudioZone.id);
+ std::string missingContextMessage;
+ EXPECT_TRUE(testutils::contextContainsAllAudioAttributeUsages(carAudioZone.audioZoneContext,
+ missingContextMessage))
+ << "Audio zone context for zone id " << std::to_string(carAudioZone.id)
+ << missingContextMessage;
+ EXPECT_FALSE(carAudioZone.audioZoneConfigs.empty())
+ << "Audio zone zone id " << std::to_string(carAudioZone.id)
+ << " missing zone configs";
+ std::set<android::String16> configNames;
+ bool defaultConfigFound = false;
+ for (const auto& config : carAudioZone.audioZoneConfigs) {
+ ALOGI("Zone id %d config name %s test", carAudioZone.id, ToString(config.name).c_str());
+ if (config.isDefault) {
+ EXPECT_FALSE(defaultConfigFound)
+ << "Config name " << config.name
+ << " repeats default config value in zone id " << carAudioZone.id;
+ defaultConfigFound = true;
+ }
+ EXPECT_FALSE(configNames.contains(config.name))
+ << "Config name " << config.name << " repeats in " << carAudioZone.id;
+ }
+ EXPECT_TRUE(defaultConfigFound)
+ << "Audio zone " << carAudioZone.id << " must contain default config";
+ std::set<audiomediacommon::AudioPort> inputPorts;
+ ALOGI("Zone id %d input devices test", carAudioZone.id);
+ for (const auto& audioPort : carAudioZone.inputAudioDevices) {
+ std::string address;
+ const auto hasAddress = testutils::getAddressForAudioPort(audioPort, address);
+ EXPECT_FALSE(inputPorts.contains(audioPort))
+ << "Repeating input device for " << carAudioZone.id << ", device address "
+ << (hasAddress ? address : "empty address");
+ inputPorts.insert(audioPort);
+ }
+ }
+}
+
+TEST_P(AudioControlWithAudioZoneInfo, AudioZoneConfigInfoRequirements) {
+ for (const auto& carAudioZone : audioZones) {
+ for (const auto& audioZoneConfig : carAudioZone.audioZoneConfigs) {
+ validateAudioZoneConfiguration(carAudioZone, audioZoneConfig, audioDeviceConfiguration);
+ }
+ }
+}
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioControlAidl);
INSTANTIATE_TEST_SUITE_P(
Audiocontrol, AudioControlAidl,
testing::ValuesIn(android::getAidlHalInstanceNames(IAudioControl::descriptor)),
android::PrintInstanceNameToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioControlWithAudioConfiguration);
+INSTANTIATE_TEST_SUITE_P(
+ Audiocontrol, AudioControlWithAudioConfiguration,
+ testing::ValuesIn(android::getAidlHalInstanceNames(IAudioControl::descriptor)),
+ android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioControlWithDynamicConfiguration);
+INSTANTIATE_TEST_SUITE_P(
+ Audiocontrol, AudioControlWithDynamicConfiguration,
+ testing::ValuesIn(android::getAidlHalInstanceNames(IAudioControl::descriptor)),
+ android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioControlWithAudioZoneInfo);
+INSTANTIATE_TEST_SUITE_P(
+ Audiocontrol, AudioControlWithAudioZoneInfo,
+ testing::ValuesIn(android::getAidlHalInstanceNames(IAudioControl::descriptor)),
+ android::PrintInstanceNameToString);
+
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
ProcessState::self()->setThreadPoolMaxThreadCount(1);
diff --git a/automotive/audiocontrol/aidl/vts/include/AudioControlTestUtils.h b/automotive/audiocontrol/aidl/vts/include/AudioControlTestUtils.h
new file mode 100644
index 0000000..46fdce2
--- /dev/null
+++ b/automotive/audiocontrol/aidl/vts/include/AudioControlTestUtils.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MAIN8_AUDIOCONTROLTESTUTILS_H
+#define MAIN8_AUDIOCONTROLTESTUTILS_H
+
+#include <android/hardware/automotive/audiocontrol/IAudioControl.h>
+#include <string>
+#include <vector>
+
+namespace android {
+namespace hardware {
+namespace audiocontrol {
+namespace testutils {
+
+std::string toAlphaNumeric(const std::string& info);
+
+bool getAudioPortDeviceDescriptor(
+ const android::media::audio::common::AudioPort& audioPort,
+ android::media::audio::common::AudioDeviceDescription& description);
+
+bool getAddressForAudioPort(const android::media::audio::common::AudioPort& audioPort,
+ std::string& address);
+
+bool getAddressForAudioDevice(
+ const android::hardware::automotive::audiocontrol::DeviceToContextEntry& device,
+ std::string& address);
+
+std::vector<std::string> getDeviceAddressesForVolumeGroup(
+ const android::hardware::automotive::audiocontrol::VolumeGroupConfig& config);
+
+std::vector<std::string> getDeviceAddressesForZoneConfig(
+ const android::hardware::automotive::audiocontrol::AudioZoneConfig& config);
+
+std::vector<std::string> getDeviceAddressesForZone(
+ const android::hardware::automotive::audiocontrol::AudioZone& config);
+
+bool contextInfosContainAllAudioAttributeUsages(
+ const std::vector<android::hardware::automotive::audiocontrol::AudioZoneContextInfo>& infos,
+ std::string& message);
+
+bool contextContainsAllAudioAttributeUsages(
+ const android::hardware::automotive::audiocontrol::AudioZoneContext& context,
+ std::string& message);
+
+std::vector<std::string> getContextInfoNamesForVolumeGroup(
+ const android::hardware::automotive::audiocontrol::VolumeGroupConfig& group);
+
+} // namespace testutils
+} // namespace audiocontrol
+} // namespace hardware
+} // namespace android
+
+#endif // MAIN8_AUDIOCONTROLTESTUTILS_H
diff --git a/automotive/audiocontrol/aidl/vts/src/AudioControlTestUtils.cpp b/automotive/audiocontrol/aidl/vts/src/AudioControlTestUtils.cpp
new file mode 100644
index 0000000..7b7c896
--- /dev/null
+++ b/automotive/audiocontrol/aidl/vts/src/AudioControlTestUtils.cpp
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "../include/AudioControlTestUtils.h"
+
+#include <set>
+
+using android::hardware::automotive::audiocontrol::AudioZone;
+using android::hardware::automotive::audiocontrol::AudioZoneConfig;
+using android::hardware::automotive::audiocontrol::AudioZoneContext;
+using android::hardware::automotive::audiocontrol::AudioZoneContextInfo;
+using android::hardware::automotive::audiocontrol::DeviceToContextEntry;
+using android::hardware::automotive::audiocontrol::VolumeGroupConfig;
+
+namespace audiomediacommon = android::media::audio::common;
+
+namespace android {
+namespace hardware {
+namespace audiocontrol {
+namespace testutils {
+
+std::string toAlphaNumeric(const std::string& info) {
+ std::string name = info;
+ for (size_t i = 0; i < name.size(); i++) {
+ // gtest test names must only contain alphanumeric characters
+ if (!std::isalnum(name[i])) name[i] = '_';
+ }
+
+ return name;
+}
+
+bool getAudioPortDeviceDescriptor(const audiomediacommon::AudioPort& audioPort,
+ audiomediacommon::AudioDeviceDescription& description) {
+ if (audioPort.ext.getTag() != audiomediacommon::AudioPortExt::Tag::device) {
+ return false;
+ }
+ const auto& audioDevice =
+ audioPort.ext.get<audiomediacommon::AudioPortExt::Tag::device>().device;
+ description = audioDevice.type;
+ return true;
+}
+
+bool getAddressForAudioPort(const android::media::audio::common::AudioPort& audioPort,
+ std::string& address) {
+ if (audioPort.ext.getTag() != audiomediacommon::AudioPortExt::Tag::device) {
+ return false;
+ }
+ const auto& audioDevice =
+ audioPort.ext.get<audiomediacommon::AudioPortExt::Tag::device>().device;
+
+ switch (audioDevice.address.getTag()) {
+ case audiomediacommon::AudioDeviceAddress::Tag::id:
+ address = audioDevice.address.get<audiomediacommon::AudioDeviceAddress::Tag::id>();
+ return true;
+ case audiomediacommon::AudioDeviceAddress::Tag::alsa:
+ address = android::internal::ToString(
+ audioDevice.address.get<audiomediacommon::AudioDeviceAddress::Tag::alsa>());
+ return true;
+ case audiomediacommon::AudioDeviceAddress::Tag::mac:
+ address = android::internal::ToString(
+ audioDevice.address.get<audiomediacommon::AudioDeviceAddress::Tag::mac>());
+ return true;
+ case audiomediacommon::AudioDeviceAddress::Tag::ipv4:
+ address = android::internal::ToString(
+ audioDevice.address.get<audiomediacommon::AudioDeviceAddress::Tag::ipv4>());
+ return true;
+ case audiomediacommon::AudioDeviceAddress::Tag::ipv6:
+ address = android::internal::ToString(
+ audioDevice.address.get<audiomediacommon::AudioDeviceAddress::Tag::ipv6>());
+ return true;
+ default:
+ address = audioDevice.address.toString();
+ return true;
+ }
+}
+
+bool getAddressForAudioDevice(const DeviceToContextEntry& device, std::string& address) {
+ if (device.device.flags.getTag() == audiomediacommon::AudioIoFlags::input ||
+ device.device.ext.getTag() != audiomediacommon::AudioPortExt::Tag::device) {
+ return false;
+ }
+ return getAddressForAudioPort(device.device, address);
+}
+
+std::vector<std::string> getDeviceAddressesForVolumeGroup(const VolumeGroupConfig& config) {
+ std::vector<std::string> addresses;
+ for (const auto& route : config.carAudioRoutes) {
+ std::string address;
+ if (!getAddressForAudioDevice(route, address)) {
+ continue;
+ }
+ addresses.push_back(address);
+ }
+ return addresses;
+}
+
+std::vector<std::string> getDeviceAddressesForZoneConfig(const AudioZoneConfig& config) {
+ std::vector<std::string> addresses;
+ for (const auto& volumeGroup : config.volumeGroups) {
+ const auto groupAddresses = getDeviceAddressesForVolumeGroup(volumeGroup);
+ addresses.insert(addresses.begin(), groupAddresses.begin(), groupAddresses.end());
+ }
+ return addresses;
+}
+
+std::vector<std::string> getDeviceAddressesForZone(const AudioZone& config) {
+ std::vector<std::string> addresses;
+ for (const auto& zoneConfig : config.audioZoneConfigs) {
+ const auto groupAddresses = getDeviceAddressesForZoneConfig(zoneConfig);
+ addresses.insert(addresses.begin(), groupAddresses.begin(), groupAddresses.end());
+ }
+ return addresses;
+}
+
+static void addContextUsages(const AudioZoneContextInfo& info,
+ std::set<audiomediacommon::AudioUsage>& contextUsages) {
+ for (const auto& audioAttribute : info.audioAttributes) {
+ contextUsages.insert(audioAttribute.usage);
+ }
+}
+
+bool contextInfosContainAllAudioAttributeUsages(const std::vector<AudioZoneContextInfo>& infos,
+ std::string& message) {
+ static const std::vector<audiomediacommon::AudioUsage> audioUsages{
+ audiomediacommon::AudioUsage::UNKNOWN,
+ audiomediacommon::AudioUsage::MEDIA,
+ audiomediacommon::AudioUsage::VOICE_COMMUNICATION,
+ audiomediacommon::AudioUsage::VOICE_COMMUNICATION_SIGNALLING,
+ audiomediacommon::AudioUsage::ALARM,
+ audiomediacommon::AudioUsage::NOTIFICATION,
+ audiomediacommon::AudioUsage::NOTIFICATION_TELEPHONY_RINGTONE,
+ audiomediacommon::AudioUsage::NOTIFICATION_EVENT,
+ audiomediacommon::AudioUsage::ASSISTANCE_ACCESSIBILITY,
+ audiomediacommon::AudioUsage::ASSISTANCE_NAVIGATION_GUIDANCE,
+ audiomediacommon::AudioUsage::ASSISTANCE_SONIFICATION,
+ audiomediacommon::AudioUsage::GAME,
+ audiomediacommon::AudioUsage::ASSISTANT,
+ audiomediacommon::AudioUsage::CALL_ASSISTANT,
+ audiomediacommon::AudioUsage::EMERGENCY,
+ audiomediacommon::AudioUsage::SAFETY,
+ audiomediacommon::AudioUsage::VEHICLE_STATUS,
+ audiomediacommon::AudioUsage::ANNOUNCEMENT,
+ };
+
+ std::set<audiomediacommon::AudioUsage> contextUsages;
+ for (const auto& contextInfo : infos) {
+ addContextUsages(contextInfo, contextUsages);
+ }
+
+ bool allUsagesPresent = true;
+ for (const auto& usage : audioUsages) {
+ if (contextUsages.contains(usage)) {
+ continue;
+ }
+ if (message.empty()) {
+ message = " Missing usage(s): ";
+ }
+ message += audiomediacommon::toString(usage) + ", ";
+ allUsagesPresent = false;
+ }
+ return allUsagesPresent;
+}
+
+bool contextContainsAllAudioAttributeUsages(const AudioZoneContext& context, std::string& message) {
+ return contextInfosContainAllAudioAttributeUsages(context.audioContextInfos, message);
+}
+
+std::vector<std::string> getContextInfoNamesForAudioRoute(const DeviceToContextEntry& route) {
+ std::vector<std::string> contextInfoNames;
+ contextInfoNames.reserve(route.contextNames.size());
+ for (const auto& contextName : route.contextNames) {
+ contextInfoNames.push_back(android::internal::ToString(contextName));
+ }
+ return contextInfoNames;
+}
+
+std::vector<std::string> getContextInfoNamesForVolumeGroup(const VolumeGroupConfig& group) {
+ std::vector<std::string> contextInfoNames;
+ for (const auto& route : group.carAudioRoutes) {
+ std::vector<std::string> routeContexts = getContextInfoNamesForAudioRoute(route);
+ contextInfoNames.insert(contextInfoNames.begin(), routeContexts.begin(),
+ routeContexts.end());
+ }
+ return contextInfoNames;
+}
+
+} // namespace testutils
+} // namespace audiocontrol
+} // namespace hardware
+} // namespace android
\ No newline at end of file