Move in common audio types into audio.media.audio.common

The following types added or updated:
 - AudioConfig
 - AudioConfigBase
 - AudioEncapsulationMode
 - AudioOffloadInfo
 - AudioStreamType
 - AudioUsage

Added comments to AIDL files to match the SDK definitions.

Updated conversion code to/from legacy. Unified error handling.

Bug: 188932434
Test: atest AidlConversionUnitTests
Test: atest SoundHw2CompatTest
Test: atest SoundTriggerMiddlewareImplTest
Change-Id: I9299eec684410940216695799dfe67b175918671
diff --git a/core/jni/android_media_audio_common_AidlConversion.cpp b/core/jni/android_media_audio_common_AidlConversion.cpp
index 6dcaf76..2ef817c 100644
--- a/core/jni/android_media_audio_common_AidlConversion.cpp
+++ b/core/jni/android_media_audio_common_AidlConversion.cpp
@@ -16,6 +16,9 @@
 
 #define LOG_TAG "AidlConversion"
 
+#include <sstream>
+#include <type_traits>
+
 #include <android_os_Parcel.h>
 #include <binder/Parcel.h>
 #include <jni.h>
@@ -28,13 +31,64 @@
 namespace {
 
 using namespace android;
+using media::audio::common::AudioChannelLayout;
+using media::audio::common::AudioEncapsulationMode;
+using media::audio::common::AudioFormatDescription;
+using media::audio::common::AudioStreamType;
+using media::audio::common::AudioUsage;
 
 #define PACKAGE "android/media/audio/common"
 #define CLASSNAME PACKAGE "/AidlConversion"
 
+// Used for creating messages.
+template <typename T>
+struct type_info {
+    static constexpr const char* name = "";
+};
+#define TYPE_NAME_QUOTE(x) #x
+#define TYPE_NAME_STRINGIFY(x) TYPE_NAME_QUOTE(x)
+#define TYPE_NAME(n)                                                \
+    template <>                                                     \
+    struct type_info<n> {                                           \
+        static constexpr const char* name = TYPE_NAME_STRINGIFY(n); \
+    }
+
+TYPE_NAME(AudioChannelLayout);
+TYPE_NAME(AudioEncapsulationMode);
+TYPE_NAME(AudioFormatDescription);
+TYPE_NAME(AudioStreamType);
+TYPE_NAME(AudioUsage);
+TYPE_NAME(audio_encapsulation_mode_t);
+TYPE_NAME(audio_stream_type_t);
+TYPE_NAME(audio_usage_t);
+
+template <typename AidlType, typename LegacyType, typename ConvFunc>
+int aidl2legacy(JNIEnv* env, AidlType aidl, const ConvFunc& conv, LegacyType fallbackValue) {
+    const auto result = conv(aidl);
+    if (result.ok()) {
+        return result.value();
+    }
+    std::ostringstream msg;
+    msg << "Failed to convert " << type_info<AidlType>::name << " value "
+        << static_cast<std::underlying_type_t<AidlType>>(aidl);
+    jniThrowException(env, "java/lang/IllegalArgumentException", msg.str().c_str());
+    return fallbackValue;
+}
+
+template <typename LegacyType, typename AidlType, typename ConvFunc>
+int legacy2aidl(JNIEnv* env, LegacyType legacy, const ConvFunc& conv, AidlType fallbackValue) {
+    const auto result = conv(legacy);
+    if (result.ok()) {
+        return static_cast<std::underlying_type_t<AidlType>>(result.value());
+    }
+    std::ostringstream msg;
+    msg << "Failed to convert legacy " << type_info<LegacyType>::name << " value " << legacy;
+    jniThrowException(env, "java/lang/IllegalArgumentException", msg.str().c_str());
+    return static_cast<std::underlying_type_t<AidlType>>(fallbackValue);
+}
+
 template <typename AidlType, typename ConvFunc>
-int aidl2legacy(JNIEnv* env, jobject clazz, jobject jParcel, const ConvFunc& conv,
-                int fallbackValue) {
+int aidlParcel2legacy(JNIEnv* env, jobject jParcel, const ConvFunc& conv, int fallbackValue) {
     if (Parcel* parcel = parcelForJavaObject(env, jParcel); parcel != nullptr) {
         AidlType aidl{};
         if (status_t status = aidl.readFromParcel(parcel); status == OK) {
@@ -43,8 +97,11 @@
                 return legacy.value();
             }
         } else {
-            ALOGE("aidl2legacy: Failed to read from parcel: %d", status);
+            ALOGE("aidl2legacy: Failed to read from parcel: %s", statusToString(status).c_str());
         }
+        std::ostringstream msg;
+        msg << "Failed to convert " << type_info<AidlType>::name << " value " << aidl.toString();
+        jniThrowException(env, "java/lang/IllegalArgumentException", msg.str().c_str());
     } else {
         ALOGE("aidl2legacy: Failed to retrieve the native parcel from Java parcel");
     }
@@ -52,9 +109,12 @@
 }
 
 template <typename LegacyType, typename ConvFunc>
-jobject legacy2aidl(JNIEnv* env, jobject clazz, LegacyType legacy, const ConvFunc& conv) {
+jobject legacy2aidlParcel(JNIEnv* env, LegacyType legacy, const ConvFunc& conv) {
     auto aidl = conv(legacy);
     if (!aidl.ok()) {
+        std::ostringstream msg;
+        msg << "Failed to convert legacy " << type_info<LegacyType>::name << " value " << legacy;
+        jniThrowException(env, "java/lang/IllegalArgumentException", msg.str().c_str());
         return 0;
     }
     if (jobject jParcel = createJavaParcelObject(env); jParcel != 0) {
@@ -62,6 +122,9 @@
             if (status_t status = aidl.value().writeToParcel(parcel); status == OK) {
                 parcel->setDataPosition(0);
                 return jParcel;
+            } else {
+                ALOGE("legacy2aidl: Failed to write to parcel: %s, aidl value: %s",
+                      statusToString(status).c_str(), aidl.value().toString().c_str());
             }
         } else {
             ALOGE("legacy2aidl: Failed to retrieve the native parcel from Java parcel");
@@ -73,38 +136,71 @@
     return 0;
 }
 
-int aidl2legacy_AudioChannelLayout_Parcel_audio_channel_mask_t(JNIEnv* env, jobject clazz,
+int aidl2legacy_AudioChannelLayout_Parcel_audio_channel_mask_t(JNIEnv* env, jobject,
                                                                jobject jParcel, jboolean isInput) {
-    return aidl2legacy<media::audio::common::AudioChannelLayout>(
-            env, clazz, jParcel,
-            [isInput](const media::audio::common::AudioChannelLayout& l) {
+    return aidlParcel2legacy<AudioChannelLayout>(
+            env, jParcel,
+            [isInput](const AudioChannelLayout& l) {
                 return aidl2legacy_AudioChannelLayout_audio_channel_mask_t(l, isInput);
             },
             AUDIO_CHANNEL_INVALID);
 }
 
 jobject legacy2aidl_audio_channel_mask_t_AudioChannelLayout_Parcel(
-        JNIEnv* env, jobject clazz, int /*audio_channel_mask_t*/ legacy, jboolean isInput) {
-    return legacy2aidl<audio_channel_mask_t>(
-            env, clazz, static_cast<audio_channel_mask_t>(legacy),
-            [isInput](audio_channel_mask_t m) {
+        JNIEnv* env, jobject, int /*audio_channel_mask_t*/ legacy, jboolean isInput) {
+    return legacy2aidlParcel(
+            env, static_cast<audio_channel_mask_t>(legacy), [isInput](audio_channel_mask_t m) {
                 return legacy2aidl_audio_channel_mask_t_AudioChannelLayout(m, isInput);
             });
 }
 
-int aidl2legacy_AudioFormatDescription_Parcel_audio_format_t(JNIEnv* env, jobject clazz,
+int aidl2legacy_AudioFormatDescription_Parcel_audio_format_t(JNIEnv* env, jobject,
                                                              jobject jParcel) {
-    return aidl2legacy<
-            media::audio::common::
-                    AudioFormatDescription>(env, clazz, jParcel,
-                                            aidl2legacy_AudioFormatDescription_audio_format_t,
-                                            AUDIO_FORMAT_INVALID);
+    return aidlParcel2legacy<
+            AudioFormatDescription>(env, jParcel, aidl2legacy_AudioFormatDescription_audio_format_t,
+                                    AUDIO_FORMAT_INVALID);
 }
 
-jobject legacy2aidl_audio_format_t_AudioFormatDescription_Parcel(JNIEnv* env, jobject clazz,
+jobject legacy2aidl_audio_format_t_AudioFormatDescription_Parcel(JNIEnv* env, jobject,
                                                                  int /*audio_format_t*/ legacy) {
-    return legacy2aidl<audio_format_t>(env, clazz, static_cast<audio_format_t>(legacy),
-                                       legacy2aidl_audio_format_t_AudioFormatDescription);
+    return legacy2aidlParcel(env, static_cast<audio_format_t>(legacy),
+                             legacy2aidl_audio_format_t_AudioFormatDescription);
+}
+
+jint aidl2legacy_AudioEncapsulationMode_audio_encapsulation_mode_t(JNIEnv* env, jobject,
+                                                                   jint aidl) {
+    return aidl2legacy(env, AudioEncapsulationMode(static_cast<int32_t>(aidl)),
+                       android::aidl2legacy_AudioEncapsulationMode_audio_encapsulation_mode_t,
+                       AUDIO_ENCAPSULATION_MODE_NONE);
+}
+
+jint legacy2aidl_audio_encapsulation_mode_t_AudioEncapsulationMode(JNIEnv* env, jobject,
+                                                                   jint legacy) {
+    return legacy2aidl(env, static_cast<audio_encapsulation_mode_t>(legacy),
+                       android::legacy2aidl_audio_encapsulation_mode_t_AudioEncapsulationMode,
+                       AudioEncapsulationMode::INVALID);
+}
+
+jint aidl2legacy_AudioStreamType_audio_stream_type_t(JNIEnv* env, jobject, jint aidl) {
+    return aidl2legacy(env, AudioStreamType(static_cast<int32_t>(aidl)),
+                       android::aidl2legacy_AudioStreamType_audio_stream_type_t,
+                       AUDIO_STREAM_DEFAULT);
+}
+
+jint legacy2aidl_audio_stream_type_t_AudioStreamType(JNIEnv* env, jobject, jint legacy) {
+    return legacy2aidl(env, static_cast<audio_stream_type_t>(legacy),
+                       android::legacy2aidl_audio_stream_type_t_AudioStreamType,
+                       AudioStreamType::INVALID);
+}
+
+jint aidl2legacy_AudioUsage_audio_usage_t(JNIEnv* env, jobject, jint aidl) {
+    return aidl2legacy(env, AudioUsage(static_cast<int32_t>(aidl)),
+                       android::aidl2legacy_AudioUsage_audio_usage_t, AUDIO_USAGE_UNKNOWN);
+}
+
+jint legacy2aidl_audio_usage_t_AudioUsage(JNIEnv* env, jobject, jint legacy) {
+    return legacy2aidl(env, static_cast<audio_usage_t>(legacy),
+                       android::legacy2aidl_audio_usage_t_AudioUsage, AudioUsage::INVALID);
 }
 
 const JNINativeMethod gMethods[] = {
@@ -116,6 +212,18 @@
          reinterpret_cast<void*>(aidl2legacy_AudioFormatDescription_Parcel_audio_format_t)},
         {"legacy2aidl_audio_format_t_AudioFormatDescription_Parcel", "(I)Landroid/os/Parcel;",
          reinterpret_cast<void*>(legacy2aidl_audio_format_t_AudioFormatDescription_Parcel)},
+        {"aidl2legacy_AudioEncapsulationMode_audio_encapsulation_mode_t", "(I)I",
+         reinterpret_cast<void*>(aidl2legacy_AudioEncapsulationMode_audio_encapsulation_mode_t)},
+        {"legacy2aidl_audio_encapsulation_mode_t_AudioEncapsulationMode", "(I)I",
+         reinterpret_cast<void*>(legacy2aidl_audio_encapsulation_mode_t_AudioEncapsulationMode)},
+        {"aidl2legacy_AudioStreamType_audio_stream_type_t", "(I)I",
+         reinterpret_cast<void*>(aidl2legacy_AudioStreamType_audio_stream_type_t)},
+        {"legacy2aidl_audio_stream_type_t_AudioStreamType", "(I)I",
+         reinterpret_cast<void*>(legacy2aidl_audio_stream_type_t_AudioStreamType)},
+        {"aidl2legacy_AudioUsage_audio_usage_t", "(I)I",
+         reinterpret_cast<void*>(aidl2legacy_AudioUsage_audio_usage_t)},
+        {"legacy2aidl_audio_usage_t_AudioUsage", "(I)I",
+         reinterpret_cast<void*>(legacy2aidl_audio_usage_t_AudioUsage)},
 };
 
 } // namespace
diff --git a/media/Android.bp b/media/Android.bp
index 82d6160..ce62b03 100644
--- a/media/Android.bp
+++ b/media/Android.bp
@@ -54,6 +54,8 @@
     srcs: [
         "aidl/android/media/audio/common/AudioChannelLayout.aidl",
         "aidl/android/media/audio/common/AudioConfig.aidl",
+        "aidl/android/media/audio/common/AudioConfigBase.aidl",
+        "aidl/android/media/audio/common/AudioEncapsulationMode.aidl",
         "aidl/android/media/audio/common/AudioFormatDescription.aidl",
         "aidl/android/media/audio/common/AudioFormatType.aidl",
         "aidl/android/media/audio/common/AudioOffloadInfo.aidl",
diff --git a/media/aidl/android/media/audio/common/AudioConfig.aidl b/media/aidl/android/media/audio/common/AudioConfig.aidl
index 4a264d8..8d71e8d 100644
--- a/media/aidl/android/media/audio/common/AudioConfig.aidl
+++ b/media/aidl/android/media/audio/common/AudioConfig.aidl
@@ -16,8 +16,7 @@
 
 package android.media.audio.common;
 
-import android.media.audio.common.AudioChannelLayout;
-import android.media.audio.common.AudioFormatDescription;
+import android.media.audio.common.AudioConfigBase;
 import android.media.audio.common.AudioOffloadInfo;
 
 /**
@@ -28,9 +27,8 @@
 @JavaDerive(equals = true, toString = true)
 @VintfStability
 parcelable AudioConfig {
-    int sampleRateHz;
-    AudioChannelLayout channelMask;
-    AudioFormatDescription format;
+    AudioConfigBase base;
     AudioOffloadInfo offloadInfo;
+    /** I/O buffer size in frames. */
     long frameCount;
 }
diff --git a/media/aidl/android/media/audio/common/AudioConfigBase.aidl b/media/aidl/android/media/audio/common/AudioConfigBase.aidl
new file mode 100644
index 0000000..63f12f4
--- /dev/null
+++ b/media/aidl/android/media/audio/common/AudioConfigBase.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2020 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.media.audio.common;
+
+import android.media.audio.common.AudioChannelLayout;
+import android.media.audio.common.AudioFormatDescription;
+
+/**
+ * Base configuration attributes applicable to any stream of audio.
+ *
+ * {@hide}
+ */
+@JavaDerive(equals = true, toString = true)
+@VintfStability
+parcelable AudioConfigBase {
+    int sampleRate;
+    AudioChannelLayout channelMask;
+    AudioFormatDescription format;
+}
diff --git a/media/aidl/android/media/audio/common/AudioEncapsulationMode.aidl b/media/aidl/android/media/audio/common/AudioEncapsulationMode.aidl
new file mode 100644
index 0000000..6f8e9e1
--- /dev/null
+++ b/media/aidl/android/media/audio/common/AudioEncapsulationMode.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2020 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.media.audio.common;
+
+/**
+ * Encapsulation mode used for sending audio compressed data.
+ *
+ * {@hide}
+ */
+@VintfStability
+@Backing(type="byte")
+enum AudioEncapsulationMode {
+    /**
+     * Used as default value in parcelables to indicate that a value was not
+     * set. Should never be considered a valid setting, except for backward
+     * compatibility scenarios.
+     */
+    INVALID = -1,
+    /** No encapsulation mode for metadata. */
+    NONE = 0,
+    /** Elementary stream payload with metadata. */
+    ELEMENTARY_STREAM = 1,
+    /** Handle-based payload with metadata. */
+    HANDLE = 2,
+}
diff --git a/media/aidl/android/media/audio/common/AudioOffloadInfo.aidl b/media/aidl/android/media/audio/common/AudioOffloadInfo.aidl
index b6b5487..46496c3 100644
--- a/media/aidl/android/media/audio/common/AudioOffloadInfo.aidl
+++ b/media/aidl/android/media/audio/common/AudioOffloadInfo.aidl
@@ -16,8 +16,8 @@
 
 package android.media.audio.common;
 
-import android.media.audio.common.AudioChannelLayout;
-import android.media.audio.common.AudioFormatDescription;
+import android.media.audio.common.AudioConfigBase;
+import android.media.audio.common.AudioEncapsulationMode;
 import android.media.audio.common.AudioStreamType;
 import android.media.audio.common.AudioUsage;
 
@@ -29,15 +29,28 @@
 @JavaDerive(equals = true, toString = true)
 @VintfStability
 parcelable AudioOffloadInfo {
-    int sampleRateHz;
-    AudioChannelLayout channelMask;
-    AudioFormatDescription format;
+    /** Base audio configuration. */
+    AudioConfigBase base;
+    /** Stream type. Intended for use by the system only. */
     AudioStreamType streamType = AudioStreamType.INVALID;
+    /** Bit rate in bits per second. */
     int bitRatePerSecond;
-    long durationMicroseconds;
+    /** Duration in microseconds, -1 if unknown. */
+    long durationUs;
+    /** True if the stream is tied to a video stream. */
     boolean hasVideo;
+    /** True if streaming, false if local playback. */
     boolean isStreaming;
-    int bitWidth;
-    int bufferSize;
+    /** Sample bit width. */
+    int bitWidth = 16;
+    /** Offload fragment size. */
+    int offloadBufferSize;
+    /** See the documentation of AudioUsage. */
     AudioUsage usage = AudioUsage.INVALID;
+    /** See the documentation of AudioEncapsulationMode. */
+    AudioEncapsulationMode encapsulationMode = AudioEncapsulationMode.INVALID;
+    /** Content id from tuner HAL (0 if none). */
+    int contentId;
+    /** Sync id from tuner HAL (0 if none). */
+    int syncId;
 }
diff --git a/media/aidl/android/media/audio/common/AudioStreamType.aidl b/media/aidl/android/media/audio/common/AudioStreamType.aidl
index 8b70367..1fa3a9c 100644
--- a/media/aidl/android/media/audio/common/AudioStreamType.aidl
+++ b/media/aidl/android/media/audio/common/AudioStreamType.aidl
@@ -14,15 +14,13 @@
  * limitations under the License.
  */
 
- // This file has been semi-automatically generated using hidl2aidl from its counterpart in
- // hardware/interfaces/audio/common/5.0/types.hal
-
 package android.media.audio.common;
 
 /**
- *  Audio streams
- *
- * Audio stream type describing the intended use case of a stream.
+ * Audio stream type describing the intended use case of a stream. Streams
+ * must be used in the context of volume management only. For playback type
+ * identification purposes, AudioContentType and AudioUsage must be used,
+ * similar to how it's done in the SDK.
  *
  * {@hide}
  */
@@ -30,21 +28,71 @@
 @Backing(type="int")
 enum AudioStreamType {
     /**
-     * Used as default value in parcelables to indicate that a value was not set.
-     * Should never be considered a valid setting, except for backward compatibility scenarios.
+     * Used as default value in parcelables to indicate that a value was not
+     * set. Should never be considered a valid setting, except for backward
+     * compatibility scenarios.
      */
     INVALID = -2,
+    /**
+     * Indicates that the operation is applied to the "default" stream
+     * in this context, e.g. MUSIC in normal device state, or RING if the
+     * phone is ringing.
+     */
     DEFAULT = -1,
-    MIN = 0,
+    /** Used to identify the volume of audio streams for phone calls. */
     VOICE_CALL = 0,
+    /** Used to identify the volume of audio streams for system sounds. */
     SYSTEM = 1,
+    /**
+     * Used to identify the volume of audio streams for the phone ring and
+     * message alerts.
+     */
     RING = 2,
+    /** Used to identify the volume of audio streams for music playback. */
     MUSIC = 3,
+    /** Used to identify the volume of audio streams for alarms. */
     ALARM = 4,
+    /** Used to identify the volume of audio streams for notifications. */
     NOTIFICATION = 5,
+    /**
+     * Used to identify the volume of audio streams for phone calls when
+     * connected via Bluetooth.
+     */
     BLUETOOTH_SCO = 6,
+    /**
+     * Used to identify the volume of audio streams for enforced system sounds
+     * in certain countries (e.g camera in Japan).
+     */
     ENFORCED_AUDIBLE = 7,
+    /** Used to identify the volume of audio streams for DTMF tones. */
     DTMF = 8,
+    /**
+     * Used to identify the volume of audio streams exclusively transmitted
+     * through the speaker (TTS) of the device.
+     */
     TTS = 9,
+    /**
+     * Used to identify the volume of audio streams for accessibility prompts.
+     */
     ACCESSIBILITY = 10,
+    /**
+     * Used to identify the volume of audio streams for virtual assistant.
+     */
+    ASSISTANT = 11,
+    /**
+     * Used for dynamic policy output mixes. Only used by the audio policy.
+     *
+     * Value reserved for system use only. HALs must never return this value to
+     * the system or accept it from the system.
+     */
+    SYS_RESERVED_REROUTING = 12,
+    /**
+     * Used for audio flinger tracks volume. Only used by the audioflinger.
+     *
+     * Value reserved for system use only. HALs must never return this value to
+     * the system or accept it from the system.
+     */
+    SYS_RESERVED_PATCH = 13,
+    /** Used for the stream corresponding to the call assistant usage. */
+    CALL_ASSISTANT = 14,
 }
diff --git a/media/aidl/android/media/audio/common/AudioUsage.aidl b/media/aidl/android/media/audio/common/AudioUsage.aidl
index 028eefe..34a7185 100644
--- a/media/aidl/android/media/audio/common/AudioUsage.aidl
+++ b/media/aidl/android/media/audio/common/AudioUsage.aidl
@@ -14,9 +14,6 @@
  * limitations under the License.
  */
 
- // This file has been semi-automatically generated using hidl2aidl from its counterpart in
- // hardware/interfaces/audio/common/5.0/types.hal
-
 package android.media.audio.common;
 
 /**
@@ -26,21 +23,119 @@
 @Backing(type="int")
 enum AudioUsage {
     /**
-     * Used as default value in parcelables to indicate that a value was not set.
-     * Should never be considered a valid setting, except for backward compatibility scenarios.
+     * Used as default value in parcelables to indicate that a value was not
+     * set. Should never be considered a valid setting, except for backward
+     * compatibility scenarios.
      */
     INVALID = -1,
+    /**
+     * Usage value to use when the usage is unknown.
+     */
     UNKNOWN = 0,
+    /**
+     * Usage value to use when the usage is media, such as music, or movie
+     * soundtracks.
+     */
     MEDIA = 1,
+    /**
+     * Usage value to use when the usage is voice communications, such as
+     * telephony or VoIP.
+     */
     VOICE_COMMUNICATION = 2,
+    /**
+     * Usage value to use when the usage is in-call signalling, such as with
+     * a "busy" beep, or DTMF tones.
+     */
     VOICE_COMMUNICATION_SIGNALLING = 3,
+    /**
+     * Usage value to use when the usage is an alarm (e.g. wake-up alarm).
+     */
     ALARM = 4,
+    /**
+     * Usage value to use when the usage is notification. See other notification
+     * usages for more specialized uses.
+     */
     NOTIFICATION = 5,
+    /**
+     * Usage value to use when the usage is telephony ringtone.
+     */
     NOTIFICATION_TELEPHONY_RINGTONE = 6,
+    /**
+     * Usage value to use when the usage is a request to enter/end a
+     * communication, such as a VoIP communication or video-conference.
+     *
+     * Value reserved for system use only. HALs must never return this value to
+     * the system or accept it from the system.
+     */
+    SYS_RESERVED_NOTIFICATION_COMMUNICATION_REQUEST = 7,
+    /**
+     * Usage value to use when the usage is notification for an "instant"
+     * communication such as a chat, or SMS.
+     *
+     * Value reserved for system use only. HALs must never return this value to
+     * the system or accept it from the system.
+     */
+    SYS_RESERVED_NOTIFICATION_COMMUNICATION_INSTANT = 8,
+    /**
+     * Usage value to use when the usage is notification for a
+     * non-immediate type of communication such as e-mail.
+     *
+     * Value reserved for system use only. HALs must never return this value to
+     * the system or accept it from the system.
+     */
+    SYS_RESERVED_NOTIFICATION_COMMUNICATION_DELAYED = 9,
+    /**
+     * Usage value to use when the usage is to attract the user's attention,
+     * such as a reminder or low battery warning.
+     */
+    NOTIFICATION_EVENT = 10,
+    /**
+     * Usage value to use when the usage is for accessibility, such as with
+     * a screen reader.
+     */
     ASSISTANCE_ACCESSIBILITY = 11,
+    /**
+     * Usage value to use when the usage is driving or navigation directions.
+     */
     ASSISTANCE_NAVIGATION_GUIDANCE = 12,
+    /**
+     * Usage value to use when the usage is sonification, such as  with user
+     * interface sounds.
+     */
     ASSISTANCE_SONIFICATION = 13,
+    /**
+     * Usage value to use when the usage is for game audio.
+     */
     GAME = 14,
+    /**
+     * Usage value to use when feeding audio to the platform and replacing
+     * "traditional" audio source, such as audio capture devices.
+     */
     VIRTUAL_SOURCE = 15,
+    /**
+     * Usage value to use for audio responses to user queries, audio
+     * instructions or help utterances.
+     */
     ASSISTANT = 16,
+    /**
+     * Usage value to use for assistant voice interaction with remote caller on
+     * Cell and VoIP calls.
+     */
+    CALL_ASSISTANT = 17,
+    /**
+     * Usage value to use when the usage is an emergency.
+     */
+    EMERGENCY = 1000,
+    /**
+     * Usage value to use when the usage is a safety sound.
+     */
+    SAFETY = 1001,
+    /**
+     * Usage value to use when the usage is a vehicle status.
+     */
+    VEHICLE_STATUS = 1002,
+    /**
+     * Usage value to use when the usage is an announcement.
+     */
+    ANNOUNCEMENT = 1003,
 }
diff --git a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioConfig.aidl b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioConfig.aidl
index 5fdeb4c..6b8686c 100644
--- a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioConfig.aidl
+++ b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioConfig.aidl
@@ -35,9 +35,7 @@
 /* @hide */
 @JavaDerive(equals=true, toString=true) @VintfStability
 parcelable AudioConfig {
-  int sampleRateHz;
-  android.media.audio.common.AudioChannelLayout channelMask;
-  android.media.audio.common.AudioFormatDescription format;
+  android.media.audio.common.AudioConfigBase base;
   android.media.audio.common.AudioOffloadInfo offloadInfo;
   long frameCount;
 }
diff --git a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioConfigBase.aidl b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioConfigBase.aidl
new file mode 100644
index 0000000..f3e716b
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioConfigBase.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2020 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.media.audio.common;
+/* @hide */
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioConfigBase {
+  int sampleRate;
+  android.media.audio.common.AudioChannelLayout channelMask;
+  android.media.audio.common.AudioFormatDescription format;
+}
diff --git a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioEncapsulationMode.aidl b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioEncapsulationMode.aidl
new file mode 100644
index 0000000..0cf2f31
--- /dev/null
+++ b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioEncapsulationMode.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2020 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.media.audio.common;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum AudioEncapsulationMode {
+  INVALID = -1,
+  NONE = 0,
+  ELEMENTARY_STREAM = 1,
+  HANDLE = 2,
+}
diff --git a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioOffloadInfo.aidl b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioOffloadInfo.aidl
index 9404a4b..40bd53b2 100644
--- a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioOffloadInfo.aidl
+++ b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioOffloadInfo.aidl
@@ -35,15 +35,16 @@
 /* @hide */
 @JavaDerive(equals=true, toString=true) @VintfStability
 parcelable AudioOffloadInfo {
-  int sampleRateHz;
-  android.media.audio.common.AudioChannelLayout channelMask;
-  android.media.audio.common.AudioFormatDescription format;
+  android.media.audio.common.AudioConfigBase base;
   android.media.audio.common.AudioStreamType streamType = android.media.audio.common.AudioStreamType.INVALID;
   int bitRatePerSecond;
-  long durationMicroseconds;
+  long durationUs;
   boolean hasVideo;
   boolean isStreaming;
-  int bitWidth;
-  int bufferSize;
+  int bitWidth = 16;
+  int offloadBufferSize;
   android.media.audio.common.AudioUsage usage = android.media.audio.common.AudioUsage.INVALID;
+  android.media.audio.common.AudioEncapsulationMode encapsulationMode = android.media.audio.common.AudioEncapsulationMode.INVALID;
+  int contentId;
+  int syncId;
 }
diff --git a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioStreamType.aidl b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioStreamType.aidl
index 915c668..cbca6c5 100644
--- a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioStreamType.aidl
+++ b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioStreamType.aidl
@@ -12,8 +12,7 @@
  * 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 has been semi-automatically generated using hidl2aidl from its counterpart in
-// hardware/interfaces/audio/common/5.0/types.hal
+ */
 ///////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
@@ -38,7 +37,6 @@
 enum AudioStreamType {
   INVALID = -2,
   DEFAULT = -1,
-  MIN = 0,
   VOICE_CALL = 0,
   SYSTEM = 1,
   RING = 2,
@@ -50,4 +48,8 @@
   DTMF = 8,
   TTS = 9,
   ACCESSIBILITY = 10,
+  ASSISTANT = 11,
+  SYS_RESERVED_REROUTING = 12,
+  SYS_RESERVED_PATCH = 13,
+  CALL_ASSISTANT = 14,
 }
diff --git a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioUsage.aidl b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioUsage.aidl
index f5130a4..4c72455 100644
--- a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioUsage.aidl
+++ b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioUsage.aidl
@@ -12,8 +12,7 @@
  * 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 has been semi-automatically generated using hidl2aidl from its counterpart in
-// hardware/interfaces/audio/common/5.0/types.hal
+ */
 ///////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
@@ -44,10 +43,19 @@
   ALARM = 4,
   NOTIFICATION = 5,
   NOTIFICATION_TELEPHONY_RINGTONE = 6,
+  SYS_RESERVED_NOTIFICATION_COMMUNICATION_REQUEST = 7,
+  SYS_RESERVED_NOTIFICATION_COMMUNICATION_INSTANT = 8,
+  SYS_RESERVED_NOTIFICATION_COMMUNICATION_DELAYED = 9,
+  NOTIFICATION_EVENT = 10,
   ASSISTANCE_ACCESSIBILITY = 11,
   ASSISTANCE_NAVIGATION_GUIDANCE = 12,
   ASSISTANCE_SONIFICATION = 13,
   GAME = 14,
   VIRTUAL_SOURCE = 15,
   ASSISTANT = 16,
+  CALL_ASSISTANT = 17,
+  EMERGENCY = 1000,
+  SAFETY = 1001,
+  VEHICLE_STATUS = 1002,
+  ANNOUNCEMENT = 1003,
 }
diff --git a/media/java/android/media/audio/common/AidlConversion.java b/media/java/android/media/audio/common/AidlConversion.java
index 3b58934..f96ba8c 100644
--- a/media/java/android/media/audio/common/AidlConversion.java
+++ b/media/java/android/media/audio/common/AidlConversion.java
@@ -35,18 +35,25 @@
  *  aidl2api_AIDL-type-name_SDK-type-name
  *  api2aidl_SDK-type-name_AIDL-type-name
  *
+ * Since the range of the SDK values is generally narrower than
+ * the range of AIDL values, when a match can't be found, the
+ * conversion function returns a corresponding 'INVALID' value.
+ *
  * Methods that convert between AIDL and legacy types are called
  * using the following pattern:
  *
  *  aidl2legacy_AIDL-type-name_native-type-name
  *  legacy2aidl_native-type-name_AIDL-type-name
  *
+ * In general, there is a 1:1 mapping between AIDL and framework
+ * types, and a failure to convert a value indicates a programming
+ * error. Thus, the conversion functions may throw an IllegalArgumentException.
+ *
  * @hide
  */
 @VisibleForTesting
 public class AidlConversion {
     /** Convert from AIDL AudioChannelLayout to legacy audio_channel_mask_t. */
-    @VisibleForTesting
     public static int /*audio_channel_mask_t*/ aidl2legacy_AudioChannelLayout_audio_channel_mask_t(
             @NonNull AudioChannelLayout aidl, boolean isInput) {
         Parcel out = Parcel.obtain();
@@ -60,7 +67,6 @@
     }
 
     /** Convert from legacy audio_channel_mask_t to AIDL AudioChannelLayout. */
-    @VisibleForTesting
     public static AudioChannelLayout legacy2aidl_audio_channel_mask_t_AudioChannelLayout(
             int /*audio_channel_mask_t*/ legacy, boolean isInput) {
         Parcel in = legacy2aidl_audio_channel_mask_t_AudioChannelLayout_Parcel(legacy, isInput);
@@ -71,12 +77,11 @@
                 in.recycle();
             }
         }
-        throw new IllegalArgumentException("Invalid legacy audio "
-                + (isInput ? "input" : "output") + " channel mask: " + legacy);
+        throw new IllegalArgumentException("Failed to convert legacy audio "
+                + (isInput ? "input" : "output") + " audio_channel_mask_t " + legacy + " value");
     }
 
     /** Convert from AIDL AudioFormatDescription to legacy audio_format_t. */
-    @VisibleForTesting
     public static int /*audio_format_t*/ aidl2legacy_AudioFormatDescription_audio_format_t(
             @NonNull AudioFormatDescription aidl) {
         Parcel out = Parcel.obtain();
@@ -90,7 +95,6 @@
     }
 
     /** Convert from legacy audio_format_t to AIDL AudioFormatDescription. */
-    @VisibleForTesting
     public static @NonNull AudioFormatDescription legacy2aidl_audio_format_t_AudioFormatDescription(
             int /*audio_format_t*/ legacy) {
         Parcel in = legacy2aidl_audio_format_t_AudioFormatDescription_Parcel(legacy);
@@ -101,28 +105,33 @@
                 in.recycle();
             }
         }
-        throw new IllegalArgumentException("Invalid legacy audio format: " + legacy);
+        throw new IllegalArgumentException(
+                "Failed to convert legacy audio_format_t value " + legacy);
     }
 
+    /** Convert from AIDL AudioEncapsulationMode to legacy audio_encapsulation_mode_t. */
+    public static native int aidl2legacy_AudioEncapsulationMode_audio_encapsulation_mode_t(
+            int /*AudioEncapsulationMode.* */ aidl);
+
+    /** Convert from legacy audio_encapsulation_mode_t to AIDL AudioEncapsulationMode. */
+    public static native int legacy2aidl_audio_encapsulation_mode_t_AudioEncapsulationMode(
+            int /*audio_encapsulation_mode_t*/ legacy);
+
+    /** Convert from AIDL AudioStreamType to legacy audio_stream_type_t. */
+    public static native int aidl2legacy_AudioStreamType_audio_stream_type_t(
+            int /*AudioStreamType.* */ aidl);
+
     /** Convert from legacy audio_stream_type_t to AIDL AudioStreamType. */
-    @VisibleForTesting
-    public static int legacy2aidl_audio_stream_type_t_AudioStreamType(
-            int /*audio_stream_type_t*/ legacy) {
-        // Relies on the fact that AudioStreamType was converted from
-        // the HIDL definition which uses the same constant values as system/audio.h
-        return legacy;
-    }
+    public static native int legacy2aidl_audio_stream_type_t_AudioStreamType(
+            int /*audio_stream_type_t*/ legacy);
+
+    /** Convert from AIDL AudioUsage to legacy audio_usage_t. */
+    public static native int aidl2legacy_AudioUsage_audio_usage_t(int /*AudioUsage.* */ aidl);
 
     /** Convert from legacy audio_usage_t to AIDL AudioUsage. */
-    @VisibleForTesting
-    public static int legacy2aidl_audio_usage_t_AudioUsage(int /*audio_usage_t*/ legacy) {
-        // Relies on the fact that AudioUsage was converted from
-        // the HIDL definition which uses the same constant values as system/audio.h
-        return legacy;
-    }
+    public static native int legacy2aidl_audio_usage_t_AudioUsage(int /*audio_usage_t*/ legacy);
 
     /** Convert from AIDL AudioChannelLayout to SDK AudioFormat.CHANNEL_*. */
-    @VisibleForTesting
     public static int aidl2api_AudioChannelLayout_AudioFormatChannelMask(
             @NonNull AudioChannelLayout aidlMask, boolean isInput) {
         switch (aidlMask.getTag()) {
@@ -283,29 +292,34 @@
     }
 
     /** Convert from AIDL AudioConfig to SDK AudioFormat. */
-    @VisibleForTesting
     public static @NonNull AudioFormat aidl2api_AudioConfig_AudioFormat(
-            @NonNull AudioConfig audioConfig, boolean isInput) {
+            @NonNull AudioConfig aidl, boolean isInput) {
+        // Only information from the encapsulated AudioConfigBase is used.
+        return aidl2api_AudioConfigBase_AudioFormat(aidl.base, isInput);
+    }
+
+    /** Convert from AIDL AudioConfigBase to SDK AudioFormat. */
+    public static @NonNull AudioFormat aidl2api_AudioConfigBase_AudioFormat(
+            @NonNull AudioConfigBase aidl, boolean isInput) {
         AudioFormat.Builder apiBuilder = new AudioFormat.Builder();
-        apiBuilder.setSampleRate(audioConfig.sampleRateHz);
-        if (audioConfig.channelMask.getTag() != AudioChannelLayout.indexMask) {
+        apiBuilder.setSampleRate(aidl.sampleRate);
+        if (aidl.channelMask.getTag() != AudioChannelLayout.indexMask) {
             apiBuilder.setChannelMask(aidl2api_AudioChannelLayout_AudioFormatChannelMask(
-                            audioConfig.channelMask, isInput));
+                            aidl.channelMask, isInput));
         } else {
             apiBuilder.setChannelIndexMask(aidl2api_AudioChannelLayout_AudioFormatChannelMask(
-                            audioConfig.channelMask, isInput));
+                            aidl.channelMask, isInput));
         }
-        apiBuilder.setEncoding(aidl2api_AudioFormat_AudioFormatEncoding(audioConfig.format));
+        apiBuilder.setEncoding(aidl2api_AudioFormat_AudioFormatEncoding(aidl.format));
         return apiBuilder.build();
     }
 
     /** Convert from AIDL AudioFormat to SDK AudioFormat.ENCODING_*. */
-    @VisibleForTesting
     public static int aidl2api_AudioFormat_AudioFormatEncoding(
-            @NonNull AudioFormatDescription aidlFormat) {
-        switch (aidlFormat.type) {
+            @NonNull AudioFormatDescription aidl) {
+        switch (aidl.type) {
             case AudioFormatType.PCM:
-                switch (aidlFormat.pcm) {
+                switch (aidl.pcm) {
                     case PcmType.UINT_8_BIT:
                         return AudioFormat.ENCODING_PCM_8BIT;
                     case PcmType.INT_16_BIT:
@@ -321,54 +335,54 @@
                         return AudioFormat.ENCODING_INVALID;
                 }
             case AudioFormatType.NON_PCM: // same as DEFAULT
-                if (aidlFormat.encoding != null && !aidlFormat.encoding.isEmpty()) {
-                    if (MediaFormat.MIMETYPE_AUDIO_AC3.equals(aidlFormat.encoding)) {
+                if (aidl.encoding != null && !aidl.encoding.isEmpty()) {
+                    if (MediaFormat.MIMETYPE_AUDIO_AC3.equals(aidl.encoding)) {
                         return AudioFormat.ENCODING_AC3;
-                    } else if (MediaFormat.MIMETYPE_AUDIO_EAC3.equals(aidlFormat.encoding)) {
+                    } else if (MediaFormat.MIMETYPE_AUDIO_EAC3.equals(aidl.encoding)) {
                         return AudioFormat.ENCODING_E_AC3;
-                    } else if (MediaFormat.MIMETYPE_AUDIO_DTS.equals(aidlFormat.encoding)) {
+                    } else if (MediaFormat.MIMETYPE_AUDIO_DTS.equals(aidl.encoding)) {
                         return AudioFormat.ENCODING_DTS;
-                    } else if (MediaFormat.MIMETYPE_AUDIO_DTS_HD.equals(aidlFormat.encoding)) {
+                    } else if (MediaFormat.MIMETYPE_AUDIO_DTS_HD.equals(aidl.encoding)) {
                         return AudioFormat.ENCODING_DTS_HD;
-                    } else if (MediaFormat.MIMETYPE_AUDIO_MPEG.equals(aidlFormat.encoding)) {
+                    } else if (MediaFormat.MIMETYPE_AUDIO_MPEG.equals(aidl.encoding)) {
                         return AudioFormat.ENCODING_MP3;
-                    } else if (MediaFormat.MIMETYPE_AUDIO_AAC_LC.equals(aidlFormat.encoding)) {
+                    } else if (MediaFormat.MIMETYPE_AUDIO_AAC_LC.equals(aidl.encoding)) {
                         return AudioFormat.ENCODING_AAC_LC;
-                    } else if (MediaFormat.MIMETYPE_AUDIO_AAC_HE_V1.equals(aidlFormat.encoding)) {
+                    } else if (MediaFormat.MIMETYPE_AUDIO_AAC_HE_V1.equals(aidl.encoding)) {
                         return AudioFormat.ENCODING_AAC_HE_V1;
-                    } else if (MediaFormat.MIMETYPE_AUDIO_AAC_HE_V2.equals(aidlFormat.encoding)) {
+                    } else if (MediaFormat.MIMETYPE_AUDIO_AAC_HE_V2.equals(aidl.encoding)) {
                         return AudioFormat.ENCODING_AAC_HE_V2;
-                    } else if (MediaFormat.MIMETYPE_AUDIO_IEC61937.equals(aidlFormat.encoding)
-                            && aidlFormat.pcm == PcmType.INT_16_BIT) {
+                    } else if (MediaFormat.MIMETYPE_AUDIO_IEC61937.equals(aidl.encoding)
+                            && aidl.pcm == PcmType.INT_16_BIT) {
                         return AudioFormat.ENCODING_IEC61937;
                     } else if (MediaFormat.MIMETYPE_AUDIO_DOLBY_TRUEHD.equals(
-                                    aidlFormat.encoding)) {
+                                    aidl.encoding)) {
                         return AudioFormat.ENCODING_DOLBY_TRUEHD;
-                    } else if (MediaFormat.MIMETYPE_AUDIO_AAC_ELD.equals(aidlFormat.encoding)) {
+                    } else if (MediaFormat.MIMETYPE_AUDIO_AAC_ELD.equals(aidl.encoding)) {
                         return AudioFormat.ENCODING_AAC_ELD;
-                    } else if (MediaFormat.MIMETYPE_AUDIO_AAC_XHE.equals(aidlFormat.encoding)) {
+                    } else if (MediaFormat.MIMETYPE_AUDIO_AAC_XHE.equals(aidl.encoding)) {
                         return AudioFormat.ENCODING_AAC_XHE;
-                    } else if (MediaFormat.MIMETYPE_AUDIO_AC4.equals(aidlFormat.encoding)) {
+                    } else if (MediaFormat.MIMETYPE_AUDIO_AC4.equals(aidl.encoding)) {
                         return AudioFormat.ENCODING_AC4;
-                    } else if (MediaFormat.MIMETYPE_AUDIO_EAC3_JOC.equals(aidlFormat.encoding)) {
+                    } else if (MediaFormat.MIMETYPE_AUDIO_EAC3_JOC.equals(aidl.encoding)) {
                         return AudioFormat.ENCODING_E_AC3_JOC;
-                    } else if (MediaFormat.MIMETYPE_AUDIO_DOLBY_MAT.equals(aidlFormat.encoding)
-                            || aidlFormat.encoding.startsWith(
+                    } else if (MediaFormat.MIMETYPE_AUDIO_DOLBY_MAT.equals(aidl.encoding)
+                            || aidl.encoding.startsWith(
                                     MediaFormat.MIMETYPE_AUDIO_DOLBY_MAT + ".")) {
                         return AudioFormat.ENCODING_DOLBY_MAT;
-                    } else if (MediaFormat.MIMETYPE_AUDIO_OPUS.equals(aidlFormat.encoding)) {
+                    } else if (MediaFormat.MIMETYPE_AUDIO_OPUS.equals(aidl.encoding)) {
                         return AudioFormat.ENCODING_OPUS;
-                    } else if (MediaFormat.MIMETYPE_AUDIO_MPEGH_BL_L3.equals(aidlFormat.encoding)) {
+                    } else if (MediaFormat.MIMETYPE_AUDIO_MPEGH_BL_L3.equals(aidl.encoding)) {
                         return AudioFormat.ENCODING_MPEGH_BL_L3;
-                    } else if (MediaFormat.MIMETYPE_AUDIO_MPEGH_BL_L4.equals(aidlFormat.encoding)) {
+                    } else if (MediaFormat.MIMETYPE_AUDIO_MPEGH_BL_L4.equals(aidl.encoding)) {
                         return AudioFormat.ENCODING_MPEGH_BL_L4;
-                    } else if (MediaFormat.MIMETYPE_AUDIO_MPEGH_LC_L3.equals(aidlFormat.encoding)) {
+                    } else if (MediaFormat.MIMETYPE_AUDIO_MPEGH_LC_L3.equals(aidl.encoding)) {
                         return AudioFormat.ENCODING_MPEGH_LC_L3;
-                    } else if (MediaFormat.MIMETYPE_AUDIO_MPEGH_LC_L4.equals(aidlFormat.encoding)) {
+                    } else if (MediaFormat.MIMETYPE_AUDIO_MPEGH_LC_L4.equals(aidl.encoding)) {
                         return AudioFormat.ENCODING_MPEGH_LC_L4;
-                    } else if (MediaFormat.MIMETYPE_AUDIO_DTS_UHD.equals(aidlFormat.encoding)) {
+                    } else if (MediaFormat.MIMETYPE_AUDIO_DTS_UHD.equals(aidl.encoding)) {
                         return AudioFormat.ENCODING_DTS_UHD;
-                    } else if (MediaFormat.MIMETYPE_AUDIO_DRA.equals(aidlFormat.encoding)) {
+                    } else if (MediaFormat.MIMETYPE_AUDIO_DRA.equals(aidl.encoding)) {
                         return AudioFormat.ENCODING_DRA;
                     } else {
                         return AudioFormat.ENCODING_INVALID;
diff --git a/media/tests/aidltests/src/com/android/media/AidlConversionUnitTests.java b/media/tests/aidltests/src/com/android/media/AidlConversionUnitTests.java
index c9e79e6..5f64d20 100644
--- a/media/tests/aidltests/src/com/android/media/AidlConversionUnitTests.java
+++ b/media/tests/aidltests/src/com/android/media/AidlConversionUnitTests.java
@@ -16,19 +16,19 @@
 
 package android.media.audio.common;
 
+import android.media.AudioAttributes;
 import android.media.AudioFormat;
 import android.media.AudioSystem;
+import android.media.AudioTrack;
 import android.media.MediaFormat;
 import android.platform.test.annotations.Presubmit;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import androidx.test.runner.AndroidJUnit4;
+
+import static org.junit.Assert.*;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
 
 /**
  * Unit tests for AidlConversion utilities.
@@ -36,10 +36,15 @@
  * Run with "atest AidlConversionUnitTests".
  */
 @Presubmit
-@RunWith(JUnit4.class)
+@RunWith(AndroidJUnit4.class)
 public final class AidlConversionUnitTests {
 
     private static final String TAG = "AidlConvTests";
+    // Negative values are considered to be "invalid" as a general rule.
+    // However, '-1' is sometimes used as "system invalid" value, and thus
+    // does not cause an exception to be thrown during conversion.
+    private static int sInvalidValue = -2;
+    private static byte sInvalidValueByte = -2;
 
     @Test
     public void testAudioChannelConversionApiDefault() {
@@ -92,11 +97,12 @@
     }
 
     @Test
-    public void testAudioConfigConfersionApiIndex() {
+    public void testAudioConfigConversionApiIndex() {
         final AudioConfig aidl = new AudioConfig();
-        aidl.sampleRateHz = 8000;
-        aidl.channelMask = AudioChannelLayout.indexMask(AudioChannelLayout.INDEX_MASK_1);
-        aidl.format = createPcm16FormatAidl();
+        aidl.base = new AudioConfigBase();
+        aidl.base.sampleRate = 8000;
+        aidl.base.channelMask = AudioChannelLayout.indexMask(AudioChannelLayout.INDEX_MASK_1);
+        aidl.base.format = createPcm16FormatAidl();
         // Other fields in AudioConfig are irrelevant.
         final AudioFormat api = AidlConversion.aidl2api_AudioConfig_AudioFormat(
                 aidl, false /*isInput*/);
@@ -109,11 +115,12 @@
     }
 
     @Test
-    public void testAudioConfigConfersionApiLayout() {
+    public void testAudioConfigConversionApiLayout() {
         final AudioConfig aidl = new AudioConfig();
-        aidl.sampleRateHz = 8000;
-        aidl.channelMask = AudioChannelLayout.layoutMask(AudioChannelLayout.LAYOUT_MONO);
-        aidl.format = createPcm16FormatAidl();
+        aidl.base = new AudioConfigBase();
+        aidl.base.sampleRate = 8000;
+        aidl.base.channelMask = AudioChannelLayout.layoutMask(AudioChannelLayout.LAYOUT_MONO);
+        aidl.base.format = createPcm16FormatAidl();
         // Other fields in AudioConfig are irrelevant.
         final AudioFormat api = AidlConversion.aidl2api_AudioConfig_AudioFormat(
                 aidl, false /*isInput*/);
@@ -128,6 +135,40 @@
     }
 
     @Test
+    public void testAudioConfigBaseConversionApiIndex() {
+        final AudioConfigBase aidl = new AudioConfigBase();
+        aidl.sampleRate = 8000;
+        aidl.channelMask = AudioChannelLayout.indexMask(AudioChannelLayout.INDEX_MASK_1);
+        aidl.format = createPcm16FormatAidl();
+        final AudioFormat api = AidlConversion.aidl2api_AudioConfigBase_AudioFormat(
+                aidl, false /*isInput*/);
+        final AudioFormat apiInput = AidlConversion.aidl2api_AudioConfigBase_AudioFormat(
+                aidl, true /*isInput*/);
+        assertEquals(api, apiInput);
+        assertEquals(8000, api.getSampleRate());
+        assertEquals(1, api.getChannelIndexMask());
+        assertEquals(AudioFormat.ENCODING_PCM_16BIT, api.getEncoding());
+    }
+
+    @Test
+    public void testAudioConfigBaseConversionApiLayout() {
+        final AudioConfigBase aidl = new AudioConfigBase();
+        aidl.sampleRate = 8000;
+        aidl.channelMask = AudioChannelLayout.layoutMask(AudioChannelLayout.LAYOUT_MONO);
+        aidl.format = createPcm16FormatAidl();
+        final AudioFormat api = AidlConversion.aidl2api_AudioConfigBase_AudioFormat(
+                aidl, false /*isInput*/);
+        assertEquals(8000, api.getSampleRate());
+        assertEquals(AudioFormat.CHANNEL_OUT_MONO, api.getChannelMask());
+        assertEquals(AudioFormat.ENCODING_PCM_16BIT, api.getEncoding());
+        final AudioFormat apiInput = AidlConversion.aidl2api_AudioConfigBase_AudioFormat(
+                aidl, true /*isInput*/);
+        assertEquals(8000, apiInput.getSampleRate());
+        assertEquals(AudioFormat.CHANNEL_IN_MONO, apiInput.getChannelMask());
+        assertEquals(AudioFormat.ENCODING_PCM_16BIT, apiInput.getEncoding());
+    }
+
+    @Test
     public void testAudioFormatConversionApiDefault() {
         final AudioFormatDescription aidl = new AudioFormatDescription();
         final int api = AidlConversion.aidl2api_AudioFormat_AudioFormatEncoding(aidl);
@@ -236,6 +277,22 @@
     }
 
     @Test
+    public void testAudioChannelConversionLegacyInvalid() {
+        assertThrows(IllegalArgumentException.class,
+                () -> AidlConversion.aidl2legacy_AudioChannelLayout_audio_channel_mask_t(
+                        AudioChannelLayout.voiceMask(sInvalidValue), false /*isInput*/));
+        assertThrows(IllegalArgumentException.class,
+                () -> AidlConversion.aidl2legacy_AudioChannelLayout_audio_channel_mask_t(
+                        AudioChannelLayout.voiceMask(sInvalidValue), true /*isInput*/));
+        assertThrows(IllegalArgumentException.class,
+                () -> AidlConversion.legacy2aidl_audio_channel_mask_t_AudioChannelLayout(
+                        sInvalidValue, false /*isInput*/));
+        assertThrows(IllegalArgumentException.class,
+                () -> AidlConversion.legacy2aidl_audio_channel_mask_t_AudioChannelLayout(
+                        sInvalidValue, true /*isInput*/));
+    }
+
+    @Test
     public void testAudioFormatConversionLegacyDefault() {
         final int legacy = AudioSystem.AUDIO_FORMAT_DEFAULT;
         final AudioFormatDescription aidl =
@@ -273,7 +330,67 @@
         assertEquals(legacy, legacyBack);
     }
 
-    private AudioFormatDescription createPcm16FormatAidl() {
+    @Test
+    public void testAudioFormatConversionLegacyInvalid() {
+        final AudioFormatDescription aidl = new AudioFormatDescription();
+        aidl.type = sInvalidValueByte;
+        assertThrows(IllegalArgumentException.class,
+                () -> AidlConversion.aidl2legacy_AudioFormatDescription_audio_format_t(aidl));
+        assertThrows(IllegalArgumentException.class,
+                () -> AidlConversion.legacy2aidl_audio_format_t_AudioFormatDescription(
+                        sInvalidValue));
+    }
+
+    @Test
+    public void testAudioEncapsulationModeConversionLegacy() {
+        // AIDL values are synchronized with SDK, so we can use the SDK values as AIDL.
+        final int aidl = AudioTrack.ENCAPSULATION_MODE_ELEMENTARY_STREAM;
+        final int legacy =
+                AidlConversion.aidl2legacy_AudioEncapsulationMode_audio_encapsulation_mode_t(aidl);
+        final int aidlBack =
+                AidlConversion.legacy2aidl_audio_encapsulation_mode_t_AudioEncapsulationMode(
+                        legacy);
+        assertEquals(aidl, aidlBack);
+
+        assertThrows(IllegalArgumentException.class,
+                () -> AidlConversion.aidl2legacy_AudioEncapsulationMode_audio_encapsulation_mode_t(
+                        sInvalidValue));
+        assertThrows(IllegalArgumentException.class,
+                () -> AidlConversion.legacy2aidl_audio_encapsulation_mode_t_AudioEncapsulationMode(
+                        sInvalidValue));
+    }
+
+    @Test
+    public void testAudioStreamTypeConversionLegacy() {
+        // AIDL values are synchronized with SDK, so we can use the SDK values as AIDL.
+        final int aidl = AudioSystem.STREAM_MUSIC;
+        final int legacy = AidlConversion.aidl2legacy_AudioStreamType_audio_stream_type_t(aidl);
+        final int aidlBack = AidlConversion.legacy2aidl_audio_stream_type_t_AudioStreamType(legacy);
+        assertEquals(aidl, aidlBack);
+
+        assertThrows(IllegalArgumentException.class,
+                () -> AidlConversion.aidl2legacy_AudioStreamType_audio_stream_type_t(
+                        sInvalidValue));
+        assertThrows(IllegalArgumentException.class,
+                () -> AidlConversion.legacy2aidl_audio_stream_type_t_AudioStreamType(
+                        sInvalidValue));
+    }
+
+    @Test
+    public void testAudioUsageConversionLegacy() {
+        // AIDL values are synchronized with SDK, so we can use the SDK values as AIDL.
+        final int aidl = AudioAttributes.USAGE_MEDIA;
+        final int legacy = AidlConversion.aidl2legacy_AudioUsage_audio_usage_t(aidl);
+        final int aidlBack = AidlConversion.legacy2aidl_audio_usage_t_AudioUsage(legacy);
+        assertEquals(aidl, aidlBack);
+
+        assertThrows(IllegalArgumentException.class,
+                () -> AidlConversion.aidl2legacy_AudioUsage_audio_usage_t(sInvalidValue));
+        assertThrows(IllegalArgumentException.class,
+                () -> AidlConversion.legacy2aidl_audio_usage_t_AudioUsage(sInvalidValue));
+    }
+
+    private static AudioFormatDescription createPcm16FormatAidl() {
         final AudioFormatDescription aidl = new AudioFormatDescription();
         aidl.type = AudioFormatType.PCM;
         aidl.pcm = PcmType.INT_16_BIT;
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/ConversionUtil.java b/services/core/java/com/android/server/soundtrigger_middleware/ConversionUtil.java
index c170603..47bd72a 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/ConversionUtil.java
+++ b/services/core/java/com/android/server/soundtrigger_middleware/ConversionUtil.java
@@ -23,6 +23,7 @@
 import android.hardware.soundtrigger.V2_3.ISoundTriggerHw;
 import android.media.audio.common.AidlConversion;
 import android.media.audio.common.AudioConfig;
+import android.media.audio.common.AudioConfigBase;
 import android.media.audio.common.AudioOffloadInfo;
 import android.media.soundtrigger.AudioCapabilities;
 import android.media.soundtrigger.ConfidenceLevel;
@@ -351,14 +352,8 @@
     AudioConfig hidl2aidlAudioConfig(
             @NonNull android.hardware.audio.common.V2_0.AudioConfig hidlConfig, boolean isInput) {
         AudioConfig aidlConfig = new AudioConfig();
-        aidlConfig.sampleRateHz = hidlConfig.sampleRateHz;
-        // Relies on the fact that HIDL AudioChannelMask uses the same constant values as
-        // system/audio.h.
-        aidlConfig.channelMask = AidlConversion.legacy2aidl_audio_channel_mask_t_AudioChannelLayout(
-                hidlConfig.channelMask, isInput);
-        // Relies on the fact that HIDL AudioFormat uses the same constant values as system/audio.h.
-        aidlConfig.format = AidlConversion.legacy2aidl_audio_format_t_AudioFormatDescription(
-                hidlConfig.format);
+        aidlConfig.base = hidl2aidlAudioConfigBase(hidlConfig.sampleRateHz, hidlConfig.channelMask,
+                hidlConfig.format, isInput);
         aidlConfig.offloadInfo = hidl2aidlOffloadInfo(hidlConfig.offloadInfo);
         aidlConfig.frameCount = hidlConfig.frameCount;
         return aidlConfig;
@@ -368,26 +363,36 @@
     AudioOffloadInfo hidl2aidlOffloadInfo(
             @NonNull android.hardware.audio.common.V2_0.AudioOffloadInfo hidlInfo) {
         AudioOffloadInfo aidlInfo = new AudioOffloadInfo();
-        aidlInfo.sampleRateHz = hidlInfo.sampleRateHz;
-        // Relies on the fact that HIDL AudioChannelMask uses the same constant values as
-        // system/audio.h.
-        aidlInfo.channelMask = AidlConversion.legacy2aidl_audio_channel_mask_t_AudioChannelLayout(
-                hidlInfo.channelMask, false /*isInput*/);
-        // Relies on the fact that HIDL AudioFormat uses the same constant values as system/audio.h.
-        aidlInfo.format = AidlConversion.legacy2aidl_audio_format_t_AudioFormatDescription(
-                hidlInfo.format);
+        aidlInfo.base = hidl2aidlAudioConfigBase(hidlInfo.sampleRateHz, hidlInfo.channelMask,
+                hidlInfo.format, false /*isInput*/);
         aidlInfo.streamType = AidlConversion.legacy2aidl_audio_stream_type_t_AudioStreamType(
                 hidlInfo.streamType);
         aidlInfo.bitRatePerSecond = hidlInfo.bitRatePerSecond;
-        aidlInfo.durationMicroseconds = hidlInfo.durationMicroseconds;
+        aidlInfo.durationUs = hidlInfo.durationMicroseconds;
         aidlInfo.hasVideo = hidlInfo.hasVideo;
         aidlInfo.isStreaming = hidlInfo.isStreaming;
         aidlInfo.bitWidth = hidlInfo.bitWidth;
-        aidlInfo.bufferSize = hidlInfo.bufferSize;
+        aidlInfo.offloadBufferSize = hidlInfo.bufferSize;
         aidlInfo.usage = AidlConversion.legacy2aidl_audio_usage_t_AudioUsage(hidlInfo.usage);
         return aidlInfo;
     }
 
+    // Ideally we would want to convert AudioConfigBase as a unit, however
+    // HIDL V2 lacks this type, so convert by field instead.
+    static @NonNull
+    AudioConfigBase hidl2aidlAudioConfigBase(int sampleRateHz, int channelMask, int format,
+            boolean isInput) {
+        AudioConfigBase aidlBase = new AudioConfigBase();
+        aidlBase.sampleRate = sampleRateHz;
+        // Relies on the fact that HIDL AudioChannelMask uses the same constant values as
+        // system/audio.h.
+        aidlBase.channelMask = AidlConversion.legacy2aidl_audio_channel_mask_t_AudioChannelLayout(
+                channelMask, isInput);
+        // Relies on the fact that HIDL AudioFormat uses the same constant values as system/audio.h.
+        aidlBase.format = AidlConversion.legacy2aidl_audio_format_t_AudioFormatDescription(format);
+        return aidlBase;
+    }
+
     @Nullable
     static ModelParameterRange hidl2aidlModelParameterRange(
             android.hardware.soundtrigger.V2_3.ModelParameterRange hidlRange) {
diff --git a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/TestUtil.java b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/TestUtil.java
index f54f144..39815b7 100644
--- a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/TestUtil.java
+++ b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/TestUtil.java
@@ -27,6 +27,7 @@
 import android.media.MediaFormat;
 import android.media.audio.common.AudioChannelLayout;
 import android.media.audio.common.AudioConfig;
+import android.media.audio.common.AudioConfigBase;
 import android.media.audio.common.AudioFormatDescription;
 import android.media.audio.common.AudioFormatType;
 import android.media.soundtrigger.AudioCapabilities;
@@ -340,10 +341,11 @@
         event.capturePreambleMs = 345;
         event.triggerInData = true;
         event.audioConfig = new AudioConfig();
-        event.audioConfig.sampleRateHz = 456;
-        event.audioConfig.channelMask = AudioChannelLayout.layoutMask(
+        event.audioConfig.base = new AudioConfigBase();
+        event.audioConfig.base.sampleRate = 456;
+        event.audioConfig.base.channelMask = AudioChannelLayout.layoutMask(
                 AudioChannelLayout.LAYOUT_MONO);
-        event.audioConfig.format = createAudioFormatMp3();
+        event.audioConfig.base.format = createAudioFormatMp3();
         //event.audioConfig.offloadInfo is irrelevant.
         event.data = new byte[]{31, 32, 33};
         return event;
@@ -367,10 +369,10 @@
         assertEquals(234, event.captureDelayMs);
         assertEquals(345, event.capturePreambleMs);
         assertTrue(event.triggerInData);
-        assertEquals(456, event.audioConfig.sampleRateHz);
+        assertEquals(456, event.audioConfig.base.sampleRate);
         assertEquals(AudioChannelLayout.layoutMask(AudioChannelLayout.LAYOUT_MONO),
-                event.audioConfig.channelMask);
-        assertEquals(createAudioFormatMp3(), event.audioConfig.format);
+                event.audioConfig.base.channelMask);
+        assertEquals(createAudioFormatMp3(), event.audioConfig.base.format);
         assertArrayEquals(new byte[]{31, 32, 33}, event.data);
     }