Merge "identity: Add multi-document presentation support."
diff --git a/audio/aidl/Android.bp b/audio/aidl/Android.bp
new file mode 100644
index 0000000..c172674
--- /dev/null
+++ b/audio/aidl/Android.bp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2021 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"],
+}
+
+aidl_interface {
+    name: "android.hardware.audio.common",
+    vendor_available: true,
+    srcs: [
+        "android/hardware/audio/common/PlaybackTrackMetadata.aidl",
+        "android/hardware/audio/common/RecordTrackMetadata.aidl",
+        "android/hardware/audio/common/SinkMetadata.aidl",
+        "android/hardware/audio/common/SourceMetadata.aidl",
+    ],
+    imports: [
+        "android.media.audio.common.types",
+    ],
+    stability: "vintf",
+    backend: {
+        cpp: {
+            enabled: true,
+        },
+        java: {
+            platform_apis: true,
+        },
+        ndk: {
+            vndk: {
+                enabled: true,
+            },
+        },
+    },
+    versions: [
+    ],
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.common/current/android/hardware/audio/common/PlaybackTrackMetadata.aidl b/audio/aidl/aidl_api/android.hardware.audio.common/current/android/hardware/audio/common/PlaybackTrackMetadata.aidl
new file mode 100644
index 0000000..8fe8696
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.common/current/android/hardware/audio/common/PlaybackTrackMetadata.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 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.audio.common;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable PlaybackTrackMetadata {
+  android.media.audio.common.AudioUsage usage = android.media.audio.common.AudioUsage.INVALID;
+  android.media.audio.common.AudioContentType contentType = android.media.audio.common.AudioContentType.UNKNOWN;
+  float gain;
+  @utf8InCpp String[] tags;
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.common/current/android/hardware/audio/common/RecordTrackMetadata.aidl b/audio/aidl/aidl_api/android.hardware.audio.common/current/android/hardware/audio/common/RecordTrackMetadata.aidl
new file mode 100644
index 0000000..50330ef
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.common/current/android/hardware/audio/common/RecordTrackMetadata.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 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.audio.common;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable RecordTrackMetadata {
+  android.media.audio.common.AudioSource source = android.media.audio.common.AudioSource.SYS_RESERVED_INVALID;
+  float gain;
+  @utf8InCpp String[] tags;
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.common/current/android/hardware/audio/common/SinkMetadata.aidl b/audio/aidl/aidl_api/android.hardware.audio.common/current/android/hardware/audio/common/SinkMetadata.aidl
new file mode 100644
index 0000000..270147d
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.common/current/android/hardware/audio/common/SinkMetadata.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 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.audio.common;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable SinkMetadata {
+  android.hardware.audio.common.RecordTrackMetadata[] tracks;
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.common/current/android/hardware/audio/common/SourceMetadata.aidl b/audio/aidl/aidl_api/android.hardware.audio.common/current/android/hardware/audio/common/SourceMetadata.aidl
new file mode 100644
index 0000000..2d4a982
--- /dev/null
+++ b/audio/aidl/aidl_api/android.hardware.audio.common/current/android/hardware/audio/common/SourceMetadata.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 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.audio.common;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable SourceMetadata {
+  android.hardware.audio.common.PlaybackTrackMetadata[] tracks;
+}
diff --git a/audio/aidl/android/hardware/audio/common/PlaybackTrackMetadata.aidl b/audio/aidl/android/hardware/audio/common/PlaybackTrackMetadata.aidl
new file mode 100644
index 0000000..28a2f32
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/common/PlaybackTrackMetadata.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2021 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.audio.common;
+
+import android.media.audio.common.AudioContentType;
+import android.media.audio.common.AudioUsage;
+
+/**
+ * Metadata of a playback track for an output stream.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable PlaybackTrackMetadata {
+    AudioUsage usage = AudioUsage.INVALID;
+    AudioContentType contentType = AudioContentType.UNKNOWN;
+    /**
+     * Non-negative linear gain (scaling) applied to track samples.
+     * 0 means muted, 1 is unity gain, 2 means double amplitude, etc.
+     */
+    float gain;
+    /**
+     * Tags from AudioTrack audio attributes. Tag is an additional use case
+     * qualifier complementing AudioUsage and AudioContentType. Tags are set by
+     * vendor specific applications and must be prefixed by "VX_". Vendor must
+     * namespace their tag names to avoid conflicts, for example:
+     * "VX_GOOGLE_VR". At least 3 characters are required for the vendor
+     * namespace.
+     */
+    @utf8InCpp String[] tags;
+}
diff --git a/audio/aidl/android/hardware/audio/common/RecordTrackMetadata.aidl b/audio/aidl/android/hardware/audio/common/RecordTrackMetadata.aidl
new file mode 100644
index 0000000..9a59b41
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/common/RecordTrackMetadata.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2021 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.audio.common;
+
+import android.media.audio.common.AudioSource;
+
+/**
+ * Metadata of a record track for an input stream.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable RecordTrackMetadata {
+    AudioSource source = AudioSource.SYS_RESERVED_INVALID;
+    /**
+     * Non-negative linear gain (scaling) applied to track samples.
+     * 0 means muted, 1 is unity gain, 2 means double amplitude, etc.
+     */
+    float gain;
+    /**
+     * Tags from AudioRecord audio attributes. Tag is an additional use case
+     * qualifier complementing AudioUsage and AudioContentType. Tags are set by
+     * vendor specific applications and must be prefixed by "VX_". Vendor must
+     * namespace their tag names to avoid conflicts, for example:
+     * "VX_GOOGLE_VR". At least 3 characters are required for the vendor
+     * namespace.
+     */
+    @utf8InCpp String[] tags;
+}
diff --git a/audio/aidl/android/hardware/audio/common/SinkMetadata.aidl b/audio/aidl/android/hardware/audio/common/SinkMetadata.aidl
new file mode 100644
index 0000000..188c847
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/common/SinkMetadata.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2021 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.audio.common;
+
+import android.hardware.audio.common.RecordTrackMetadata;
+
+/**
+ * Metadata of record tracks for an input stream.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable SinkMetadata {
+    RecordTrackMetadata[] tracks;
+}
diff --git a/audio/aidl/android/hardware/audio/common/SourceMetadata.aidl b/audio/aidl/android/hardware/audio/common/SourceMetadata.aidl
new file mode 100644
index 0000000..e9f23c6
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/common/SourceMetadata.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2021 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.audio.common;
+
+import android.hardware.audio.common.PlaybackTrackMetadata;
+
+/**
+ * Metadata of playback tracks for an output stream.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable SourceMetadata {
+    PlaybackTrackMetadata[] tracks;
+}
diff --git a/automotive/evs/OWNERS b/automotive/evs/OWNERS
index 6fc5024..b973e91 100644
--- a/automotive/evs/OWNERS
+++ b/automotive/evs/OWNERS
@@ -1,3 +1,3 @@
+ankitarora@google.com
 changyeon@google.com
-garysungang@google.com
-haoxiangl@google.com
+jwhpryor@google.com
diff --git a/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.cpp b/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.cpp
index d7d5476..6e8c1d7 100644
--- a/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.cpp
+++ b/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.cpp
@@ -41,12 +41,8 @@
     BluetoothAudioProvidersFactory::hearing_aid_provider_instance_;
 LeAudioOutputAudioProvider
     BluetoothAudioProvidersFactory::leaudio_output_provider_instance_;
-LeAudioOffloadOutputAudioProvider
-    BluetoothAudioProvidersFactory::leaudio_offload_output_provider_instance_;
 LeAudioInputAudioProvider
     BluetoothAudioProvidersFactory::leaudio_input_provider_instance_;
-LeAudioOffloadInputAudioProvider
-    BluetoothAudioProvidersFactory::leaudio_offload_input_provider_instance_;
 
 Return<void> BluetoothAudioProvidersFactory::openProvider(
     const V2_0::SessionType sessionType, openProvider_cb _hidl_cb) {
@@ -94,15 +90,9 @@
     case SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH:
       provider = &leaudio_output_provider_instance_;
       break;
-    case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
-      provider = &leaudio_offload_output_provider_instance_;
-      break;
     case SessionType::LE_AUDIO_SOFTWARE_DECODED_DATAPATH:
       provider = &leaudio_input_provider_instance_;
       break;
-    case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
-      provider = &leaudio_offload_input_provider_instance_;
-      break;
     default:
       status = BluetoothAudioStatus::FAILURE;
   }
diff --git a/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.h b/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.h
index f8f557e..714d738 100644
--- a/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.h
+++ b/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.h
@@ -56,8 +56,6 @@
   static HearingAidAudioProvider hearing_aid_provider_instance_;
   static LeAudioOutputAudioProvider leaudio_output_provider_instance_;
   static LeAudioInputAudioProvider leaudio_input_provider_instance_;
-  static LeAudioOffloadOutputAudioProvider leaudio_offload_output_provider_instance_;
-  static LeAudioOffloadInputAudioProvider leaudio_offload_input_provider_instance_;
 };
 
 extern "C" IBluetoothAudioProvidersFactory*
diff --git a/bluetooth/audio/2.2/IBluetoothAudioProvider.hal b/bluetooth/audio/2.2/IBluetoothAudioProvider.hal
index bc16b01..f577537 100644
--- a/bluetooth/audio/2.2/IBluetoothAudioProvider.hal
+++ b/bluetooth/audio/2.2/IBluetoothAudioProvider.hal
@@ -59,4 +59,14 @@
      */
     startSession_2_2(IBluetoothAudioPort hostIf, AudioConfiguration audioConfig)
                 generates (Status status, fmq_sync<uint8_t> dataMQ);
+
+    /**
+     * Called when the audio configuration of the stream has been changed.
+     *
+     * @param audioConfig The audio configuration negotiated with the remote
+     *    device. The PCM parameters are set if software based encoding,
+     *    otherwise the correct codec configuration is used for hardware
+     *    encoding.
+     */
+    updateAudioConfiguration(AudioConfiguration audioConfig);
 };
diff --git a/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp b/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp
index 18ac292..202cfb9 100644
--- a/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp
+++ b/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp
@@ -186,6 +186,29 @@
   return Void();
 }
 
+Return<void> BluetoothAudioProvider::updateAudioConfiguration(
+    const AudioConfiguration& audioConfig) {
+  LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
+
+  if (stack_iface_ == nullptr) {
+    LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+              << " has NO session";
+    return Void();
+  }
+
+  if (audioConfig.getDiscriminator() != audio_config_.getDiscriminator()) {
+    LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+              << " audio config type is not match";
+    return Void();
+  }
+
+  audio_config_ = audioConfig;
+  BluetoothAudioSessionReport_2_2::ReportAudioConfigChanged(session_type_,
+                                                            audio_config_);
+
+  return Void();
+}
+
 }  // namespace implementation
 }  // namespace V2_2
 }  // namespace audio
diff --git a/bluetooth/audio/2.2/default/BluetoothAudioProvider.h b/bluetooth/audio/2.2/default/BluetoothAudioProvider.h
index 0f1f3c6..425ea3b 100644
--- a/bluetooth/audio/2.2/default/BluetoothAudioProvider.h
+++ b/bluetooth/audio/2.2/default/BluetoothAudioProvider.h
@@ -53,6 +53,8 @@
   Return<void> streamStarted(BluetoothAudioStatus status) override;
   Return<void> streamSuspended(BluetoothAudioStatus status) override;
   Return<void> endSession() override;
+  Return<void> updateAudioConfiguration(
+      const AudioConfiguration& audioConfig) override;
 
  protected:
   sp<BluetoothAudioDeathRecipient> death_recipient_;
diff --git a/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp b/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp
index 2fe31d5..490a436 100644
--- a/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp
+++ b/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp
@@ -98,15 +98,9 @@
     case V2_1::SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH:
       provider = &leaudio_output_provider_instance_;
       break;
-    case V2_1::SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
-      provider = &leaudio_offload_output_provider_instance_;
-      break;
     case V2_1::SessionType::LE_AUDIO_SOFTWARE_DECODED_DATAPATH:
       provider = &leaudio_input_provider_instance_;
       break;
-    case V2_1::SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
-      provider = &leaudio_offload_input_provider_instance_;
-      break;
     default:
       status = BluetoothAudioStatus::FAILURE;
   }
@@ -239,7 +233,7 @@
                                 LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
              sessionType == V2_1::SessionType::
                                 LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
-    std::vector<LeAudioCodecCapabilitiesPair> db_codec_capabilities =
+    std::vector<LeAudioCodecCapabilitiesSetting> db_codec_capabilities =
         android::bluetooth::audio::GetLeAudioOffloadCodecCapabilities(
             sessionType);
     if (db_codec_capabilities.size()) {
diff --git a/bluetooth/audio/2.2/types.hal b/bluetooth/audio/2.2/types.hal
index 8ec3660..6755899 100644
--- a/bluetooth/audio/2.2/types.hal
+++ b/bluetooth/audio/2.2/types.hal
@@ -83,23 +83,22 @@
 safe_union AudioCapabilities {
     PcmParameters pcmCapabilities;
     CodecCapabilities codecCapabilities;
-    LeAudioCodecCapabilitiesPair leAudioCapabilities;
+    LeAudioCodecCapabilitiesSetting leAudioCapabilities;
 };
 
 /**
- * Used to specify th le audio capabilities pair of the Hardware offload encode and decode.
+ * Used to specify the le audio capabilities for unicast and broadcast hardware offload.
  */
-struct LeAudioCodecCapabilitiesPair{
-    LeAudioMode mode;
-    LeAudioCodecCapability encodeCapability;
-    LeAudioCodecCapability decodeCapability;
+struct LeAudioCodecCapabilitiesSetting{
+    UnicastCapability unicastEncodeCapability;
+    UnicastCapability unicastDecodeCapability;
+    BroadcastCapability broadcastCapability;
 };
 
 /**
- * Used to specify the le audio capabilities of the codecs supported by Hardware offload
- * for encode or decode.
+ * Used to specify the le audio unicast codec capabilities for hardware offload.
  */
-struct LeAudioCodecCapability {
+struct UnicastCapability {
     CodecType codecType;
     AudioLocation supportedChannel;
 
@@ -112,3 +111,17 @@
     // Should use safe union when there is more than one codec
     Lc3Parameters capabilities;
 };
+
+/**
+ * Used to specify the le audio broadcast codec capabilities for hardware offload.
+ */
+struct BroadcastCapability {
+    CodecType codecType;
+    AudioLocation supportedChannel;
+
+    // Supported channel count for each stream
+    uint8_t channelCountPerStream;
+
+    // Should use safe union when there is more than one codec
+    vec<Lc3Parameters> capabilities;
+};
diff --git a/bluetooth/audio/aidl/Android.bp b/bluetooth/audio/aidl/Android.bp
new file mode 100644
index 0000000..12eed55
--- /dev/null
+++ b/bluetooth/audio/aidl/Android.bp
@@ -0,0 +1,48 @@
+// Copyright (C) 2021 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"],
+}
+
+aidl_interface {
+    name: "android.hardware.bluetooth.audio",
+    vendor_available: true,
+    srcs: ["android/hardware/bluetooth/audio/*.aidl"],
+    stability: "vintf",
+    imports: [
+        "android.hardware.common-V2",
+        "android.hardware.common.fmq-V1",
+        "android.hardware.audio.common",
+    ],
+    backend: {
+        cpp: {
+            enabled: false,
+        },
+        java: {
+            sdk_version: "module_current",
+            enabled: false,
+        },
+        ndk: {
+            vndk: {
+                enabled: true,
+            },
+        },
+    },
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl
new file mode 100644
index 0000000..ad44c26
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@VintfStability
+parcelable AacCapabilities {
+  android.hardware.bluetooth.audio.AacObjectType objectType;
+  int[] sampleRateHz;
+  android.hardware.bluetooth.audio.ChannelMode channelMode;
+  boolean variableBitRateSupported;
+  byte[] bitsPerSample;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacConfiguration.aidl
new file mode 100644
index 0000000..6adef6d
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacConfiguration.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@VintfStability
+parcelable AacConfiguration {
+  android.hardware.bluetooth.audio.AacObjectType objectType;
+  int sampleRateHz;
+  android.hardware.bluetooth.audio.ChannelMode channelMode;
+  boolean variableBitRateEnabled;
+  byte bitsPerSample;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl
new file mode 100644
index 0000000..c129c66
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 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.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum AacObjectType {
+  MPEG2_LC = 1,
+  MPEG4_LC = 2,
+  MPEG4_LTP = 4,
+  MPEG4_SCALABLE = 8,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxCapabilities.aidl
new file mode 100644
index 0000000..4767b69
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxCapabilities.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@VintfStability
+parcelable AptxCapabilities {
+  int[] sampleRateHz;
+  android.hardware.bluetooth.audio.ChannelMode channelMode;
+  byte[] bitsPerSample;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxConfiguration.aidl
new file mode 100644
index 0000000..91e88b3
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxConfiguration.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@VintfStability
+parcelable AptxConfiguration {
+  int sampleRateHz;
+  android.hardware.bluetooth.audio.ChannelMode channelMode;
+  byte bitsPerSample;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioCapabilities.aidl
new file mode 100644
index 0000000..8ae716f
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioCapabilities.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@VintfStability
+union AudioCapabilities {
+  android.hardware.bluetooth.audio.PcmCapabilities pcmCapabilities;
+  android.hardware.bluetooth.audio.CodecCapabilities a2dpCapabilities;
+  android.hardware.bluetooth.audio.LeAudioCodecCapabilitiesSetting leAudioCapabilities;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl
new file mode 100644
index 0000000..50b54c3
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@VintfStability
+union AudioConfiguration {
+  android.hardware.bluetooth.audio.PcmConfiguration pcmConfig;
+  android.hardware.bluetooth.audio.CodecConfiguration a2dpConfig;
+  android.hardware.bluetooth.audio.LeAudioConfiguration leAudioConfig;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioLocation.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioLocation.aidl
new file mode 100644
index 0000000..319a5e2
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioLocation.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@Backing(type="int") @VintfStability
+enum AudioLocation {
+  UNKNOWN = 1,
+  FRONT_LEFT = 2,
+  FRONT_RIGHT = 4,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BluetoothAudioStatus.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BluetoothAudioStatus.aidl
new file mode 100644
index 0000000..7c0d825
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BluetoothAudioStatus.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@Backing(type="int") @VintfStability
+enum BluetoothAudioStatus {
+  UNKNOWN = 0,
+  SUCCESS = 1,
+  UNSUPPORTED_CODEC_CONFIGURATION = 2,
+  FAILURE = 3,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastCapability.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastCapability.aidl
new file mode 100644
index 0000000..58710ef
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastCapability.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2022 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.bluetooth.audio;
+@VintfStability
+parcelable BroadcastCapability {
+  android.hardware.bluetooth.audio.CodecType codecType;
+  android.hardware.bluetooth.audio.AudioLocation supportedChannel;
+  int channelCountPerStream;
+  android.hardware.bluetooth.audio.BroadcastCapability.LeAudioCodecCapabilities leAudioCodecCapabilities;
+  @VintfStability
+  parcelable VendorCapabilities {
+    ParcelableHolder extension;
+  }
+  @VintfStability
+  union LeAudioCodecCapabilities {
+    @nullable android.hardware.bluetooth.audio.Lc3Capabilities[] lc3Capabilities;
+    @nullable android.hardware.bluetooth.audio.BroadcastCapability.VendorCapabilities[] vendorCapabillities;
+  }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl
new file mode 100644
index 0000000..5fa3926
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@VintfStability
+parcelable BroadcastConfiguration {
+  android.hardware.bluetooth.audio.BroadcastConfiguration.BroadcastStreamMap[] streamMap;
+  @VintfStability
+  parcelable BroadcastStreamMap {
+    char streamHandle;
+    int audioChannelAllocation;
+    android.hardware.bluetooth.audio.LeAudioCodecConfiguration leAudioCodecConfig;
+  }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl
new file mode 100644
index 0000000..3ca93c3
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum ChannelMode {
+  UNKNOWN = 1,
+  MONO = 2,
+  STEREO = 4,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecCapabilities.aidl
new file mode 100644
index 0000000..e2a08a0
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecCapabilities.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@VintfStability
+parcelable CodecCapabilities {
+  android.hardware.bluetooth.audio.CodecType codecType;
+  android.hardware.bluetooth.audio.CodecCapabilities.Capabilities capabilities;
+  @VintfStability
+  union Capabilities {
+    android.hardware.bluetooth.audio.SbcCapabilities sbcCapabilities;
+    android.hardware.bluetooth.audio.AacCapabilities aacCapabilities;
+    android.hardware.bluetooth.audio.LdacCapabilities ldacCapabilities;
+    android.hardware.bluetooth.audio.AptxCapabilities aptxCapabilities;
+    android.hardware.bluetooth.audio.Lc3Capabilities lc3Capabilities;
+  }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecConfiguration.aidl
new file mode 100644
index 0000000..34ebd60
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecConfiguration.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@VintfStability
+parcelable CodecConfiguration {
+  android.hardware.bluetooth.audio.CodecType codecType;
+  int encodedAudioBitrate;
+  int peerMtu;
+  boolean isScmstEnabled;
+  android.hardware.bluetooth.audio.CodecConfiguration.CodecSpecific config;
+  @VintfStability
+  union CodecSpecific {
+    android.hardware.bluetooth.audio.SbcConfiguration sbcConfig;
+    android.hardware.bluetooth.audio.AacConfiguration aacConfig;
+    android.hardware.bluetooth.audio.LdacConfiguration ldacConfig;
+    android.hardware.bluetooth.audio.AptxConfiguration aptxConfig;
+    android.hardware.bluetooth.audio.Lc3Configuration lc3Config;
+  }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl
new file mode 100644
index 0000000..44b434b
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@Backing(type="int") @VintfStability
+enum CodecType {
+  UNKNOWN = 0,
+  SBC = 1,
+  AAC = 2,
+  APTX = 3,
+  APTX_HD = 4,
+  LDAC = 5,
+  LC3 = 6,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
new file mode 100644
index 0000000..9a1557a
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@VintfStability
+interface IBluetoothAudioPort {
+  android.hardware.bluetooth.audio.PresentationPosition getPresentationPosition();
+  void startStream();
+  void stopStream();
+  void suspendStream();
+  void updateSourceMetadata(in android.hardware.audio.common.SourceMetadata sourceMetadata);
+  void updateSinkMetadata(in android.hardware.audio.common.SinkMetadata sinkMetadata);
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
new file mode 100644
index 0000000..0dcba2e
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@VintfStability
+interface IBluetoothAudioProvider {
+  void endSession();
+  android.hardware.common.fmq.MQDescriptor<byte,android.hardware.common.fmq.SynchronizedReadWrite> startSession(in android.hardware.bluetooth.audio.IBluetoothAudioPort hostIf, in android.hardware.bluetooth.audio.AudioConfiguration audioConfig);
+  void streamStarted(in android.hardware.bluetooth.audio.BluetoothAudioStatus status);
+  void streamSuspended(in android.hardware.bluetooth.audio.BluetoothAudioStatus status);
+  void updateAudioConfiguration(in android.hardware.bluetooth.audio.AudioConfiguration audioConfig);
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
new file mode 100644
index 0000000..5e33deb
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@VintfStability
+interface IBluetoothAudioProviderFactory {
+  android.hardware.bluetooth.audio.AudioCapabilities[] getProviderCapabilities(in android.hardware.bluetooth.audio.SessionType sessionType);
+  android.hardware.bluetooth.audio.IBluetoothAudioProvider openProvider(in android.hardware.bluetooth.audio.SessionType sessionType);
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Capabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Capabilities.aidl
new file mode 100644
index 0000000..cc4449a
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Capabilities.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@VintfStability
+parcelable Lc3Capabilities {
+  byte[] pcmBitDepth;
+  int[] samplingFrequencyHz;
+  int[] frameDurationUs;
+  int[] octetsPerFrame;
+  byte[] blocksPerSdu;
+  android.hardware.bluetooth.audio.ChannelMode[] channelMode;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Configuration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Configuration.aidl
new file mode 100644
index 0000000..7e8dccf
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Lc3Configuration.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@VintfStability
+parcelable Lc3Configuration {
+  byte pcmBitDepth;
+  int samplingFrequencyHz;
+  int frameDurationUs;
+  int octetsPerFrame;
+  byte blocksPerSdu;
+  android.hardware.bluetooth.audio.ChannelMode channelMode;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacCapabilities.aidl
new file mode 100644
index 0000000..19e041a
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacCapabilities.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@VintfStability
+parcelable LdacCapabilities {
+  int[] sampleRateHz;
+  android.hardware.bluetooth.audio.LdacChannelMode channelMode;
+  android.hardware.bluetooth.audio.LdacQualityIndex qualityIndex;
+  byte[] bitsPerSample;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl
new file mode 100644
index 0000000..a9d6c5e
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum LdacChannelMode {
+  UNKNOWN = 1,
+  STEREO = 2,
+  DUAL = 4,
+  MONO = 8,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacConfiguration.aidl
new file mode 100644
index 0000000..8a37638
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacConfiguration.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@VintfStability
+parcelable LdacConfiguration {
+  int sampleRateHz;
+  android.hardware.bluetooth.audio.LdacChannelMode channelMode;
+  android.hardware.bluetooth.audio.LdacQualityIndex qualityIndex;
+  byte bitsPerSample;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl
new file mode 100644
index 0000000..693392f
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum LdacQualityIndex {
+  HIGH = 1,
+  MID = 2,
+  LOW = 4,
+  ABR = 8,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.aidl
new file mode 100644
index 0000000..9818d54
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022 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.bluetooth.audio;
+@VintfStability
+parcelable LeAudioCodecCapabilitiesSetting {
+  android.hardware.bluetooth.audio.UnicastCapability unicastEncodeCapability;
+  android.hardware.bluetooth.audio.UnicastCapability unicastDecodeCapability;
+  android.hardware.bluetooth.audio.BroadcastCapability broadcastCapability;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
new file mode 100644
index 0000000..bb3d7e4
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@VintfStability
+union LeAudioCodecConfiguration {
+  android.hardware.bluetooth.audio.Lc3Configuration lc3Config;
+  android.hardware.bluetooth.audio.LeAudioCodecConfiguration.VendorConfiguration vendorConfig;
+  @VintfStability
+  parcelable VendorConfiguration {
+    ParcelableHolder extension;
+  }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
new file mode 100644
index 0000000..2bc1791
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@VintfStability
+parcelable LeAudioConfiguration {
+  android.hardware.bluetooth.audio.LeAudioMode mode;
+  android.hardware.bluetooth.audio.LeAudioConfiguration.LeAudioModeConfig modeConfig;
+  android.hardware.bluetooth.audio.CodecType codecType;
+  @VintfStability
+  union LeAudioModeConfig {
+    android.hardware.bluetooth.audio.UnicastConfiguration unicastConfig;
+    android.hardware.bluetooth.audio.BroadcastConfiguration broadcastConfig;
+  }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioMode.aidl
new file mode 100644
index 0000000..766f637
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioMode.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum LeAudioMode {
+  UNKNOWN = 0,
+  UNICAST = 1,
+  BROADCAST = 2,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmCapabilities.aidl
new file mode 100644
index 0000000..6cfe5cd
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmCapabilities.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@VintfStability
+parcelable PcmCapabilities {
+  int[] sampleRateHz;
+  android.hardware.bluetooth.audio.ChannelMode channelMode;
+  byte[] bitsPerSample;
+  int[] dataIntervalUs;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmConfiguration.aidl
new file mode 100644
index 0000000..93d7805
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PcmConfiguration.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@VintfStability
+parcelable PcmConfiguration {
+  int sampleRateHz;
+  android.hardware.bluetooth.audio.ChannelMode channelMode;
+  byte bitsPerSample;
+  int dataIntervalUs;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PresentationPosition.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PresentationPosition.aidl
new file mode 100644
index 0000000..7e997e8
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/PresentationPosition.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2021 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.bluetooth.audio;
+@VintfStability
+parcelable PresentationPosition {
+  long remoteDeviceAudioDelayNanos;
+  long transmittedOctets;
+  android.hardware.bluetooth.audio.PresentationPosition.TimeSpec transmittedOctetsTimestamp;
+  @VintfStability
+  parcelable TimeSpec {
+    long tvSec;
+    long tvNSec;
+  }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl
new file mode 100644
index 0000000..5170f16
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum SbcAllocMethod {
+  ALLOC_MD_S = 1,
+  ALLOC_MD_L = 2,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcCapabilities.aidl
new file mode 100644
index 0000000..ec3aa0f
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcCapabilities.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@VintfStability
+parcelable SbcCapabilities {
+  int[] sampleRateHz;
+  android.hardware.bluetooth.audio.SbcChannelMode channelMode;
+  byte[] blockLength;
+  byte[] numSubbands;
+  android.hardware.bluetooth.audio.SbcAllocMethod allocMethod;
+  byte[] bitsPerSample;
+  int minBitpool;
+  int maxBitpool;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl
new file mode 100644
index 0000000..88fca4a
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum SbcChannelMode {
+  UNKNOWN = 1,
+  JOINT_STEREO = 2,
+  STEREO = 4,
+  DUAL = 8,
+  MONO = 16,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcConfiguration.aidl
new file mode 100644
index 0000000..8eab9c3
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcConfiguration.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@VintfStability
+parcelable SbcConfiguration {
+  int sampleRateHz;
+  android.hardware.bluetooth.audio.SbcChannelMode channelMode;
+  byte blockLength;
+  byte numSubbands;
+  android.hardware.bluetooth.audio.SbcAllocMethod allocMethod;
+  byte bitsPerSample;
+  int minBitpool;
+  int maxBitpool;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl
new file mode 100644
index 0000000..72d7fb2
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum SessionType {
+  UNKNOWN = 0,
+  A2DP_SOFTWARE_ENCODING_DATAPATH = 1,
+  A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH = 2,
+  HEARING_AID_SOFTWARE_ENCODING_DATAPATH = 3,
+  LE_AUDIO_SOFTWARE_ENCODING_DATAPATH = 4,
+  LE_AUDIO_SOFTWARE_DECODING_DATAPATH = 5,
+  LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH = 6,
+  LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH = 7,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastCapability.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastCapability.aidl
new file mode 100644
index 0000000..130fef9
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastCapability.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@VintfStability
+parcelable UnicastCapability {
+  android.hardware.bluetooth.audio.CodecType codecType;
+  android.hardware.bluetooth.audio.AudioLocation supportedChannel;
+  int deviceCount;
+  int channelCountPerDevice;
+  android.hardware.bluetooth.audio.UnicastCapability.LeAudioCodecCapabilities leAudioCodecCapabilities;
+  @VintfStability
+  parcelable VendorCapabilities {
+    ParcelableHolder extension;
+  }
+  @VintfStability
+  union LeAudioCodecCapabilities {
+    android.hardware.bluetooth.audio.Lc3Capabilities lc3Capabilities;
+    android.hardware.bluetooth.audio.UnicastCapability.VendorCapabilities vendorCapabillities;
+  }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastConfiguration.aidl
new file mode 100644
index 0000000..b385763
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastConfiguration.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+@VintfStability
+parcelable UnicastConfiguration {
+  android.hardware.bluetooth.audio.UnicastConfiguration.UnicastStreamMap[] streamMap;
+  int peerDelay;
+  android.hardware.bluetooth.audio.LeAudioCodecConfiguration leAudioCodecConfig;
+  @VintfStability
+  parcelable UnicastStreamMap {
+    char streamHandle;
+    int audioChannelAllocation;
+  }
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl
new file mode 100644
index 0000000..4303883
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.AacObjectType;
+import android.hardware.bluetooth.audio.ChannelMode;
+
+/**
+ * Used for Hardware Encoding AAC codec capabilities
+ */
+@VintfStability
+parcelable AacCapabilities {
+    /* bitfield */
+    AacObjectType objectType;
+    int[] sampleRateHz;
+    /* bitfield */
+    ChannelMode channelMode;
+    boolean variableBitRateSupported;
+    byte[] bitsPerSample;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacConfiguration.aidl
new file mode 100644
index 0000000..30338e7
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacConfiguration.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.AacObjectType;
+import android.hardware.bluetooth.audio.ChannelMode;
+
+/**
+ * Used for Hardware Encoding AAC codec configuration
+ */
+@VintfStability
+parcelable AacConfiguration {
+    AacObjectType objectType;
+    int sampleRateHz;
+    ChannelMode channelMode;
+    boolean variableBitRateEnabled;
+    byte bitsPerSample;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacObjectType.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacObjectType.aidl
new file mode 100644
index 0000000..480e422
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacObjectType.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 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.bluetooth.audio;
+
+@VintfStability
+@Backing(type="byte")
+enum AacObjectType {
+    /**
+     * MPEG-2 Low Complexity. Support is Mandatory.
+     */
+    MPEG2_LC = 1,
+    /**
+     * MPEG-4 Low Complexity. Support is Optional.
+     */
+    MPEG4_LC = 1 << 1,
+    /**
+     * MPEG-4 Long Term Prediction. Support is Optional.
+     */
+    MPEG4_LTP = 1 << 2,
+    /**
+     * MPEG-4 Scalable. Support is Optional.
+     */
+    MPEG4_SCALABLE = 1 << 3,
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxCapabilities.aidl
new file mode 100644
index 0000000..6a37fc6
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxCapabilities.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.ChannelMode;
+
+/**
+ * Used for Hardware Encoding AptX and AptX-HD codec capabilities
+ */
+@VintfStability
+parcelable AptxCapabilities {
+    int[] sampleRateHz;
+    /* bitfield */
+    ChannelMode channelMode;
+    byte[] bitsPerSample;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxConfiguration.aidl
new file mode 100644
index 0000000..83b7b0c
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxConfiguration.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.ChannelMode;
+
+/**
+ * Used for Hardware Encoding AptX and AptX-HD codec configuration
+ */
+@VintfStability
+parcelable AptxConfiguration {
+    int sampleRateHz;
+    ChannelMode channelMode;
+    byte bitsPerSample;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioCapabilities.aidl
new file mode 100644
index 0000000..a75c445
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioCapabilities.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.CodecCapabilities;
+import android.hardware.bluetooth.audio.LeAudioCodecCapabilitiesSetting;
+import android.hardware.bluetooth.audio.PcmCapabilities;
+
+/**
+ * Used to specify the capabilities of the different session types
+ */
+@VintfStability
+union AudioCapabilities {
+    PcmCapabilities pcmCapabilities;
+    CodecCapabilities a2dpCapabilities;
+    LeAudioCodecCapabilitiesSetting leAudioCapabilities;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl
new file mode 100644
index 0000000..81b41dc
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.CodecConfiguration;
+import android.hardware.bluetooth.audio.LeAudioConfiguration;
+import android.hardware.bluetooth.audio.PcmConfiguration;
+
+/**
+ * Used to configure either a Hardware or Software Encoding session based on session type
+ */
+@VintfStability
+union AudioConfiguration {
+    PcmConfiguration pcmConfig;
+    CodecConfiguration a2dpConfig;
+    LeAudioConfiguration leAudioConfig;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioLocation.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioLocation.aidl
new file mode 100644
index 0000000..dedfbf9
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioLocation.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+@VintfStability
+@Backing(type="int")
+enum AudioLocation {
+    UNKNOWN = 1,
+    FRONT_LEFT = 1 << 1,
+    FRONT_RIGHT = 1 << 2,
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BluetoothAudioStatus.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BluetoothAudioStatus.aidl
new file mode 100644
index 0000000..ec78445
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BluetoothAudioStatus.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+@VintfStability
+@Backing(type="int")
+enum BluetoothAudioStatus {
+    UNKNOWN = 0,
+    SUCCESS = 1,
+    UNSUPPORTED_CODEC_CONFIGURATION = 2,
+    // General failure
+    FAILURE = 3
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastCapability.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastCapability.aidl
new file mode 100644
index 0000000..cb63f88
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastCapability.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2022 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.AudioLocation;
+import android.hardware.bluetooth.audio.CodecType;
+import android.hardware.bluetooth.audio.Lc3Capabilities;
+import android.hardware.bluetooth.audio.LeAudioMode;
+
+/**
+ * Used to specify the le audio broadcast codec capabilities for hardware offload.
+ */
+@VintfStability
+parcelable BroadcastCapability {
+    @VintfStability
+    parcelable VendorCapabilities {
+        ParcelableHolder extension;
+    }
+    @VintfStability
+    union LeAudioCodecCapabilities {
+        @nullable Lc3Capabilities[] lc3Capabilities;
+        @nullable VendorCapabilities[] vendorCapabillities;
+    }
+    CodecType codecType;
+    AudioLocation supportedChannel;
+    // Supported channel count for each stream
+    int channelCountPerStream;
+    LeAudioCodecCapabilities leAudioCodecCapabilities;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl
new file mode 100644
index 0000000..cfc9d3a
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/BroadcastConfiguration.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.LeAudioCodecConfiguration;
+
+@VintfStability
+parcelable BroadcastConfiguration {
+    @VintfStability
+    parcelable BroadcastStreamMap {
+        /*
+         * The connection handle used for a unicast or a broadcast group.
+         * Range: 0x0000 to 0xEFFF
+         */
+        char streamHandle;
+        /*
+         * Audio channel allocation is  a bit field, each enabled bit means that given audio
+         * direction, i.e. "left", or "right" is used. Ordering of audio channels comes from the
+         * least significant bit to the most significant bit.
+         */
+        int audioChannelAllocation;
+        LeAudioCodecConfiguration leAudioCodecConfig;
+    }
+    BroadcastStreamMap[] streamMap;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/ChannelMode.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/ChannelMode.aidl
new file mode 100644
index 0000000..2df879d
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/ChannelMode.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+@VintfStability
+@Backing(type="byte")
+enum ChannelMode {
+    UNKNOWN = 1,
+    MONO = 1 << 1,
+    STEREO = 1 << 2,
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecCapabilities.aidl
new file mode 100644
index 0000000..5bf0252
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecCapabilities.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.AacCapabilities;
+import android.hardware.bluetooth.audio.AptxCapabilities;
+import android.hardware.bluetooth.audio.CodecType;
+import android.hardware.bluetooth.audio.Lc3Capabilities;
+import android.hardware.bluetooth.audio.LdacCapabilities;
+import android.hardware.bluetooth.audio.SbcCapabilities;
+
+/**
+ * Used to specify the capabilities of the codecs supported by Hardware Encoding.
+ * AptX and AptX-HD both use the AptxCapabilities field.
+ */
+@VintfStability
+parcelable CodecCapabilities {
+    @VintfStability
+    union Capabilities {
+        SbcCapabilities sbcCapabilities;
+        AacCapabilities aacCapabilities;
+        LdacCapabilities ldacCapabilities;
+        AptxCapabilities aptxCapabilities;
+        Lc3Capabilities lc3Capabilities;
+    }
+    CodecType codecType;
+    Capabilities capabilities;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecConfiguration.aidl
new file mode 100644
index 0000000..9e43f22
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecConfiguration.aidl
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.AacConfiguration;
+import android.hardware.bluetooth.audio.AptxConfiguration;
+import android.hardware.bluetooth.audio.CodecType;
+import android.hardware.bluetooth.audio.Lc3Configuration;
+import android.hardware.bluetooth.audio.LdacConfiguration;
+import android.hardware.bluetooth.audio.SbcConfiguration;
+
+/**
+ * Used to configure a Hardware Encoding session.
+ * AptX and AptX-HD both use the AptxConfiguration field.
+ */
+@VintfStability
+parcelable CodecConfiguration {
+    @VintfStability
+    union CodecSpecific {
+        SbcConfiguration sbcConfig;
+        AacConfiguration aacConfig;
+        LdacConfiguration ldacConfig;
+        AptxConfiguration aptxConfig;
+        Lc3Configuration lc3Config;
+    }
+    CodecType codecType;
+    /**
+     * The encoded audio bitrate in bits / second.
+     * 0x00000000 - The audio bitrate is not specified / unused
+     * 0x00000001 - 0x00FFFFFF - Encoded audio bitrate in bits/second
+     * 0x01000000 - 0xFFFFFFFF - Reserved
+     *
+     * The HAL needs to support all legal bitrates for the selected codec.
+     */
+    int encodedAudioBitrate;
+    /**
+     * Peer MTU (in two-octets)
+     */
+    int peerMtu;
+    /**
+     * Content protection by SCMS-T
+     */
+    boolean isScmstEnabled;
+    CodecSpecific config;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecType.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecType.aidl
new file mode 100644
index 0000000..68c60f5
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecType.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+@VintfStability
+@Backing(type="int")
+enum CodecType {
+    UNKNOWN,
+    SBC,
+    AAC,
+    APTX,
+    APTX_HD,
+    LDAC,
+    LC3,
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
new file mode 100644
index 0000000..827f57d
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioPort.aidl
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+import android.hardware.audio.common.SinkMetadata;
+import android.hardware.audio.common.SourceMetadata;
+import android.hardware.bluetooth.audio.PresentationPosition;
+
+/**
+ * HAL interface from the Audio HAL to the Bluetooth stack
+ *
+ * The Audio HAL calls methods in this interface to start, suspend, and stop
+ * an audio stream. These calls return immediately and the results, if any,
+ * are sent over the IBluetoothAudioProvider interface.
+ *
+ * Moreover, the Audio HAL can also get the presentation position of the stream
+ * and provide stream metadata.
+ *
+ */
+@VintfStability
+interface IBluetoothAudioPort {
+    /**
+     * Get the audio presentation position.
+     *
+     * @return the audio presentation position
+     *
+     */
+    PresentationPosition getPresentationPosition();
+
+    /**
+     * This indicates that the caller of this method has opened the data path
+     * and wants to start an audio stream. The caller must wait for a
+     * IBluetoothAudioProvider.streamStarted(Status) call.
+     */
+    void startStream();
+
+    /**
+     * This indicates that the caller of this method wants to stop the audio
+     * stream. The data path will be closed after this call. There is no
+     * callback from the IBluetoothAudioProvider interface even though the
+     * teardown is asynchronous.
+     */
+    void stopStream();
+
+    /**
+     * This indicates that the caller of this method wants to suspend the audio
+     * stream. The caller must wait for the Bluetooth process to call
+     * IBluetoothAudioProvider.streamSuspended(Status). The caller still keeps
+     * the data path open.
+     */
+    void suspendStream();
+
+    /**
+     * Called when the metadata of the stream's source has been changed.
+     *
+     * @param sourceMetadata Description of the audio that is played by the
+     *    clients.
+     */
+    void updateSourceMetadata(in SourceMetadata sourceMetadata);
+
+    /**
+     * Called when the metadata of the stream's sink has been changed.
+     *
+     * @param sinkMetadata as passed from Audio Framework
+     */
+    void updateSinkMetadata(in SinkMetadata sinkMetadata);
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
new file mode 100644
index 0000000..6f88f30
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.AudioConfiguration;
+import android.hardware.bluetooth.audio.BluetoothAudioStatus;
+import android.hardware.bluetooth.audio.IBluetoothAudioPort;
+import android.hardware.common.fmq.MQDescriptor;
+import android.hardware.common.fmq.SynchronizedReadWrite;
+
+/**
+ * HAL interface from the Bluetooth stack to the Audio HAL
+ *
+ * The Bluetooth stack calls methods in this interface to start and end audio
+ * sessions and sends callback events to the Audio HAL.
+ *
+ */
+@VintfStability
+interface IBluetoothAudioProvider {
+    /**
+     * Ends the current session and unregisters the IBluetoothAudioPort
+     * interface.
+     */
+    void endSession();
+
+    /**
+     * This method indicates that the Bluetooth stack is ready to stream audio.
+     * It registers an instance of IBluetoothAudioPort with and provides the
+     * current negotiated codec to the Audio HAL. After this method is called,
+     * the Audio HAL can invoke IBluetoothAudioPort.startStream().
+     *
+     * Note: endSession() must be called to unregister this IBluetoothAudioPort
+     *
+     * @param hostIf An instance of IBluetoothAudioPort for stream control
+     * @param audioConfig The audio configuration negotiated with the remote
+     *    device. The PCM parameters are set if software based encoding,
+     *    otherwise the correct codec configuration is used for hardware
+     *    encoding.
+     *
+     * @return The fast message queue for audio data from/to this
+     *    provider. Audio data will be in PCM format as specified by the
+     *    audioConfig.pcmConfig parameter. Invalid if streaming is offloaded
+     *    from/to hardware or on failure
+     */
+    MQDescriptor<byte, SynchronizedReadWrite> startSession(
+            in IBluetoothAudioPort hostIf, in AudioConfiguration audioConfig);
+
+    /**
+     * Callback for IBluetoothAudioPort.startStream()
+     *
+     * @param status true for SUCCESS or false for FAILURE
+     */
+    void streamStarted(in BluetoothAudioStatus status);
+
+    /**
+     * Callback for IBluetoothAudioPort.suspendStream()
+     *
+     * @param status true for SUCCESS or false for FAILURE
+     */
+    void streamSuspended(in BluetoothAudioStatus status);
+
+    /**
+     * Called when the audio configuration of the stream has been changed.
+     *
+     * @param audioConfig The audio configuration negotiated with the remote
+     *    device. The PCM parameters are set if software based encoding,
+     *    otherwise the correct codec configuration is used for hardware
+     *    encoding.
+     */
+    void updateAudioConfiguration(in AudioConfiguration audioConfig);
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
new file mode 100644
index 0000000..3cde22c
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.AudioCapabilities;
+import android.hardware.bluetooth.audio.IBluetoothAudioProvider;
+import android.hardware.bluetooth.audio.SessionType;
+/**
+ * This factory allows a HAL implementation to be split into multiple
+ * independent providers.
+ *
+ * When the Bluetooth stack is ready to create an audio session, it must first
+ * obtain the IBluetoothAudioProvider for that session type by calling
+ * openProvider().
+ *
+ */
+
+@VintfStability
+interface IBluetoothAudioProviderFactory {
+    /**
+     * Gets a list of audio capabilities for a session type.
+     *
+     * For software encoding, the PCM capabilities are returned.
+     * For hardware encoding, the supported codecs and their capabilities are
+     * returned.
+     *
+     * @param sessionType The session type (e.g.
+     *    A2DP_SOFTWARE_ENCODING_DATAPATH).
+     * @return A list containing all the capabilities
+     *    supported by the sesson type. The capabilities is a list of
+     *    available options when configuring the codec for the session.
+     *    For software encoding it is the PCM data rate.
+     *    For hardware encoding it is the list of supported codecs and their
+     *    capabilities.
+     *    If a provider isn't supported, an empty list should be returned.
+     *    Note: Only one entry should exist per codec when using hardware
+     *    encoding.
+     */
+    AudioCapabilities[] getProviderCapabilities(in SessionType sessionType);
+
+    /**
+     * Opens an audio provider for a session type. To close the provider, it is
+     * necessary to release references to the returned provider object.
+     *
+     * @param sessionType The session type (e.g.
+     *    LE_AUDIO_SOFTWARE_ENCODING_DATAPATH).
+     *
+     * @return provider The provider of the specified session type
+     */
+    IBluetoothAudioProvider openProvider(in SessionType sessionType);
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Capabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Capabilities.aidl
new file mode 100644
index 0000000..fc2f382
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Capabilities.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.ChannelMode;
+
+/**
+ * Used for Hardware Encoding/Decoding LC3 codec capabilities.
+ */
+@VintfStability
+parcelable Lc3Capabilities {
+    /*
+     * PCM is Input for encoder, Output for decoder
+     */
+    byte[] pcmBitDepth;
+    /*
+     * codec-specific parameters
+     */
+    int[] samplingFrequencyHz;
+    /*
+     * FrameDuration based on microseconds.
+     */
+    int[] frameDurationUs;
+    /*
+     * length in octets of a codec frame
+     */
+    int[] octetsPerFrame;
+    /*
+     * Number of blocks of codec frames per single SDU (Service Data Unit)
+     */
+    byte[] blocksPerSdu;
+    /*
+     * Channel mode used in A2DP special audio, ignored in standard LE Audio mode
+     */
+    ChannelMode[] channelMode;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Configuration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Configuration.aidl
new file mode 100644
index 0000000..e8a93b2
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Lc3Configuration.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.ChannelMode;
+
+/**
+ * Used for Hardware Encoding/Decoding LC3 codec configuration.
+ */
+@VintfStability
+parcelable Lc3Configuration {
+    /*
+     * PCM is Input for encoder, Output for decoder
+     */
+    byte pcmBitDepth;
+    /*
+     * codec-specific parameters
+     */
+    int samplingFrequencyHz;
+    /*
+     * FrameDuration based on microseconds.
+     */
+    int frameDurationUs;
+    /*
+     * length in octets of a codec frame
+     */
+    int octetsPerFrame;
+    /*
+     * Number of blocks of codec frames per single SDU (Service Data Unit)
+     */
+    byte blocksPerSdu;
+    /*
+     * Channel mode used in A2DP special audio, ignored in standard LE Audio mode
+     */
+    ChannelMode channelMode;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacCapabilities.aidl
new file mode 100644
index 0000000..44cca7e
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacCapabilities.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.LdacChannelMode;
+import android.hardware.bluetooth.audio.LdacQualityIndex;
+
+/**
+ * Used for Hardware Encoding LDAC codec capabilities
+ * all qualities must be supported.
+ */
+@VintfStability
+parcelable LdacCapabilities {
+    int[] sampleRateHz;
+    /* bitfiled */
+    LdacChannelMode channelMode;
+    /* bitfiled */
+    LdacQualityIndex qualityIndex;
+    byte[] bitsPerSample;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacChannelMode.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacChannelMode.aidl
new file mode 100644
index 0000000..3acca32
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacChannelMode.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+/**
+ * Channel Mode: 3 bits
+ */
+@VintfStability
+@Backing(type="byte")
+enum LdacChannelMode {
+    UNKNOWN = 1,
+    STEREO = 1 << 1,
+    DUAL = 1 << 2,
+    MONO = 1 << 3,
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacConfiguration.aidl
new file mode 100644
index 0000000..cc03dd0
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacConfiguration.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.LdacChannelMode;
+import android.hardware.bluetooth.audio.LdacQualityIndex;
+
+/**
+ * Used for Hardware Encoding LDAC codec configuration
+ * Only used when configuring the codec.
+ */
+@VintfStability
+parcelable LdacConfiguration {
+    int sampleRateHz;
+    LdacChannelMode channelMode;
+    LdacQualityIndex qualityIndex;
+    byte bitsPerSample;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacQualityIndex.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacQualityIndex.aidl
new file mode 100644
index 0000000..cb12583
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LdacQualityIndex.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+@VintfStability
+@Backing(type="byte")
+enum LdacQualityIndex {
+    /**
+     * 990kbps
+     */
+    HIGH = 1,
+    /**
+     * 660kbps
+     */
+    MID = 1 << 1,
+    /**
+     * 330kbps
+     */
+    LOW = 1 << 2,
+    /**
+     * Adaptive Bit Rate mode
+     */
+    ABR = 1 << 3,
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.aidl
new file mode 100644
index 0000000..58dac06
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecCapabilitiesSetting.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2022 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.BroadcastCapability;
+import android.hardware.bluetooth.audio.UnicastCapability;
+
+/**
+ * Used to specify the le audio capabilities for unicast and broadcast hardware offload.
+ */
+@VintfStability
+parcelable LeAudioCodecCapabilitiesSetting {
+    UnicastCapability unicastEncodeCapability;
+    UnicastCapability unicastDecodeCapability;
+    BroadcastCapability broadcastCapability;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
new file mode 100644
index 0000000..421eeb2
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.Lc3Configuration;
+
+@VintfStability
+union LeAudioCodecConfiguration {
+    @VintfStability
+    parcelable VendorConfiguration {
+        ParcelableHolder extension;
+    }
+    Lc3Configuration lc3Config;
+    VendorConfiguration vendorConfig;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
new file mode 100644
index 0000000..515794b
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.BroadcastConfiguration;
+import android.hardware.bluetooth.audio.CodecType;
+import android.hardware.bluetooth.audio.LeAudioMode;
+import android.hardware.bluetooth.audio.UnicastConfiguration;
+
+@VintfStability
+parcelable LeAudioConfiguration {
+    @VintfStability
+    union LeAudioModeConfig {
+        UnicastConfiguration unicastConfig;
+        BroadcastConfiguration broadcastConfig;
+    }
+    /*
+     * The mode of the LE audio
+     */
+    LeAudioMode mode;
+    LeAudioModeConfig modeConfig;
+    CodecType codecType;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioMode.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioMode.aidl
new file mode 100644
index 0000000..2cf019e
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioMode.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+@VintfStability
+@Backing(type="byte")
+enum LeAudioMode {
+    UNKNOWN,
+    UNICAST,
+    BROADCAST,
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmCapabilities.aidl
new file mode 100644
index 0000000..f5d699e
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmCapabilities.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.ChannelMode;
+
+/**
+ * Used for Software Encoding audio feed capabilities
+ */
+@VintfStability
+parcelable PcmCapabilities {
+    int[] sampleRateHz;
+    ChannelMode channelMode;
+    byte[] bitsPerSample;
+    /**
+     * Data interval for data transfer
+     */
+    int[] dataIntervalUs;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmConfiguration.aidl
new file mode 100644
index 0000000..03aa27b
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PcmConfiguration.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.ChannelMode;
+
+/**
+ * Used for Software Encoding audio feed configuration
+ */
+@VintfStability
+parcelable PcmConfiguration {
+    int sampleRateHz;
+    ChannelMode channelMode;
+    byte bitsPerSample;
+    /**
+     * Data interval for data transfer
+     */
+    int dataIntervalUs;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PresentationPosition.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PresentationPosition.aidl
new file mode 100644
index 0000000..f3b8aed
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/PresentationPosition.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2021 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.bluetooth.audio;
+
+@VintfStability
+parcelable PresentationPosition {
+    @VintfStability
+    parcelable TimeSpec {
+        /**
+         * seconds
+         */
+        long tvSec;
+        /**
+         *  nanoseconds
+         */
+        long tvNSec;
+    }
+    /*
+     * remoteDeviceAudioDelayNanos the audio delay from when the remote
+     * device (e.g. headset) receives audio data to when the device plays the
+     * sound. If the delay is unknown, the value is set to zero.
+     */
+    long remoteDeviceAudioDelayNanos;
+    /*
+     * transmittedOctets the number of audio data octets that were sent
+     * to a remote device. This excludes octets that have been written to the
+     * data path but have not been sent to the remote device. The count is
+     * not reset until stopStream() is called. If the software data path is
+     * unused (e.g. Hardware Offload), the value is set to 0.
+     */
+    long transmittedOctets;
+    /*
+     * transmittedOctetsTimestamp the value of CLOCK_MONOTONIC
+     * corresponding to transmittedOctets. If the software data path is
+     * unused (e.g., for Hardware Offload), the value is set to zero.
+     */
+    TimeSpec transmittedOctetsTimestamp;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcAllocMethod.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcAllocMethod.aidl
new file mode 100644
index 0000000..7047e34
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcAllocMethod.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+@VintfStability
+@Backing(type="byte")
+enum SbcAllocMethod {
+    /**
+     * SNR
+     */
+    ALLOC_MD_S = 1,
+    /**
+     * Loudness
+     */
+    ALLOC_MD_L = 1 << 1,
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcCapabilities.aidl
new file mode 100644
index 0000000..cf62ed4
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcCapabilities.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.SbcAllocMethod;
+import android.hardware.bluetooth.audio.SbcChannelMode;
+
+/**
+ * Used for Hardware Encoding SBC codec capabilities.
+ */
+@VintfStability
+parcelable SbcCapabilities {
+    int[] sampleRateHz;
+    /* bitfield */
+    SbcChannelMode channelMode;
+    byte[] blockLength;
+    byte[] numSubbands;
+    /* bitfield */
+    SbcAllocMethod allocMethod;
+    byte[] bitsPerSample;
+    /*
+     * range from 2 to 250.
+     */
+    int minBitpool;
+    /*
+     * range from 2 to 250.
+     */
+    int maxBitpool;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcChannelMode.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcChannelMode.aidl
new file mode 100644
index 0000000..7eb38cd
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcChannelMode.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+@VintfStability
+@Backing(type="byte")
+enum SbcChannelMode {
+    UNKNOWN = 1,
+    JOINT_STEREO = 1 << 1,
+    STEREO = 1 << 2,
+    DUAL = 1 << 3,
+    MONO = 1 << 4,
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcConfiguration.aidl
new file mode 100644
index 0000000..054d03e
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SbcConfiguration.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.SbcAllocMethod;
+import android.hardware.bluetooth.audio.SbcChannelMode;
+
+/**
+ * Used for Hardware Encoding SBC codec configuration.
+ */
+@VintfStability
+parcelable SbcConfiguration {
+    int sampleRateHz;
+    SbcChannelMode channelMode;
+    byte blockLength;
+    byte numSubbands;
+    SbcAllocMethod allocMethod;
+    byte bitsPerSample;
+    /*
+     * range from 2 to 250.
+     */
+    int minBitpool;
+    /*
+     * range from 2 to 250.
+     */
+    int maxBitpool;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl
new file mode 100644
index 0000000..30faae3
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+@VintfStability
+@Backing(type="byte")
+enum SessionType {
+    UNKNOWN,
+    /**
+     * A2DP legacy that AVDTP media is encoded by Bluetooth Stack
+     */
+    A2DP_SOFTWARE_ENCODING_DATAPATH,
+    /**
+     * The encoding of AVDTP media is done by HW and there is control only
+     */
+    A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+    /**
+     * Used when encoded by Bluetooth Stack and streaming to Hearing Aid
+     */
+    HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
+    /**
+     * Used when encoded by Bluetooth Stack and streaming to LE Audio device
+     */
+    LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
+    /**
+     * Used when decoded by Bluetooth Stack and streaming to audio framework
+     */
+    LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
+    /**
+     * Encoding is done by HW an there is control only
+     */
+    LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+    /**
+     * Decoding is done by HW an there is control only
+     */
+    LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastCapability.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastCapability.aidl
new file mode 100644
index 0000000..cd8a4c1
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastCapability.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.AudioLocation;
+import android.hardware.bluetooth.audio.CodecType;
+import android.hardware.bluetooth.audio.Lc3Capabilities;
+import android.hardware.bluetooth.audio.LeAudioMode;
+
+/**
+ * Used to specify the le audio unicast codec capabilities for hardware offload.
+ */
+@VintfStability
+parcelable UnicastCapability {
+    @VintfStability
+    parcelable VendorCapabilities {
+        ParcelableHolder extension;
+    }
+    @VintfStability
+    union LeAudioCodecCapabilities {
+        Lc3Capabilities lc3Capabilities;
+        VendorCapabilities vendorCapabillities;
+    }
+    CodecType codecType;
+    AudioLocation supportedChannel;
+    // The number of connected device
+    int deviceCount;
+    // Supported channel count for each device
+    int channelCountPerDevice;
+    LeAudioCodecCapabilities leAudioCodecCapabilities;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastConfiguration.aidl
new file mode 100644
index 0000000..7be2c5b
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastConfiguration.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 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.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.LeAudioCodecConfiguration;
+
+@VintfStability
+parcelable UnicastConfiguration {
+    @VintfStability
+    parcelable UnicastStreamMap {
+        /*
+         * The connection handle used for a unicast or a broadcast group.
+         * Range: 0x0000 to 0xEFFF
+         */
+        char streamHandle;
+        /*
+         * Audio channel allocation is  a bit field, each enabled bit means that given audio
+         * direction, i.e. "left", or "right" is used. Ordering of audio channels comes from the
+         * least significant bit to the most significant bit. The valus follows the Bluetooth SIG
+         * Audio Location assigned number.
+         */
+        int audioChannelAllocation;
+    }
+    UnicastStreamMap[] streamMap;
+    int peerDelay;
+    LeAudioCodecConfiguration leAudioCodecConfig;
+}
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h b/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h
index 71ab464..368939e 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h
+++ b/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h
@@ -48,20 +48,38 @@
     std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
         BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
     if (session_ptr != nullptr) {
-      return session_ptr->GetAudioSession()->RegisterStatusCback(cbacks);
+      PortStatusCallbacks_2_2 cb = {
+          .control_result_cb_ = cbacks.control_result_cb_,
+          .session_changed_cb_ = cbacks.session_changed_cb_,
+          .audio_configuration_changed_cb_ = nullptr};
+      return session_ptr->RegisterStatusCback(cb);
+    }
+    return kObserversCookieUndefined;
+  }
+
+  // The control API helps the bluetooth_audio module to register
+  // PortStatusCallbacks_2_2
+  // @return: cookie - the assigned number to this bluetooth_audio output
+  static uint16_t RegisterControlResultCback(
+      const SessionType_2_1& session_type,
+      const PortStatusCallbacks_2_2& cbacks) {
+    std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
+        BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      return session_ptr->RegisterStatusCback(cbacks);
     }
     return kObserversCookieUndefined;
   }
 
   // The control API helps the bluetooth_audio module to unregister
-  // PortStatusCallbacks
+  // PortStatusCallbacks and PortStatusCallbacks_2_2
   // @param: cookie - indicates which bluetooth_audio output is
   static void UnregisterControlResultCback(const SessionType_2_1& session_type,
                                            uint16_t cookie) {
     std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
         BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
     if (session_ptr != nullptr) {
-      session_ptr->GetAudioSession()->UnregisterStatusCback(cookie);
+      session_ptr->UnregisterStatusCback(cookie);
     }
   }
 
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSessionReport_2_2.h b/bluetooth/audio/utils/session/BluetoothAudioSessionReport_2_2.h
index 79121cc..17e140e 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSessionReport_2_2.h
+++ b/bluetooth/audio/utils/session/BluetoothAudioSessionReport_2_2.h
@@ -60,7 +60,20 @@
     std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
         BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
     if (session_ptr != nullptr) {
-      session_ptr->GetAudioSession()->ReportControlStatus(start_resp, status);
+      session_ptr->ReportControlStatus(start_resp, status);
+    }
+  }
+  // The API reports the Bluetooth stack has replied the changed of the audio
+  // configuration, and will inform registered bluetooth_audio outputs
+  static void ReportAudioConfigChanged(
+      const ::android::hardware::bluetooth::audio::V2_1::SessionType&
+          session_type,
+      const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration&
+          audio_config) {
+    std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
+        BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      session_ptr->ReportAudioConfigChanged(audio_config);
     }
   }
 };
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp
index db1619b..60ac4ec 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp
@@ -359,7 +359,7 @@
       audio_session->stack_iface_ = stack_iface;
       LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_2_1_)
                 << ", AudioConfiguration=" << toString(audio_config);
-      audio_session->ReportSessionStatus();
+      ReportSessionStatus();
     };
   }
 }
@@ -386,7 +386,150 @@
   audio_session->stack_iface_ = nullptr;
   audio_session->UpdateDataPath(nullptr);
   if (toggled) {
+    ReportSessionStatus();
+  }
+}
+
+// The control function helps the bluetooth_audio module to register
+// PortStatusCallbacks_2_2
+// @return: cookie - the assigned number to this bluetooth_audio output
+uint16_t BluetoothAudioSession_2_2::RegisterStatusCback(
+    const PortStatusCallbacks_2_2& cbacks) {
+  if (session_type_2_1_ !=
+          SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
+      session_type_2_1_ !=
+          SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+    PortStatusCallbacks cb = {
+        .control_result_cb_ = cbacks.control_result_cb_,
+        .session_changed_cb_ = cbacks.session_changed_cb_};
+    return audio_session->RegisterStatusCback(cb);
+  }
+
+  std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
+  uint16_t cookie = ObserversCookieGetInitValue(session_type_2_1_);
+  uint16_t cookie_upper_bound = ObserversCookieGetUpperBound(session_type_2_1_);
+
+  while (cookie < cookie_upper_bound) {
+    if (observers_.find(cookie) == observers_.end()) {
+      break;
+    }
+    ++cookie;
+  }
+  if (cookie >= cookie_upper_bound) {
+    LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_2_1_)
+               << " has " << observers_.size()
+               << " observers already (No Resource)";
+    return kObserversCookieUndefined;
+  }
+  std::shared_ptr<struct PortStatusCallbacks_2_2> cb =
+      std::make_shared<struct PortStatusCallbacks_2_2>();
+  *cb = cbacks;
+  observers_[cookie] = cb;
+  return cookie;
+}
+
+// The control function helps the bluetooth_audio module to unregister
+// PortStatusCallbacks_2_2
+// @param: cookie - indicates which bluetooth_audio output is
+void BluetoothAudioSession_2_2::UnregisterStatusCback(uint16_t cookie) {
+  std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
+  if (session_type_2_1_ !=
+          SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
+      session_type_2_1_ !=
+          SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+    audio_session->UnregisterStatusCback(cookie);
+    return;
+  }
+  if (observers_.erase(cookie) != 1) {
+    LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_2_1_)
+                 << " no such provider=0x"
+                 << android::base::StringPrintf("%04x", cookie);
+  }
+}
+
+// invoking the registered session_changed_cb_
+void BluetoothAudioSession_2_2::ReportSessionStatus() {
+  // This is locked already by OnSessionStarted / OnSessionEnded
+  if (session_type_2_1_ !=
+          SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
+      session_type_2_1_ !=
+          SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
     audio_session->ReportSessionStatus();
+    return;
+  }
+  if (observers_.empty()) {
+    LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_2_1_)
+              << " has NO port state observer";
+    return;
+  }
+  for (auto& observer : observers_) {
+    uint16_t cookie = observer.first;
+    std::shared_ptr<struct PortStatusCallbacks_2_2> cb = observer.second;
+    LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_2_1_)
+              << " notify to bluetooth_audio=0x"
+              << android::base::StringPrintf("%04x", cookie);
+    cb->session_changed_cb_(cookie);
+  }
+}
+
+// The report function is used to report that the Bluetooth stack has notified
+// the result of startStream or suspendStream, and will invoke
+// control_result_cb_ to notify registered bluetooth_audio outputs
+void BluetoothAudioSession_2_2::ReportControlStatus(
+    bool start_resp, const BluetoothAudioStatus& status) {
+  if (session_type_2_1_ !=
+          SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
+      session_type_2_1_ !=
+          SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+    audio_session->ReportControlStatus(start_resp, status);
+    return;
+  }
+  std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
+  if (observers_.empty()) {
+    LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_2_1_)
+                 << " has NO port state observer";
+    return;
+  }
+  for (auto& observer : observers_) {
+    uint16_t cookie = observer.first;
+    std::shared_ptr<struct PortStatusCallbacks_2_2> cb = observer.second;
+    LOG(INFO) << __func__ << " - status=" << toString(status)
+              << " for SessionType=" << toString(session_type_2_1_)
+              << ", bluetooth_audio=0x"
+              << android::base::StringPrintf("%04x", cookie)
+              << (start_resp ? " started" : " suspended");
+    cb->control_result_cb_(cookie, start_resp, status);
+  }
+}
+
+// The report function is used to report that the Bluetooth stack has notified
+// the result of startStream or suspendStream, and will invoke
+// control_result_cb_ to notify registered bluetooth_audio outputs
+void BluetoothAudioSession_2_2::ReportAudioConfigChanged(
+    const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration&
+        audio_config) {
+  if (session_type_2_1_ !=
+          SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
+      session_type_2_1_ !=
+          SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+    return;
+  }
+  std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
+  audio_config_2_2_ = audio_config;
+  if (observers_.empty()) {
+    LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_2_1_)
+                 << " has NO port state observer";
+    return;
+  }
+  for (auto& observer : observers_) {
+    uint16_t cookie = observer.first;
+    std::shared_ptr<struct PortStatusCallbacks_2_2> cb = observer.second;
+    LOG(INFO) << __func__ << " for SessionType=" << toString(session_type_2_1_)
+              << ", bluetooth_audio=0x"
+              << android::base::StringPrintf("%04x", cookie);
+    if (cb->audio_configuration_changed_cb_ != nullptr) {
+      cb->audio_configuration_changed_cb_(cookie);
+    }
   }
 }
 
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h
index 6ac0188..3673fd8 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h
@@ -28,6 +28,40 @@
 namespace bluetooth {
 namespace audio {
 
+inline uint16_t ObserversCookieGetInitValue(
+    const ::android::hardware::bluetooth::audio::V2_1::SessionType&
+        session_type) {
+  return (static_cast<uint16_t>(session_type) << 8 & 0xff00);
+}
+inline uint16_t ObserversCookieGetUpperBound(
+    const ::android::hardware::bluetooth::audio::V2_1::SessionType&
+        session_type) {
+  return (static_cast<uint16_t>(session_type) << 8 & 0xff00) +
+         kObserversCookieSize;
+}
+
+struct PortStatusCallbacks_2_2 {
+  // control_result_cb_ - when the Bluetooth stack reports results of
+  // streamStarted or streamSuspended, the BluetoothAudioProvider will invoke
+  // this callback to report to the bluetooth_audio module.
+  // @param: cookie - indicates which bluetooth_audio output should handle
+  // @param: start_resp - this report is for startStream or not
+  // @param: status - the result of startStream
+  std::function<void(uint16_t cookie, bool start_resp,
+                     const BluetoothAudioStatus& status)>
+      control_result_cb_;
+  // session_changed_cb_ - when the Bluetooth stack start / end session, the
+  // BluetoothAudioProvider will invoke this callback to notify to the
+  // bluetooth_audio module.
+  // @param: cookie - indicates which bluetooth_audio output should handle
+  std::function<void(uint16_t cookie)> session_changed_cb_;
+  // audio_configuration_changed_cb_ - when the Bluetooth stack change the audio
+  // configuration, the BluetoothAudioProvider will invoke this callback to
+  // notify to the bluetooth_audio module.
+  // @param: cookie - indicates which bluetooth_audio output should handle
+  std::function<void(uint16_t cookie)> audio_configuration_changed_cb_;
+};
+
 class BluetoothAudioSession_2_2 {
  private:
   std::shared_ptr<BluetoothAudioSession> audio_session;
@@ -50,6 +84,13 @@
   static ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
       invalidLeOffloadAudioConfiguration;
 
+  // saving those registered bluetooth_audio's callbacks
+  std::unordered_map<uint16_t, std::shared_ptr<struct PortStatusCallbacks_2_2>>
+      observers_;
+
+  // invoking the registered session_changed_cb_
+  void ReportSessionStatus();
+
  public:
   BluetoothAudioSession_2_2(
       const ::android::hardware::bluetooth::audio::V2_1::SessionType&
@@ -82,6 +123,29 @@
   bool SuspendStream();
   void StopStream();
 
+  // The control function helps the bluetooth_audio module to register
+  // PortStatusCallbacks_2_2
+  // @return: cookie - the assigned number to this bluetooth_audio output
+  uint16_t RegisterStatusCback(const PortStatusCallbacks_2_2& cbacks);
+
+  // The control function helps the bluetooth_audio module to unregister
+  // PortStatusCallbacks_2_2
+  // @param: cookie - indicates which bluetooth_audio output is
+  void UnregisterStatusCback(uint16_t cookie);
+
+  // The report function is used to report that the Bluetooth stack has notified
+  // the result of startStream or suspendStream, and will invoke
+  // control_result_cb_ to notify registered bluetooth_audio outputs
+  void ReportControlStatus(bool start_resp, const BluetoothAudioStatus& status);
+
+  // The report function is used to report that the Bluetooth stack has notified
+  // the audio configuration changed, and will invoke
+  // audio_configuration_changed_cb_ to notify registered bluetooth_audio
+  // outputs
+  void ReportAudioConfigChanged(
+      const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration&
+          audio_config);
+
   // The control function is for the bluetooth_audio module to get the current
   // AudioConfiguration
   const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.cpp b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.cpp
index 34cfd7e..4c99b0f 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.cpp
+++ b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.cpp
@@ -30,16 +30,20 @@
 using ::android::hardware::bluetooth::audio::V2_1::Lc3Parameters;
 using ::android::hardware::bluetooth::audio::V2_1::SampleRate;
 using ::android::hardware::bluetooth::audio::V2_2::AudioLocation;
-using ::android::hardware::bluetooth::audio::V2_2::LeAudioCodecCapabilitiesPair;
-using ::android::hardware::bluetooth::audio::V2_2::LeAudioCodecCapability;
-using ::android::hardware::bluetooth::audio::V2_2::LeAudioMode;
+using ::android::hardware::bluetooth::audio::V2_2::BroadcastCapability;
+using ::android::hardware::bluetooth::audio::V2_2::
+    LeAudioCodecCapabilitiesSetting;
+using ::android::hardware::bluetooth::audio::V2_2::UnicastCapability;
 using SessionType_2_1 =
     ::android::hardware::bluetooth::audio::V2_1::SessionType;
 
 // Stores the list of offload supported capability
-std::vector<LeAudioCodecCapabilitiesPair> kDefaultOffloadLeAudioCapabilities;
+std::vector<LeAudioCodecCapabilitiesSetting> kDefaultOffloadLeAudioCapabilities;
 
-static const LeAudioCodecCapability kInvalidLc3Capability = {
+static const UnicastCapability kInvalidUnicastCapability = {
+    .codecType = CodecType::UNKNOWN};
+
+static const BroadcastCapability kInvalidBroadcastCapability = {
     .codecType = CodecType::UNKNOWN};
 
 // Default Supported Codecs
@@ -94,53 +98,53 @@
   return true;
 }
 
-LeAudioCodecCapability composeLc3Capability(AudioLocation audioLocation,
-                                            uint8_t deviceCnt,
-                                            uint8_t channelCount,
-                                            Lc3Parameters capability) {
-  return LeAudioCodecCapability{.codecType = CodecType::LC3,
-                                .supportedChannel = audioLocation,
-                                .deviceCount = deviceCnt,
-                                .channelCountPerDevice = channelCount,
-                                .capabilities = capability};
+UnicastCapability composeUnicastLc3Capability(AudioLocation audioLocation,
+                                              uint8_t deviceCnt,
+                                              uint8_t channelCount,
+                                              Lc3Parameters capability) {
+  return UnicastCapability{.codecType = CodecType::LC3,
+                           .supportedChannel = audioLocation,
+                           .deviceCount = deviceCnt,
+                           .channelCountPerDevice = channelCount,
+                           .capabilities = capability};
 }
 
-std::vector<LeAudioCodecCapabilitiesPair> GetLeAudioOffloadCodecCapabilities(
+std::vector<LeAudioCodecCapabilitiesSetting> GetLeAudioOffloadCodecCapabilities(
     const SessionType_2_1& session_type) {
   if (session_type !=
           SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
       session_type !=
           SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
-    return std::vector<LeAudioCodecCapabilitiesPair>(0);
+    return std::vector<LeAudioCodecCapabilitiesSetting>(0);
   }
 
   if (kDefaultOffloadLeAudioCapabilities.empty()) {
     for (auto [audioLocation, deviceCnt, channelCount] :
          supportedDeviceSetting) {
       for (auto capability : supportedLc3CapabilityList) {
-        LeAudioCodecCapability lc3Capability = composeLc3Capability(
+        UnicastCapability lc3Capability = composeUnicastLc3Capability(
             audioLocation, deviceCnt, channelCount, capability);
-        LeAudioCodecCapability lc3MonoCapability =
-            composeLc3Capability(monoAudio, 1, 1, capability);
+        UnicastCapability lc3MonoDecodeCapability =
+            composeUnicastLc3Capability(monoAudio, 1, 1, capability);
 
         // Adds the capability for encode only
         kDefaultOffloadLeAudioCapabilities.push_back(
-            {.mode = LeAudioMode::UNICAST,
-             .encodeCapability = lc3Capability,
-             .decodeCapability = kInvalidLc3Capability});
+            {.unicastEncodeCapability = lc3Capability,
+             .unicastDecodeCapability = kInvalidUnicastCapability,
+             .broadcastCapability = kInvalidBroadcastCapability});
 
         // Adds the capability for decode only
         kDefaultOffloadLeAudioCapabilities.push_back(
-            {.mode = LeAudioMode::UNICAST,
-             .encodeCapability = kInvalidLc3Capability,
-             .decodeCapability = lc3Capability});
+            {.unicastEncodeCapability = kInvalidUnicastCapability,
+             .unicastDecodeCapability = lc3Capability,
+             .broadcastCapability = kInvalidBroadcastCapability});
 
         // Adds the capability for the case that encode and decode exist at the
         // same time
         kDefaultOffloadLeAudioCapabilities.push_back(
-            {.mode = LeAudioMode::UNICAST,
-             .encodeCapability = lc3Capability,
-             .decodeCapability = lc3MonoCapability});
+            {.unicastEncodeCapability = lc3Capability,
+             .unicastDecodeCapability = lc3MonoDecodeCapability,
+             .broadcastCapability = kInvalidBroadcastCapability});
       }
     }
   }
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.h b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.h
index 89da6a3..34bba5f 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.h
+++ b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.h
@@ -31,7 +31,7 @@
     const ::android::hardware::bluetooth::audio::V2_2::LeAudioConfiguration&
         le_audio_codec_config);
 
-std::vector<hardware::bluetooth::audio::V2_2::LeAudioCodecCapabilitiesPair>
+std::vector<hardware::bluetooth::audio::V2_2::LeAudioCodecCapabilitiesSetting>
 GetLeAudioOffloadCodecCapabilities(
     const ::android::hardware::bluetooth::audio::V2_1::SessionType&
         session_type);
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index eeff7bb..6879a95 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -139,6 +139,13 @@
             <instance>default</instance>
         </interface>
     </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.bluetooth.audio</name>
+        <interface>
+            <name>IBluetoothAudioProviderFactory</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
     <hal format="hidl" optional="true">
         <name>android.hardware.boot</name>
         <version>1.2</version>
diff --git a/compatibility_matrices/exclude/fcm_exclude.cpp b/compatibility_matrices/exclude/fcm_exclude.cpp
index d8c9170..f34009d 100644
--- a/compatibility_matrices/exclude/fcm_exclude.cpp
+++ b/compatibility_matrices/exclude/fcm_exclude.cpp
@@ -51,6 +51,7 @@
             "android.hardware.media.bufferpool@2.0",
             "android.hardware.radio.config@1.2",
             // AIDL
+            "android.hardware.audio.common",
             "android.hardware.biometrics.common",
             "android.hardware.common",
             "android.hardware.common.fmq",
diff --git a/dumpstate/aidl/Android.bp b/dumpstate/aidl/Android.bp
index e18eade..22d836b 100644
--- a/dumpstate/aidl/Android.bp
+++ b/dumpstate/aidl/Android.bp
@@ -34,7 +34,6 @@
             enabled: false,
         },
         ndk: {
-            separate_platform_variant: false,
             vndk: {
                 enabled: true,
             },
diff --git a/dumpstate/aidl/android/hardware/dumpstate/IDumpstateDevice.aidl b/dumpstate/aidl/android/hardware/dumpstate/IDumpstateDevice.aidl
index 3b42546..b994d04 100644
--- a/dumpstate/aidl/android/hardware/dumpstate/IDumpstateDevice.aidl
+++ b/dumpstate/aidl/android/hardware/dumpstate/IDumpstateDevice.aidl
@@ -103,8 +103,9 @@
      * @param timeoutMillis An approximate "budget" for how much time this call has been allotted.
      *     If execution runs longer than this, the IDumpstateDevice service may be killed and only
      *     partial information will be included in the report.
-     * @return If error, return service specific error with code
-     *           ERROR_UNSUPPORTED_MODE or ERROR_DEVICE_LOGGING_NOT_ENABLED
+     * @throws ServiceSpecificException with one of the following values:
+     *         |ERROR_UNSUPPORTED_MODE|,
+     *         |ERROR_DEVICE_LOGGING_NOT_ENABLED|
      */
     void dumpstateBoard(in ParcelFileDescriptor[] fd, in DumpstateMode mode, in long timeoutMillis);
 
diff --git a/health/2.1/vts/OWNERS b/health/2.1/vts/OWNERS
index 20450ba..a6803cd 100644
--- a/health/2.1/vts/OWNERS
+++ b/health/2.1/vts/OWNERS
@@ -1,3 +1,2 @@
 elsk@google.com
-hridya@google.com
 sspatil@google.com
diff --git a/health/aidl/Android.bp b/health/aidl/Android.bp
index 6e2f1d4..22bb4fa 100644
--- a/health/aidl/Android.bp
+++ b/health/aidl/Android.bp
@@ -37,7 +37,6 @@
             sdk_version: "module_current",
         },
         ndk: {
-            separate_platform_variant: false,
             vndk: {
                 enabled: true,
             },
diff --git a/health/aidl/default/Android.bp b/health/aidl/default/Android.bp
index 8aa7638..8eab997 100644
--- a/health/aidl/default/Android.bp
+++ b/health/aidl/default/Android.bp
@@ -120,6 +120,15 @@
     },
 }
 
+// Users of libhealth_aidl_impl should use this defaults.
+cc_defaults {
+    name: "libhealth_aidl_impl_user",
+    defaults: [
+        "libhealth_aidl_common_defaults",
+        "libhealth_aidl_charger_defaults",
+    ],
+}
+
 // AIDL version of android.hardware.health@2.1-service.
 // Default binder service of the health HAL.
 cc_defaults {
@@ -127,8 +136,7 @@
     relative_install_path: "hw",
     vintf_fragments: ["android.hardware.health-service.example.xml"],
     defaults: [
-        "libhealth_aidl_common_defaults",
-        "libhealth_aidl_charger_defaults",
+        "libhealth_aidl_impl_user",
     ],
     static_libs: [
         "libhealth_aidl_impl",
diff --git a/ir/aidl/Android.bp b/ir/aidl/Android.bp
index 8741157..a623491 100644
--- a/ir/aidl/Android.bp
+++ b/ir/aidl/Android.bp
@@ -12,6 +12,15 @@
 // 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"],
+}
+
 aidl_interface {
     name: "android.hardware.ir",
     vendor_available: true,
@@ -25,7 +34,6 @@
             sdk_version: "module_current",
         },
         ndk: {
-            separate_platform_variant: false,
             vndk: {
                 // TODO(b/206116595) enable this
                 enabled: false,
diff --git a/ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/IConsumerIr.aidl b/ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/IConsumerIr.aidl
index 056a8b1..07bf4b4 100644
--- a/ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/IConsumerIr.aidl
+++ b/ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/IConsumerIr.aidl
@@ -35,5 +35,5 @@
 @VintfStability
 interface IConsumerIr {
   android.hardware.ir.ConsumerIrFreqRange[] getCarrierFreqs();
-  void transmit(in int carrierFreq, in int[] pattern);
+  void transmit(in int carrierFreqHz, in int[] pattern);
 }
diff --git a/ir/aidl/android/hardware/ir/IConsumerIr.aidl b/ir/aidl/android/hardware/ir/IConsumerIr.aidl
index d14fa56..f6f9742 100644
--- a/ir/aidl/android/hardware/ir/IConsumerIr.aidl
+++ b/ir/aidl/android/hardware/ir/IConsumerIr.aidl
@@ -23,23 +23,21 @@
     /**
      * Enumerates which frequencies the IR transmitter supports.
      *
-     * Status OK (EX_NONE) on success.
-     *
      * @return - an array of all supported frequency ranges.
      */
     ConsumerIrFreqRange[] getCarrierFreqs();
 
     /**
      * Sends an IR pattern at a given frequency in HZ.
-     *
-     * The pattern is alternating series of carrier on and off periods measured in
-     * microseconds. The carrier should be turned off at the end of a transmit
-     * even if there are and odd number of entries in the pattern array.
-     *
      * This call must return when the transmit is complete or encounters an error.
      *
-     * Status OK (EX_NONE) on success.
-     * EX_UNSUPPORTED_OPERATION when the frequency is not supported.
+     * @param carrierFreq - Frequency of the transmission in HZ.
+     *
+     * @param pattern - Alternating series of on and off periods measured in
+     * microseconds. The carrier should be turned off at the end of a transmit
+     * even if there are an odd number of entries in the pattern array.
+     *
+     * @throws EX_UNSUPPORTED_OPERATION when the frequency is not supported.
      */
-    void transmit(in int carrierFreq, in int[] pattern);
+    void transmit(in int carrierFreqHz, in int[] pattern);
 }
diff --git a/ir/aidl/default/Android.bp b/ir/aidl/default/Android.bp
index 6519664..a4fb439 100644
--- a/ir/aidl/default/Android.bp
+++ b/ir/aidl/default/Android.bp
@@ -13,6 +13,15 @@
 // limitations under the License.
 
 // Example binder service of the ir HAL.
+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_binary {
     name: "android.hardware.ir-service.example",
     relative_install_path: "hw",
diff --git a/ir/aidl/default/main.cpp b/ir/aidl/default/main.cpp
index 764aeaf..7c4a816 100644
--- a/ir/aidl/default/main.cpp
+++ b/ir/aidl/default/main.cpp
@@ -30,7 +30,7 @@
 
 class ConsumerIr : public BnConsumerIr {
     ::ndk::ScopedAStatus getCarrierFreqs(std::vector<ConsumerIrFreqRange>* _aidl_return) override;
-    ::ndk::ScopedAStatus transmit(int32_t in_carrierFreq,
+    ::ndk::ScopedAStatus transmit(int32_t in_carrierFreqHz,
                                   const std::vector<int32_t>& in_pattern) override;
 };
 
@@ -46,9 +46,9 @@
     return false;
 }
 
-::ndk::ScopedAStatus ConsumerIr::transmit(int32_t in_carrierFreq,
+::ndk::ScopedAStatus ConsumerIr::transmit(int32_t in_carrierFreqHz,
                                           const std::vector<int32_t>& in_pattern) {
-    if (isSupportedFreq(in_carrierFreq)) {
+    if (isSupportedFreq(in_carrierFreqHz)) {
         // trasmit the pattern, each integer is number of microseconds in an
         // alternating on/off state.
         usleep(std::accumulate(in_pattern.begin(), in_pattern.end(), 0));
diff --git a/neuralnetworks/1.3/vts/functional/MemoryDomainTests.cpp b/neuralnetworks/1.3/vts/functional/MemoryDomainTests.cpp
index e2fa6e4..af3641a 100644
--- a/neuralnetworks/1.3/vts/functional/MemoryDomainTests.cpp
+++ b/neuralnetworks/1.3/vts/functional/MemoryDomainTests.cpp
@@ -1158,12 +1158,15 @@
     auto [buffer, token] = allocateBuffer(preparedModel, {0}, {0}, kTestOperand.dimensions);
     if (buffer == nullptr) return;
 
-    Request::MemoryPool sharedMemory = createSharedMemoryPool(kTestOperandDataSize);
-    Request::MemoryPool deviceMemory = createDeviceMemoryPool(token);
+    // Use an incompatible dimension and make sure the length matches with the bad dimension.
     auto badDimensions = kTestOperand.dimensions;
     badDimensions[0] = 2;
+    const uint32_t badTestOperandDataSize = kTestOperandDataSize * 2;
+
+    Request::MemoryPool sharedMemory = createSharedMemoryPool(badTestOperandDataSize);
+    Request::MemoryPool deviceMemory = createDeviceMemoryPool(token);
     RequestArgument sharedMemoryArg = {
-            .location = {.poolIndex = 0, .offset = 0, .length = kTestOperandDataSize},
+            .location = {.poolIndex = 0, .offset = 0, .length = badTestOperandDataSize},
             .dimensions = badDimensions};
     RequestArgument deviceMemoryArg = {.location = {.poolIndex = 1}};
     RequestArgument deviceMemoryArgWithBadDimensions = {.location = {.poolIndex = 1},
diff --git a/neuralnetworks/OWNERS b/neuralnetworks/OWNERS
index def3ea9..04c5d72 100644
--- a/neuralnetworks/OWNERS
+++ b/neuralnetworks/OWNERS
@@ -1,10 +1,2 @@
 # Bug component: 195575
-# Neuralnetworks team
-butlermichael@google.com
-dgross@google.com
-galarragas@google.com
-ianhua@google.com
-jeanluc@google.com
-miaowang@google.com
-pszczepaniak@google.com
-xusongw@google.com
+include platform/packages/modules/NeuralNetworks:/NNAPI_OWNERS  # Neuralnetworks team
diff --git a/neuralnetworks/aidl/Android.bp b/neuralnetworks/aidl/Android.bp
index 065105a..aa4c4b6 100644
--- a/neuralnetworks/aidl/Android.bp
+++ b/neuralnetworks/aidl/Android.bp
@@ -38,5 +38,6 @@
     versions: [
         "1",
         "2",
+        "3",
     ],
 }
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/.hash b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/.hash
new file mode 100644
index 0000000..3b9f018
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/.hash
@@ -0,0 +1 @@
+8c2c4ca2327e6f779dad6119c03d832ea4e1def1
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/BufferDesc.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/BufferDesc.aidl
new file mode 100644
index 0000000..05cec76
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/BufferDesc.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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.neuralnetworks;
+@VintfStability
+parcelable BufferDesc {
+  int[] dimensions;
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/BufferRole.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/BufferRole.aidl
new file mode 100644
index 0000000..10a6b75
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/BufferRole.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.hardware.neuralnetworks;
+@VintfStability
+parcelable BufferRole {
+  int modelIndex;
+  int ioIndex;
+  float probability;
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Capabilities.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Capabilities.aidl
new file mode 100644
index 0000000..30877c0
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Capabilities.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.hardware.neuralnetworks;
+@VintfStability
+parcelable Capabilities {
+  android.hardware.neuralnetworks.PerformanceInfo relaxedFloat32toFloat16PerformanceScalar;
+  android.hardware.neuralnetworks.PerformanceInfo relaxedFloat32toFloat16PerformanceTensor;
+  android.hardware.neuralnetworks.OperandPerformance[] operandPerformance;
+  android.hardware.neuralnetworks.PerformanceInfo ifPerformance;
+  android.hardware.neuralnetworks.PerformanceInfo whilePerformance;
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DataLocation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DataLocation.aidl
new file mode 100644
index 0000000..db49a38
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DataLocation.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.hardware.neuralnetworks;
+@VintfStability
+parcelable DataLocation {
+  int poolIndex;
+  long offset;
+  long length;
+  long padding;
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DeviceBuffer.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DeviceBuffer.aidl
new file mode 100644
index 0000000..7cdd6db
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DeviceBuffer.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.hardware.neuralnetworks;
+@VintfStability
+parcelable DeviceBuffer {
+  android.hardware.neuralnetworks.IBuffer buffer;
+  int token;
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DeviceType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DeviceType.aidl
new file mode 100644
index 0000000..82fe8ae
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/DeviceType.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.hardware.neuralnetworks;
+@Backing(type="int") @VintfStability
+enum DeviceType {
+  OTHER = 1,
+  CPU = 2,
+  GPU = 3,
+  ACCELERATOR = 4,
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ErrorStatus.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ErrorStatus.aidl
new file mode 100644
index 0000000..57d5d6e
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ErrorStatus.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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.hardware.neuralnetworks;
+@Backing(type="int") @VintfStability
+enum ErrorStatus {
+  NONE = 0,
+  DEVICE_UNAVAILABLE = 1,
+  GENERAL_FAILURE = 2,
+  OUTPUT_INSUFFICIENT_SIZE = 3,
+  INVALID_ARGUMENT = 4,
+  MISSED_DEADLINE_TRANSIENT = 5,
+  MISSED_DEADLINE_PERSISTENT = 6,
+  RESOURCE_EXHAUSTED_TRANSIENT = 7,
+  RESOURCE_EXHAUSTED_PERSISTENT = 8,
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionPreference.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionPreference.aidl
new file mode 100644
index 0000000..4352d8f
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionPreference.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.hardware.neuralnetworks;
+@Backing(type="int") @VintfStability
+enum ExecutionPreference {
+  LOW_POWER = 0,
+  FAST_SINGLE_ANSWER = 1,
+  SUSTAINED_SPEED = 2,
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionResult.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionResult.aidl
new file mode 100644
index 0000000..44e9922
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExecutionResult.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 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.neuralnetworks;
+@VintfStability
+parcelable ExecutionResult {
+  boolean outputSufficientSize;
+  android.hardware.neuralnetworks.OutputShape[] outputShapes;
+  android.hardware.neuralnetworks.Timing timing;
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Extension.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Extension.aidl
new file mode 100644
index 0000000..c47028d
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Extension.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.hardware.neuralnetworks;
+@VintfStability
+parcelable Extension {
+  String name;
+  android.hardware.neuralnetworks.ExtensionOperandTypeInformation[] operandTypes;
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionNameAndPrefix.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionNameAndPrefix.aidl
new file mode 100644
index 0000000..6c287fd
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionNameAndPrefix.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.hardware.neuralnetworks;
+@VintfStability
+parcelable ExtensionNameAndPrefix {
+  String name;
+  char prefix;
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionOperandTypeInformation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionOperandTypeInformation.aidl
new file mode 100644
index 0000000..a3680aa
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/ExtensionOperandTypeInformation.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.hardware.neuralnetworks;
+@VintfStability
+parcelable ExtensionOperandTypeInformation {
+  char type;
+  boolean isTensor;
+  int byteSize;
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FencedExecutionResult.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FencedExecutionResult.aidl
new file mode 100644
index 0000000..7952b34
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FencedExecutionResult.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 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.neuralnetworks;
+@VintfStability
+parcelable FencedExecutionResult {
+  android.hardware.neuralnetworks.IFencedExecutionCallback callback;
+  @nullable ParcelFileDescriptor syncFence;
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FusedActivationFunc.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FusedActivationFunc.aidl
new file mode 100644
index 0000000..7e61bbb
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/FusedActivationFunc.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.hardware.neuralnetworks;
+@Backing(type="int") @VintfStability
+enum FusedActivationFunc {
+  NONE = 0,
+  RELU = 1,
+  RELU1 = 2,
+  RELU6 = 3,
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBuffer.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBuffer.aidl
new file mode 100644
index 0000000..f10e7e2
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBuffer.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.hardware.neuralnetworks;
+@VintfStability
+interface IBuffer {
+  void copyFrom(in android.hardware.neuralnetworks.Memory src, in int[] dimensions);
+  void copyTo(in android.hardware.neuralnetworks.Memory dst);
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBurst.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBurst.aidl
new file mode 100644
index 0000000..eb3d0b0
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IBurst.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 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.neuralnetworks;
+@VintfStability
+interface IBurst {
+  android.hardware.neuralnetworks.ExecutionResult executeSynchronously(in android.hardware.neuralnetworks.Request request, in long[] memoryIdentifierTokens, in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs);
+  void releaseMemoryResource(in long memoryIdentifierToken);
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IDevice.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IDevice.aidl
new file mode 100644
index 0000000..c9c67f2
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IDevice.aidl
@@ -0,0 +1,52 @@
+/*
+ * 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.hardware.neuralnetworks;
+@VintfStability
+interface IDevice {
+  android.hardware.neuralnetworks.DeviceBuffer allocate(in android.hardware.neuralnetworks.BufferDesc desc, in android.hardware.neuralnetworks.IPreparedModelParcel[] preparedModels, in android.hardware.neuralnetworks.BufferRole[] inputRoles, in android.hardware.neuralnetworks.BufferRole[] outputRoles);
+  android.hardware.neuralnetworks.Capabilities getCapabilities();
+  android.hardware.neuralnetworks.NumberOfCacheFiles getNumberOfCacheFilesNeeded();
+  android.hardware.neuralnetworks.Extension[] getSupportedExtensions();
+  boolean[] getSupportedOperations(in android.hardware.neuralnetworks.Model model);
+  android.hardware.neuralnetworks.DeviceType getType();
+  String getVersionString();
+  void prepareModel(in android.hardware.neuralnetworks.Model model, in android.hardware.neuralnetworks.ExecutionPreference preference, in android.hardware.neuralnetworks.Priority priority, in long deadlineNs, in ParcelFileDescriptor[] modelCache, in ParcelFileDescriptor[] dataCache, in byte[] token, in android.hardware.neuralnetworks.IPreparedModelCallback callback);
+  void prepareModelFromCache(in long deadlineNs, in ParcelFileDescriptor[] modelCache, in ParcelFileDescriptor[] dataCache, in byte[] token, in android.hardware.neuralnetworks.IPreparedModelCallback callback);
+  const int BYTE_SIZE_OF_CACHE_TOKEN = 32;
+  const int MAX_NUMBER_OF_CACHE_FILES = 32;
+  const int EXTENSION_TYPE_HIGH_BITS_PREFIX = 15;
+  const int EXTENSION_TYPE_LOW_BITS_TYPE = 16;
+  const int OPERAND_TYPE_BASE_MAX = 65535;
+  const int OPERATION_TYPE_BASE_MAX = 65535;
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IFencedExecutionCallback.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IFencedExecutionCallback.aidl
new file mode 100644
index 0000000..0bfb80a
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IFencedExecutionCallback.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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.neuralnetworks;
+@VintfStability
+interface IFencedExecutionCallback {
+  android.hardware.neuralnetworks.ErrorStatus getExecutionInfo(out android.hardware.neuralnetworks.Timing timingLaunched, out android.hardware.neuralnetworks.Timing timingFenced);
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModel.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModel.aidl
new file mode 100644
index 0000000..fccb5dc
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModel.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.hardware.neuralnetworks;
+@VintfStability
+interface IPreparedModel {
+  android.hardware.neuralnetworks.ExecutionResult executeSynchronously(in android.hardware.neuralnetworks.Request request, in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs);
+  android.hardware.neuralnetworks.FencedExecutionResult executeFenced(in android.hardware.neuralnetworks.Request request, in ParcelFileDescriptor[] waitFor, in boolean measureTiming, in long deadlineNs, in long loopTimeoutDurationNs, in long durationNs);
+  android.hardware.neuralnetworks.IBurst configureExecutionBurst();
+  const long DEFAULT_LOOP_TIMEOUT_DURATION_NS = 2000000000;
+  const long MAXIMUM_LOOP_TIMEOUT_DURATION_NS = 15000000000;
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelCallback.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelCallback.aidl
new file mode 100644
index 0000000..e0c763b
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelCallback.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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.neuralnetworks;
+@VintfStability
+interface IPreparedModelCallback {
+  void notify(in android.hardware.neuralnetworks.ErrorStatus status, in android.hardware.neuralnetworks.IPreparedModel preparedModel);
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelParcel.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelParcel.aidl
new file mode 100644
index 0000000..dbedf12
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/IPreparedModelParcel.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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.neuralnetworks;
+@VintfStability
+parcelable IPreparedModelParcel {
+  android.hardware.neuralnetworks.IPreparedModel preparedModel;
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Memory.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Memory.aidl
new file mode 100644
index 0000000..37fa102
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Memory.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.hardware.neuralnetworks;
+@VintfStability
+union Memory {
+  android.hardware.common.Ashmem ashmem;
+  android.hardware.common.MappableFile mappableFile;
+  android.hardware.graphics.common.HardwareBuffer hardwareBuffer;
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Model.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Model.aidl
new file mode 100644
index 0000000..30d8dda
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Model.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.hardware.neuralnetworks;
+@VintfStability
+parcelable Model {
+  android.hardware.neuralnetworks.Subgraph main;
+  android.hardware.neuralnetworks.Subgraph[] referenced;
+  byte[] operandValues;
+  android.hardware.neuralnetworks.Memory[] pools;
+  boolean relaxComputationFloat32toFloat16;
+  android.hardware.neuralnetworks.ExtensionNameAndPrefix[] extensionNameToPrefix;
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/NumberOfCacheFiles.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/NumberOfCacheFiles.aidl
new file mode 100644
index 0000000..9314760
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/NumberOfCacheFiles.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.hardware.neuralnetworks;
+@VintfStability
+parcelable NumberOfCacheFiles {
+  int numModelCache;
+  int numDataCache;
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operand.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operand.aidl
new file mode 100644
index 0000000..1d9bdd8
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operand.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.hardware.neuralnetworks;
+@VintfStability
+parcelable Operand {
+  android.hardware.neuralnetworks.OperandType type = android.hardware.neuralnetworks.OperandType.FLOAT32;
+  int[] dimensions;
+  float scale;
+  int zeroPoint;
+  android.hardware.neuralnetworks.OperandLifeTime lifetime = android.hardware.neuralnetworks.OperandLifeTime.TEMPORARY_VARIABLE;
+  android.hardware.neuralnetworks.DataLocation location;
+  @nullable android.hardware.neuralnetworks.OperandExtraParams extraParams;
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandExtraParams.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandExtraParams.aidl
new file mode 100644
index 0000000..14792cf
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandExtraParams.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.hardware.neuralnetworks;
+@VintfStability
+union OperandExtraParams {
+  android.hardware.neuralnetworks.SymmPerChannelQuantParams channelQuant;
+  byte[] extension;
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandLifeTime.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandLifeTime.aidl
new file mode 100644
index 0000000..40adfb1
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandLifeTime.aidl
@@ -0,0 +1,44 @@
+/*
+ * 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.hardware.neuralnetworks;
+@Backing(type="int") @VintfStability
+enum OperandLifeTime {
+  TEMPORARY_VARIABLE = 0,
+  SUBGRAPH_INPUT = 1,
+  SUBGRAPH_OUTPUT = 2,
+  CONSTANT_COPY = 3,
+  CONSTANT_POOL = 4,
+  NO_VALUE = 5,
+  SUBGRAPH = 6,
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandPerformance.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandPerformance.aidl
new file mode 100644
index 0000000..ebb361b
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandPerformance.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.hardware.neuralnetworks;
+@VintfStability
+parcelable OperandPerformance {
+  android.hardware.neuralnetworks.OperandType type = android.hardware.neuralnetworks.OperandType.FLOAT32;
+  android.hardware.neuralnetworks.PerformanceInfo info;
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandType.aidl
new file mode 100644
index 0000000..9f2c759
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperandType.aidl
@@ -0,0 +1,53 @@
+/*
+ * 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.hardware.neuralnetworks;
+@Backing(type="int") @VintfStability
+enum OperandType {
+  FLOAT32 = 0,
+  INT32 = 1,
+  UINT32 = 2,
+  TENSOR_FLOAT32 = 3,
+  TENSOR_INT32 = 4,
+  TENSOR_QUANT8_ASYMM = 5,
+  BOOL = 6,
+  TENSOR_QUANT16_SYMM = 7,
+  TENSOR_FLOAT16 = 8,
+  TENSOR_BOOL8 = 9,
+  FLOAT16 = 10,
+  TENSOR_QUANT8_SYMM_PER_CHANNEL = 11,
+  TENSOR_QUANT16_ASYMM = 12,
+  TENSOR_QUANT8_SYMM = 13,
+  TENSOR_QUANT8_ASYMM_SIGNED = 14,
+  SUBGRAPH = 15,
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operation.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operation.aidl
new file mode 100644
index 0000000..a4a3fbe
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Operation.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.hardware.neuralnetworks;
+@VintfStability
+parcelable Operation {
+  android.hardware.neuralnetworks.OperationType type = android.hardware.neuralnetworks.OperationType.ADD;
+  int[] inputs;
+  int[] outputs;
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperationType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperationType.aidl
new file mode 100644
index 0000000..34506c8
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OperationType.aidl
@@ -0,0 +1,143 @@
+/*
+ * 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.hardware.neuralnetworks;
+@Backing(type="int") @VintfStability
+enum OperationType {
+  ADD = 0,
+  AVERAGE_POOL_2D = 1,
+  CONCATENATION = 2,
+  CONV_2D = 3,
+  DEPTHWISE_CONV_2D = 4,
+  DEPTH_TO_SPACE = 5,
+  DEQUANTIZE = 6,
+  EMBEDDING_LOOKUP = 7,
+  FLOOR = 8,
+  FULLY_CONNECTED = 9,
+  HASHTABLE_LOOKUP = 10,
+  L2_NORMALIZATION = 11,
+  L2_POOL_2D = 12,
+  LOCAL_RESPONSE_NORMALIZATION = 13,
+  LOGISTIC = 14,
+  LSH_PROJECTION = 15,
+  LSTM = 16,
+  MAX_POOL_2D = 17,
+  MUL = 18,
+  RELU = 19,
+  RELU1 = 20,
+  RELU6 = 21,
+  RESHAPE = 22,
+  RESIZE_BILINEAR = 23,
+  RNN = 24,
+  SOFTMAX = 25,
+  SPACE_TO_DEPTH = 26,
+  SVDF = 27,
+  TANH = 28,
+  BATCH_TO_SPACE_ND = 29,
+  DIV = 30,
+  MEAN = 31,
+  PAD = 32,
+  SPACE_TO_BATCH_ND = 33,
+  SQUEEZE = 34,
+  STRIDED_SLICE = 35,
+  SUB = 36,
+  TRANSPOSE = 37,
+  ABS = 38,
+  ARGMAX = 39,
+  ARGMIN = 40,
+  AXIS_ALIGNED_BBOX_TRANSFORM = 41,
+  BIDIRECTIONAL_SEQUENCE_LSTM = 42,
+  BIDIRECTIONAL_SEQUENCE_RNN = 43,
+  BOX_WITH_NMS_LIMIT = 44,
+  CAST = 45,
+  CHANNEL_SHUFFLE = 46,
+  DETECTION_POSTPROCESSING = 47,
+  EQUAL = 48,
+  EXP = 49,
+  EXPAND_DIMS = 50,
+  GATHER = 51,
+  GENERATE_PROPOSALS = 52,
+  GREATER = 53,
+  GREATER_EQUAL = 54,
+  GROUPED_CONV_2D = 55,
+  HEATMAP_MAX_KEYPOINT = 56,
+  INSTANCE_NORMALIZATION = 57,
+  LESS = 58,
+  LESS_EQUAL = 59,
+  LOG = 60,
+  LOGICAL_AND = 61,
+  LOGICAL_NOT = 62,
+  LOGICAL_OR = 63,
+  LOG_SOFTMAX = 64,
+  MAXIMUM = 65,
+  MINIMUM = 66,
+  NEG = 67,
+  NOT_EQUAL = 68,
+  PAD_V2 = 69,
+  POW = 70,
+  PRELU = 71,
+  QUANTIZE = 72,
+  QUANTIZED_16BIT_LSTM = 73,
+  RANDOM_MULTINOMIAL = 74,
+  REDUCE_ALL = 75,
+  REDUCE_ANY = 76,
+  REDUCE_MAX = 77,
+  REDUCE_MIN = 78,
+  REDUCE_PROD = 79,
+  REDUCE_SUM = 80,
+  ROI_ALIGN = 81,
+  ROI_POOLING = 82,
+  RSQRT = 83,
+  SELECT = 84,
+  SIN = 85,
+  SLICE = 86,
+  SPLIT = 87,
+  SQRT = 88,
+  TILE = 89,
+  TOPK_V2 = 90,
+  TRANSPOSE_CONV_2D = 91,
+  UNIDIRECTIONAL_SEQUENCE_LSTM = 92,
+  UNIDIRECTIONAL_SEQUENCE_RNN = 93,
+  RESIZE_NEAREST_NEIGHBOR = 94,
+  QUANTIZED_LSTM = 95,
+  IF = 96,
+  WHILE = 97,
+  ELU = 98,
+  HARD_SWISH = 99,
+  FILL = 100,
+  RANK = 101,
+  BATCH_MATMUL = 102,
+  PACK = 103,
+  MIRROR_PAD = 104,
+  REVERSE = 105,
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OutputShape.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OutputShape.aidl
new file mode 100644
index 0000000..f733505
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/OutputShape.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.hardware.neuralnetworks;
+@VintfStability
+parcelable OutputShape {
+  int[] dimensions;
+  boolean isSufficient;
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/PerformanceInfo.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/PerformanceInfo.aidl
new file mode 100644
index 0000000..04910f5
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/PerformanceInfo.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.hardware.neuralnetworks;
+@VintfStability
+parcelable PerformanceInfo {
+  float execTime;
+  float powerUsage;
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Priority.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Priority.aidl
new file mode 100644
index 0000000..8f35709
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Priority.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.hardware.neuralnetworks;
+@Backing(type="int") @VintfStability
+enum Priority {
+  LOW = 0,
+  MEDIUM = 1,
+  HIGH = 2,
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Request.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Request.aidl
new file mode 100644
index 0000000..39ec7a9
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Request.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.hardware.neuralnetworks;
+@VintfStability
+parcelable Request {
+  android.hardware.neuralnetworks.RequestArgument[] inputs;
+  android.hardware.neuralnetworks.RequestArgument[] outputs;
+  android.hardware.neuralnetworks.RequestMemoryPool[] pools;
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestArgument.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestArgument.aidl
new file mode 100644
index 0000000..e3541c0
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestArgument.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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.hardware.neuralnetworks;
+@VintfStability
+parcelable RequestArgument {
+  boolean hasNoValue;
+  android.hardware.neuralnetworks.DataLocation location;
+  int[] dimensions;
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestMemoryPool.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestMemoryPool.aidl
new file mode 100644
index 0000000..312f581
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/RequestMemoryPool.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.hardware.neuralnetworks;
+@VintfStability
+union RequestMemoryPool {
+  android.hardware.neuralnetworks.Memory pool;
+  int token;
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Subgraph.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Subgraph.aidl
new file mode 100644
index 0000000..b7d4451
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Subgraph.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.hardware.neuralnetworks;
+@VintfStability
+parcelable Subgraph {
+  android.hardware.neuralnetworks.Operand[] operands;
+  android.hardware.neuralnetworks.Operation[] operations;
+  int[] inputIndexes;
+  int[] outputIndexes;
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/SymmPerChannelQuantParams.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/SymmPerChannelQuantParams.aidl
new file mode 100644
index 0000000..02d68f9
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/SymmPerChannelQuantParams.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.hardware.neuralnetworks;
+@VintfStability
+parcelable SymmPerChannelQuantParams {
+  float[] scales;
+  int channelDim;
+}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Timing.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Timing.aidl
new file mode 100644
index 0000000..bcc83cf
--- /dev/null
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/3/android/hardware/neuralnetworks/Timing.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.hardware.neuralnetworks;
+@VintfStability
+parcelable Timing {
+  long timeOnDeviceNs;
+  long timeInDriverNs;
+}
diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl
index 0ad254d..5f7810b 100644
--- a/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl
+++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl
@@ -5331,6 +5331,18 @@
     /**
      * Pads a tensor with mirrored values.
      *
+     * This operator specifies one of two padding modes: REFLECT or SYMMETRIC.
+     * In the case of REFLECT mode, the mirroring excludes the border element
+     * on the padding side.
+     * In the case of SYMMETRIC mode, the mirroring includes the border element
+     * on the padding side.
+     *
+     * For example, if the input is the 1-D tensor `[1, 2, 3]` and the padding
+     * is `[0, 2]` (i.e., pad no elements before the first (and only) dimension,
+     * and two elements after the first (and only) dimension), then:
+     *     - REFLECT mode produces the output `[1, 2, 3, 2, 1]`
+     *     - SYMMETRIC mode produces the output `[1, 2, 3, 3, 2]`
+     *
      * Supported tensor {@link OperandType}:
      * * {@link OperandType::TENSOR_FLOAT16}
      * * {@link OperandType::TENSOR_FLOAT32}
@@ -5349,6 +5361,11 @@
      *      front of dimension i.
      *      padding[i, 1] specifies the number of elements to be padded after the
      *      end of dimension i.
+     *      Each padding value must be nonnegative.
+     *      In the case of REFLECT mode, each padding value must be less than the
+     *      corresponding dimension.
+     *      In the case of SYMMETRIC mode, each padding value must be less than or
+     *      equal to the corresponding dimension.
      * * 2: An {@link OperandType::INT32} scalar, specifying the mode.
      *      Options are 0:REFLECT and 1:SYMMETRIC.
      *
diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Conversions.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Conversions.h
index 78433a7..477b311 100644
--- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Conversions.h
+++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Conversions.h
@@ -112,11 +112,15 @@
 GeneralResult<Request> convert(const aidl_hal::Request& request);
 GeneralResult<Timing> convert(const aidl_hal::Timing& timing);
 GeneralResult<SharedHandle> convert(const ndk::ScopedFileDescriptor& handle);
+GeneralResult<BufferDesc> convert(const aidl_hal::BufferDesc& bufferDesc);
 
 GeneralResult<std::vector<Extension>> convert(const std::vector<aidl_hal::Extension>& extension);
 GeneralResult<std::vector<SharedMemory>> convert(const std::vector<aidl_hal::Memory>& memories);
 GeneralResult<std::vector<OutputShape>> convert(
         const std::vector<aidl_hal::OutputShape>& outputShapes);
+GeneralResult<std::vector<SharedHandle>> convert(
+        const std::vector<ndk::ScopedFileDescriptor>& handles);
+GeneralResult<std::vector<BufferRole>> convert(const std::vector<aidl_hal::BufferRole>& roles);
 
 GeneralResult<std::vector<uint32_t>> toUnsigned(const std::vector<int32_t>& vec);
 
@@ -129,6 +133,7 @@
 nn::GeneralResult<std::vector<uint8_t>> unvalidatedConvert(const nn::CacheToken& cacheToken);
 nn::GeneralResult<BufferDesc> unvalidatedConvert(const nn::BufferDesc& bufferDesc);
 nn::GeneralResult<BufferRole> unvalidatedConvert(const nn::BufferRole& bufferRole);
+nn::GeneralResult<DeviceType> unvalidatedConvert(const nn::DeviceType& deviceType);
 nn::GeneralResult<bool> unvalidatedConvert(const nn::MeasureTiming& measureTiming);
 nn::GeneralResult<Memory> unvalidatedConvert(const nn::SharedMemory& memory);
 nn::GeneralResult<OutputShape> unvalidatedConvert(const nn::OutputShape& outputShape);
@@ -154,14 +159,16 @@
 nn::GeneralResult<RequestArgument> unvalidatedConvert(const nn::Request::Argument& requestArgument);
 nn::GeneralResult<RequestMemoryPool> unvalidatedConvert(const nn::Request::MemoryPool& memoryPool);
 nn::GeneralResult<Timing> unvalidatedConvert(const nn::Timing& timing);
-nn::GeneralResult<int64_t> unvalidatedConvert(const nn::Duration& duration);
 nn::GeneralResult<int64_t> unvalidatedConvert(const nn::OptionalDuration& optionalDuration);
 nn::GeneralResult<int64_t> unvalidatedConvert(const nn::OptionalTimePoint& optionalTimePoint);
 nn::GeneralResult<ndk::ScopedFileDescriptor> unvalidatedConvert(const nn::SyncFence& syncFence);
 nn::GeneralResult<ndk::ScopedFileDescriptor> unvalidatedConvert(const nn::SharedHandle& handle);
+nn::GeneralResult<Capabilities> unvalidatedConvert(const nn::Capabilities& capabilities);
+nn::GeneralResult<Extension> unvalidatedConvert(const nn::Extension& extension);
 
 nn::GeneralResult<std::vector<uint8_t>> convert(const nn::CacheToken& cacheToken);
 nn::GeneralResult<BufferDesc> convert(const nn::BufferDesc& bufferDesc);
+nn::GeneralResult<DeviceType> convert(const nn::DeviceType& deviceType);
 nn::GeneralResult<bool> convert(const nn::MeasureTiming& measureTiming);
 nn::GeneralResult<Memory> convert(const nn::SharedMemory& memory);
 nn::GeneralResult<ErrorStatus> convert(const nn::ErrorStatus& errorStatus);
@@ -172,6 +179,8 @@
 nn::GeneralResult<Timing> convert(const nn::Timing& timing);
 nn::GeneralResult<int64_t> convert(const nn::OptionalDuration& optionalDuration);
 nn::GeneralResult<int64_t> convert(const nn::OptionalTimePoint& optionalTimePoint);
+nn::GeneralResult<Capabilities> convert(const nn::Capabilities& capabilities);
+nn::GeneralResult<Extension> convert(const nn::Extension& extension);
 
 nn::GeneralResult<std::vector<BufferRole>> convert(const std::vector<nn::BufferRole>& bufferRoles);
 nn::GeneralResult<std::vector<OutputShape>> convert(
@@ -180,6 +189,7 @@
         const std::vector<nn::SharedHandle>& handles);
 nn::GeneralResult<std::vector<ndk::ScopedFileDescriptor>> convert(
         const std::vector<nn::SyncFence>& syncFences);
+nn::GeneralResult<std::vector<Extension>> convert(const std::vector<nn::Extension>& extensions);
 
 nn::GeneralResult<std::vector<int32_t>> toSigned(const std::vector<uint32_t>& vec);
 
diff --git a/neuralnetworks/aidl/utils/src/Conversions.cpp b/neuralnetworks/aidl/utils/src/Conversions.cpp
index 45628c8..113d2da 100644
--- a/neuralnetworks/aidl/utils/src/Conversions.cpp
+++ b/neuralnetworks/aidl/utils/src/Conversions.cpp
@@ -551,6 +551,10 @@
     return validatedConvert(handle);
 }
 
+GeneralResult<BufferDesc> convert(const aidl_hal::BufferDesc& bufferDesc) {
+    return validatedConvert(bufferDesc);
+}
+
 GeneralResult<std::vector<Extension>> convert(const std::vector<aidl_hal::Extension>& extension) {
     return validatedConvert(extension);
 }
@@ -564,6 +568,15 @@
     return validatedConvert(outputShapes);
 }
 
+GeneralResult<std::vector<SharedHandle>> convert(
+        const std::vector<ndk::ScopedFileDescriptor>& handles) {
+    return validatedConvert(handles);
+}
+
+GeneralResult<std::vector<BufferRole>> convert(const std::vector<aidl_hal::BufferRole>& roles) {
+    return validatedConvert(roles);
+}
+
 GeneralResult<std::vector<uint32_t>> toUnsigned(const std::vector<int32_t>& vec) {
     if (!std::all_of(vec.begin(), vec.end(), [](int32_t v) { return v >= 0; })) {
         return NN_ERROR() << "Negative value passed to conversion from signed to unsigned";
@@ -576,42 +589,7 @@
 namespace aidl::android::hardware::neuralnetworks::utils {
 namespace {
 
-template <typename Input>
-using UnvalidatedConvertOutput =
-        std::decay_t<decltype(unvalidatedConvert(std::declval<Input>()).value())>;
-
-template <typename Type>
-nn::GeneralResult<std::vector<UnvalidatedConvertOutput<Type>>> unvalidatedConvertVec(
-        const std::vector<Type>& arguments) {
-    std::vector<UnvalidatedConvertOutput<Type>> halObject;
-    halObject.reserve(arguments.size());
-    for (const auto& argument : arguments) {
-        halObject.push_back(NN_TRY(unvalidatedConvert(argument)));
-    }
-    return halObject;
-}
-
-template <typename Type>
-nn::GeneralResult<std::vector<UnvalidatedConvertOutput<Type>>> unvalidatedConvert(
-        const std::vector<Type>& arguments) {
-    return unvalidatedConvertVec(arguments);
-}
-
-template <typename Type>
-nn::GeneralResult<UnvalidatedConvertOutput<Type>> validatedConvert(const Type& canonical) {
-    NN_TRY(compliantVersion(canonical));
-    return utils::unvalidatedConvert(canonical);
-}
-
-template <typename Type>
-nn::GeneralResult<std::vector<UnvalidatedConvertOutput<Type>>> validatedConvert(
-        const std::vector<Type>& arguments) {
-    std::vector<UnvalidatedConvertOutput<Type>> halObject(arguments.size());
-    for (size_t i = 0; i < arguments.size(); ++i) {
-        halObject[i] = NN_TRY(validatedConvert(arguments[i]));
-    }
-    return halObject;
-}
+using utils::unvalidatedConvert;
 
 // Helper template for std::visit
 template <class... Ts>
@@ -721,6 +699,74 @@
             operator nn::GeneralResult<Memory>();
 }
 
+nn::GeneralResult<PerformanceInfo> unvalidatedConvert(
+        const nn::Capabilities::PerformanceInfo& info) {
+    return PerformanceInfo{.execTime = info.execTime, .powerUsage = info.powerUsage};
+}
+
+nn::GeneralResult<OperandPerformance> unvalidatedConvert(
+        const nn::Capabilities::OperandPerformance& operandPerformance) {
+    return OperandPerformance{.type = NN_TRY(unvalidatedConvert(operandPerformance.type)),
+                              .info = NN_TRY(unvalidatedConvert(operandPerformance.info))};
+}
+
+nn::GeneralResult<std::vector<OperandPerformance>> unvalidatedConvert(
+        const nn::Capabilities::OperandPerformanceTable& table) {
+    std::vector<OperandPerformance> operandPerformances;
+    operandPerformances.reserve(table.asVector().size());
+    for (const auto& operandPerformance : table.asVector()) {
+        operandPerformances.push_back(NN_TRY(unvalidatedConvert(operandPerformance)));
+    }
+    return operandPerformances;
+}
+
+nn::GeneralResult<ExtensionOperandTypeInformation> unvalidatedConvert(
+        const nn::Extension::OperandTypeInformation& info) {
+    return ExtensionOperandTypeInformation{.type = info.type,
+                                           .isTensor = info.isTensor,
+                                           .byteSize = static_cast<int32_t>(info.byteSize)};
+}
+
+nn::GeneralResult<int64_t> unvalidatedConvert(const nn::Duration& duration) {
+    if (duration < nn::Duration::zero()) {
+        return NN_ERROR() << "Unable to convert invalid (negative) duration";
+    }
+    constexpr std::chrono::nanoseconds::rep kIntMax = std::numeric_limits<int64_t>::max();
+    const auto count = duration.count();
+    return static_cast<int64_t>(std::min(count, kIntMax));
+}
+
+template <typename Input>
+using UnvalidatedConvertOutput =
+        std::decay_t<decltype(unvalidatedConvert(std::declval<Input>()).value())>;
+
+template <typename Type>
+nn::GeneralResult<std::vector<UnvalidatedConvertOutput<Type>>> unvalidatedConvert(
+        const std::vector<Type>& arguments) {
+    std::vector<UnvalidatedConvertOutput<Type>> halObject;
+    halObject.reserve(arguments.size());
+    for (const auto& argument : arguments) {
+        halObject.push_back(NN_TRY(unvalidatedConvert(argument)));
+    }
+    return halObject;
+}
+
+template <typename Type>
+nn::GeneralResult<UnvalidatedConvertOutput<Type>> validatedConvert(const Type& canonical) {
+    NN_TRY(compliantVersion(canonical));
+    return utils::unvalidatedConvert(canonical);
+}
+
+template <typename Type>
+nn::GeneralResult<std::vector<UnvalidatedConvertOutput<Type>>> validatedConvert(
+        const std::vector<Type>& arguments) {
+    std::vector<UnvalidatedConvertOutput<Type>> halObject(arguments.size());
+    for (size_t i = 0; i < arguments.size(); ++i) {
+        halObject[i] = NN_TRY(validatedConvert(arguments[i]));
+    }
+    return halObject;
+}
+
 }  // namespace
 
 nn::GeneralResult<std::vector<uint8_t>> unvalidatedConvert(const nn::CacheToken& cacheToken) {
@@ -743,6 +789,19 @@
     };
 }
 
+nn::GeneralResult<DeviceType> unvalidatedConvert(const nn::DeviceType& deviceType) {
+    switch (deviceType) {
+        case nn::DeviceType::UNKNOWN:
+            break;
+        case nn::DeviceType::OTHER:
+        case nn::DeviceType::CPU:
+        case nn::DeviceType::GPU:
+        case nn::DeviceType::ACCELERATOR:
+            return static_cast<DeviceType>(deviceType);
+    }
+    return NN_ERROR() << "Invalid DeviceType " << deviceType;
+}
+
 nn::GeneralResult<bool> unvalidatedConvert(const nn::MeasureTiming& measureTiming) {
     return measureTiming == nn::MeasureTiming::YES;
 }
@@ -956,15 +1015,6 @@
     };
 }
 
-nn::GeneralResult<int64_t> unvalidatedConvert(const nn::Duration& duration) {
-    if (duration < nn::Duration::zero()) {
-        return NN_ERROR() << "Unable to convert invalid (negative) duration";
-    }
-    constexpr std::chrono::nanoseconds::rep kIntMax = std::numeric_limits<int64_t>::max();
-    const auto count = duration.count();
-    return static_cast<int64_t>(std::min(count, kIntMax));
-}
-
 nn::GeneralResult<int64_t> unvalidatedConvert(const nn::OptionalDuration& optionalDuration) {
     if (!optionalDuration.has_value()) {
         return kNoTiming;
@@ -989,6 +1039,23 @@
     return ndk::ScopedFileDescriptor(duplicatedFd.release());
 }
 
+nn::GeneralResult<Capabilities> unvalidatedConvert(const nn::Capabilities& capabilities) {
+    return Capabilities{
+            .relaxedFloat32toFloat16PerformanceTensor = NN_TRY(
+                    unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor)),
+            .relaxedFloat32toFloat16PerformanceScalar = NN_TRY(
+                    unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar)),
+            .operandPerformance = NN_TRY(unvalidatedConvert(capabilities.operandPerformance)),
+            .ifPerformance = NN_TRY(unvalidatedConvert(capabilities.ifPerformance)),
+            .whilePerformance = NN_TRY(unvalidatedConvert(capabilities.whilePerformance)),
+    };
+}
+
+nn::GeneralResult<Extension> unvalidatedConvert(const nn::Extension& extension) {
+    return Extension{.name = extension.name,
+                     .operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes))};
+}
+
 nn::GeneralResult<std::vector<uint8_t>> convert(const nn::CacheToken& cacheToken) {
     return validatedConvert(cacheToken);
 }
@@ -997,6 +1064,10 @@
     return validatedConvert(bufferDesc);
 }
 
+nn::GeneralResult<DeviceType> convert(const nn::DeviceType& deviceType) {
+    return validatedConvert(deviceType);
+}
+
 nn::GeneralResult<bool> convert(const nn::MeasureTiming& measureTiming) {
     return validatedConvert(measureTiming);
 }
@@ -1037,6 +1108,14 @@
     return validatedConvert(outputShapes);
 }
 
+nn::GeneralResult<Capabilities> convert(const nn::Capabilities& capabilities) {
+    return validatedConvert(capabilities);
+}
+
+nn::GeneralResult<Extension> convert(const nn::Extension& extension) {
+    return validatedConvert(extension);
+}
+
 nn::GeneralResult<std::vector<BufferRole>> convert(const std::vector<nn::BufferRole>& bufferRoles) {
     return validatedConvert(bufferRoles);
 }
@@ -1056,6 +1135,10 @@
     return validatedConvert(syncFences);
 }
 
+nn::GeneralResult<std::vector<Extension>> convert(const std::vector<nn::Extension>& extensions) {
+    return validatedConvert(extensions);
+}
+
 nn::GeneralResult<std::vector<int32_t>> toSigned(const std::vector<uint32_t>& vec) {
     if (!std::all_of(vec.begin(), vec.end(),
                      [](uint32_t v) { return v <= std::numeric_limits<int32_t>::max(); })) {
diff --git a/neuralnetworks/utils/adapter/aidl/Android.bp b/neuralnetworks/utils/adapter/aidl/Android.bp
new file mode 100644
index 0000000..8269a3d
--- /dev/null
+++ b/neuralnetworks/utils/adapter/aidl/Android.bp
@@ -0,0 +1,42 @@
+//
+// Copyright (C) 2021 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_static {
+    name: "neuralnetworks_utils_hal_adapter_aidl",
+    defaults: [
+        "neuralnetworks_use_latest_utils_hal_aidl",
+        "neuralnetworks_utils_defaults",
+    ],
+    srcs: ["src/*"],
+    local_include_dirs: ["include/nnapi/hal/aidl/"],
+    export_include_dirs: ["include"],
+    static_libs: [
+        "neuralnetworks_types",
+        "neuralnetworks_utils_hal_common",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+    ],
+}
diff --git a/neuralnetworks/utils/adapter/include/nnapi/hal/Adapter.h b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Adapter.h
similarity index 63%
copy from neuralnetworks/utils/adapter/include/nnapi/hal/Adapter.h
copy to neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Adapter.h
index da00a09..4c0b328 100644
--- a/neuralnetworks/utils/adapter/include/nnapi/hal/Adapter.h
+++ b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Adapter.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2020 The Android Open Source Project
+ * Copyright (C) 2021 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.
@@ -14,20 +14,20 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_ADAPTER_H
-#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_ADAPTER_H
+#ifndef ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_ADAPTER_H
+#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_ADAPTER_H
 
-#include <android/hardware/neuralnetworks/1.3/IDevice.h>
+#include <aidl/android/hardware/neuralnetworks/BnDevice.h>
 #include <nnapi/IDevice.h>
 #include <nnapi/Types.h>
-#include <sys/types.h>
+
 #include <functional>
 #include <memory>
 
-// See hardware/interfaces/neuralnetworks/utils/README.md for more information on HIDL interface
-// lifetimes across processes and for protecting asynchronous calls across HIDL.
+// See hardware/interfaces/neuralnetworks/utils/README.md for more information on AIDL interface
+// lifetimes across processes and for protecting asynchronous calls across AIDL.
 
-namespace android::hardware::neuralnetworks::adapter {
+namespace aidl::android::hardware::neuralnetworks::adapter {
 
 /**
  * A self-contained unit of work to be executed.
@@ -37,25 +37,26 @@
 /**
  * A type-erased executor which executes a task asynchronously.
  *
- * This executor is also provided with an Application ID (Android User ID) and an optional deadline
- * for when the caller expects is the upper bound for the amount of time to complete the task.
+ * This executor is also provided an optional deadline for when the caller expects is the upper
+ * bound for the amount of time to complete the task. If needed, the Executor can retrieve the
+ * Application ID (Android User ID) by calling AIBinder_getCallingUid in android/binder_ibinder.h.
  */
-using Executor = std::function<void(Task, uid_t, nn::OptionalTimePoint)>;
+using Executor = std::function<void(Task, ::android::nn::OptionalTimePoint)>;
 
 /**
- * Adapt an NNAPI canonical interface object to a HIDL NN HAL interface object.
+ * Adapt an NNAPI canonical interface object to a AIDL NN HAL interface object.
  *
  * The IPreparedModel object created from IDevice::prepareModel or IDevice::preparedModelFromCache
  * must return "const nn::Model*" from IPreparedModel::getUnderlyingResource().
  *
  * @param device NNAPI canonical IDevice interface object to be adapted.
  * @param executor Type-erased executor to handle executing tasks asynchronously.
- * @return HIDL NN HAL IDevice interface object.
+ * @return AIDL NN HAL IDevice interface object.
  */
-sp<V1_3::IDevice> adapt(nn::SharedDevice device, Executor executor);
+std::shared_ptr<BnDevice> adapt(::android::nn::SharedDevice device, Executor executor);
 
 /**
- * Adapt an NNAPI canonical interface object to a HIDL NN HAL interface object.
+ * Adapt an NNAPI canonical interface object to a AIDL NN HAL interface object.
  *
  * The IPreparedModel object created from IDevice::prepareModel or IDevice::preparedModelFromCache
  * must return "const nn::Model*" from IPreparedModel::getUnderlyingResource().
@@ -63,10 +64,10 @@
  * This function uses a default executor, which will execute tasks from a detached thread.
  *
  * @param device NNAPI canonical IDevice interface object to be adapted.
- * @return HIDL NN HAL IDevice interface object.
+ * @return AIDL NN HAL IDevice interface object.
  */
-sp<V1_3::IDevice> adapt(nn::SharedDevice device);
+std::shared_ptr<BnDevice> adapt(::android::nn::SharedDevice device);
 
-}  // namespace android::hardware::neuralnetworks::adapter
+}  // namespace aidl::android::hardware::neuralnetworks::adapter
 
-#endif  // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_ADAPTER_H
+#endif  // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_ADAPTER_H
diff --git a/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Buffer.h b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Buffer.h
new file mode 100644
index 0000000..701e43e
--- /dev/null
+++ b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Buffer.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2021 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_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_BUFFER_H
+#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_BUFFER_H
+
+#include <aidl/android/hardware/neuralnetworks/BnBuffer.h>
+#include <aidl/android/hardware/neuralnetworks/Memory.h>
+#include <android/binder_auto_utils.h>
+#include <nnapi/IBuffer.h>
+
+#include <memory>
+#include <vector>
+
+// See hardware/interfaces/neuralnetworks/utils/README.md for more information on AIDL interface
+// lifetimes across processes and for protecting asynchronous calls across AIDL.
+
+namespace aidl::android::hardware::neuralnetworks::adapter {
+
+// Class that adapts nn::IBuffer to BnBuffer.
+class Buffer : public BnBuffer {
+  public:
+    explicit Buffer(::android::nn::SharedBuffer buffer);
+
+    ndk::ScopedAStatus copyFrom(const Memory& src, const std::vector<int32_t>& dimensions) override;
+    ndk::ScopedAStatus copyTo(const Memory& dst) override;
+
+  private:
+    const ::android::nn::SharedBuffer kBuffer;
+};
+
+}  // namespace aidl::android::hardware::neuralnetworks::adapter
+
+#endif  // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_BUFFER_H
diff --git a/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Burst.h b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Burst.h
new file mode 100644
index 0000000..f2687c4
--- /dev/null
+++ b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Burst.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2021 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_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_BURST_H
+#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_BURST_H
+
+#include <aidl/android/hardware/neuralnetworks/BnBurst.h>
+#include <aidl/android/hardware/neuralnetworks/ExecutionResult.h>
+#include <aidl/android/hardware/neuralnetworks/Request.h>
+#include <android-base/thread_annotations.h>
+#include <android/binder_auto_utils.h>
+#include <nnapi/IBurst.h>
+#include <nnapi/Types.h>
+
+#include <memory>
+#include <mutex>
+#include <unordered_map>
+#include <vector>
+
+// See hardware/interfaces/neuralnetworks/utils/README.md for more information on AIDL interface
+// lifetimes across processes and for protecting asynchronous calls across AIDL.
+
+namespace aidl::android::hardware::neuralnetworks::adapter {
+
+// Class that adapts nn::Burst to BnBurst.
+class Burst : public BnBurst {
+  public:
+    // Precondition: burst != nullptr
+    explicit Burst(::android::nn::SharedBurst burst);
+
+    ndk::ScopedAStatus executeSynchronously(const Request& request,
+                                            const std::vector<int64_t>& memoryIdentifierTokens,
+                                            bool measureTiming, int64_t deadlineNs,
+                                            int64_t loopTimeoutDurationNs,
+                                            ExecutionResult* executionResult) override;
+    ndk::ScopedAStatus releaseMemoryResource(int64_t memoryIdentifierToken) override;
+
+    class ThreadSafeMemoryCache {
+      public:
+        using Value =
+                std::pair<::android::nn::SharedMemory, ::android::nn::IBurst::OptionalCacheHold>;
+
+        Value add(int64_t token, const ::android::nn::SharedMemory& memory,
+                  const ::android::nn::IBurst& burst) const;
+        void remove(int64_t token) const;
+
+      private:
+        mutable std::mutex mMutex;
+        mutable std::unordered_map<int64_t, Value> mCache GUARDED_BY(mMutex);
+    };
+
+  private:
+    const ::android::nn::SharedBurst kBurst;
+    const ThreadSafeMemoryCache kMemoryCache;
+};
+
+}  // namespace aidl::android::hardware::neuralnetworks::adapter
+
+#endif  // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_BURST_H
diff --git a/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Device.h b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Device.h
new file mode 100644
index 0000000..aa29d63
--- /dev/null
+++ b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/Device.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2021 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_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_DEVICE_H
+#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_DEVICE_H
+
+#include "nnapi/hal/aidl/Adapter.h"
+
+#include <aidl/android/hardware/neuralnetworks/BnDevice.h>
+#include <aidl/android/hardware/neuralnetworks/BufferDesc.h>
+#include <aidl/android/hardware/neuralnetworks/BufferRole.h>
+#include <aidl/android/hardware/neuralnetworks/Capabilities.h>
+#include <aidl/android/hardware/neuralnetworks/DeviceBuffer.h>
+#include <aidl/android/hardware/neuralnetworks/DeviceType.h>
+#include <aidl/android/hardware/neuralnetworks/ExecutionPreference.h>
+#include <aidl/android/hardware/neuralnetworks/Extension.h>
+#include <aidl/android/hardware/neuralnetworks/IPreparedModelCallback.h>
+#include <aidl/android/hardware/neuralnetworks/IPreparedModelParcel.h>
+#include <aidl/android/hardware/neuralnetworks/Model.h>
+#include <aidl/android/hardware/neuralnetworks/NumberOfCacheFiles.h>
+#include <aidl/android/hardware/neuralnetworks/Priority.h>
+#include <android/binder_auto_utils.h>
+#include <nnapi/IDevice.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+// See hardware/interfaces/neuralnetworks/utils/README.md for more information on AIDL interface
+// lifetimes across processes and for protecting asynchronous calls across AIDL.
+
+namespace aidl::android::hardware::neuralnetworks::adapter {
+
+// Class that adapts nn::IDevice to BnDevice.
+class Device : public BnDevice {
+  public:
+    Device(::android::nn::SharedDevice device, Executor executor);
+
+    ndk::ScopedAStatus allocate(const BufferDesc& desc,
+                                const std::vector<IPreparedModelParcel>& preparedModels,
+                                const std::vector<BufferRole>& inputRoles,
+                                const std::vector<BufferRole>& outputRoles,
+                                DeviceBuffer* buffer) override;
+    ndk::ScopedAStatus getCapabilities(Capabilities* capabilities) override;
+    ndk::ScopedAStatus getNumberOfCacheFilesNeeded(NumberOfCacheFiles* numberOfCacheFiles) override;
+    ndk::ScopedAStatus getSupportedExtensions(std::vector<Extension>* extensions) override;
+    ndk::ScopedAStatus getSupportedOperations(const Model& model,
+                                              std::vector<bool>* supported) override;
+    ndk::ScopedAStatus getType(DeviceType* deviceType) override;
+    ndk::ScopedAStatus getVersionString(std::string* version) override;
+    ndk::ScopedAStatus prepareModel(
+            const Model& model, ExecutionPreference preference, Priority priority,
+            int64_t deadlineNs, const std::vector<ndk::ScopedFileDescriptor>& modelCache,
+            const std::vector<ndk::ScopedFileDescriptor>& dataCache,
+            const std::vector<uint8_t>& token,
+            const std::shared_ptr<IPreparedModelCallback>& callback) override;
+    ndk::ScopedAStatus prepareModelFromCache(
+            int64_t deadlineNs, const std::vector<ndk::ScopedFileDescriptor>& modelCache,
+            const std::vector<ndk::ScopedFileDescriptor>& dataCache,
+            const std::vector<uint8_t>& token,
+            const std::shared_ptr<IPreparedModelCallback>& callback) override;
+
+  protected:
+    const ::android::nn::SharedDevice kDevice;
+    const Executor kExecutor;
+};
+
+}  // namespace aidl::android::hardware::neuralnetworks::adapter
+
+#endif  // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_DEVICE_H
diff --git a/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/PreparedModel.h b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/PreparedModel.h
new file mode 100644
index 0000000..93e0427
--- /dev/null
+++ b/neuralnetworks/utils/adapter/aidl/include/nnapi/hal/aidl/PreparedModel.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2021 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_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_PREPARED_MDOEL_H
+#define ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_PREPARED_MDOEL_H
+
+#include "nnapi/hal/aidl/Adapter.h"
+
+#include <aidl/android/hardware/neuralnetworks/BnPreparedModel.h>
+#include <aidl/android/hardware/neuralnetworks/ExecutionResult.h>
+#include <aidl/android/hardware/neuralnetworks/FencedExecutionResult.h>
+#include <aidl/android/hardware/neuralnetworks/IBurst.h>
+#include <aidl/android/hardware/neuralnetworks/Request.h>
+#include <android/binder_auto_utils.h>
+#include <nnapi/IPreparedModel.h>
+#include <nnapi/Types.h>
+
+#include <memory>
+#include <vector>
+
+// See hardware/interfaces/neuralnetworks/utils/README.md for more information on AIDL interface
+// lifetimes across processes and for protecting asynchronous calls across AIDL.
+
+namespace aidl::android::hardware::neuralnetworks::adapter {
+
+// Class that adapts nn::IPreparedModel to BnPreparedModel.
+class PreparedModel : public BnPreparedModel {
+  public:
+    explicit PreparedModel(::android::nn::SharedPreparedModel preparedModel);
+
+    ndk::ScopedAStatus executeSynchronously(const Request& request, bool measureTiming,
+                                            int64_t deadlineNs, int64_t loopTimeoutDurationNs,
+                                            ExecutionResult* executionResult) override;
+    ndk::ScopedAStatus executeFenced(const Request& request,
+                                     const std::vector<ndk::ScopedFileDescriptor>& waitFor,
+                                     bool measureTiming, int64_t deadlineNs,
+                                     int64_t loopTimeoutDurationNs, int64_t durationNs,
+                                     FencedExecutionResult* executionResult) override;
+    ndk::ScopedAStatus configureExecutionBurst(std::shared_ptr<IBurst>* burst) override;
+
+    ::android::nn::SharedPreparedModel getUnderlyingPreparedModel() const;
+
+  protected:
+    const ::android::nn::SharedPreparedModel kPreparedModel;
+};
+
+}  // namespace aidl::android::hardware::neuralnetworks::adapter
+
+#endif  // ANDROID_HARDWARE_INTERFACES_NEURALNETWORKS_UTILS_ADAPTER_AIDL_PREPARED_MDOEL_H
diff --git a/neuralnetworks/utils/adapter/aidl/src/Adapter.cpp b/neuralnetworks/utils/adapter/aidl/src/Adapter.cpp
new file mode 100644
index 0000000..d0b56e8
--- /dev/null
+++ b/neuralnetworks/utils/adapter/aidl/src/Adapter.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 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 "Adapter.h"
+
+#include "Device.h"
+
+#include <aidl/android/hardware/neuralnetworks/BnDevice.h>
+#include <android/binder_interface_utils.h>
+#include <nnapi/IDevice.h>
+#include <nnapi/Types.h>
+
+#include <functional>
+#include <memory>
+#include <thread>
+
+// See hardware/interfaces/neuralnetworks/utils/README.md for more information on AIDL interface
+// lifetimes across processes and for protecting asynchronous calls across AIDL.
+
+namespace aidl::android::hardware::neuralnetworks::adapter {
+
+std::shared_ptr<BnDevice> adapt(::android::nn::SharedDevice device, Executor executor) {
+    return ndk::SharedRefBase::make<Device>(std::move(device), std::move(executor));
+}
+
+std::shared_ptr<BnDevice> adapt(::android::nn::SharedDevice device) {
+    Executor defaultExecutor = [](Task task, ::android::nn::OptionalTimePoint /*deadline*/) {
+        std::thread(std::move(task)).detach();
+    };
+    return adapt(std::move(device), std::move(defaultExecutor));
+}
+
+}  // namespace aidl::android::hardware::neuralnetworks::adapter
diff --git a/neuralnetworks/utils/adapter/aidl/src/Buffer.cpp b/neuralnetworks/utils/adapter/aidl/src/Buffer.cpp
new file mode 100644
index 0000000..c15ab65
--- /dev/null
+++ b/neuralnetworks/utils/adapter/aidl/src/Buffer.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2021 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 "Buffer.h"
+
+#include <aidl/android/hardware/neuralnetworks/BnBuffer.h>
+#include <aidl/android/hardware/neuralnetworks/Memory.h>
+#include <android-base/logging.h>
+#include <android/binder_auto_utils.h>
+#include <nnapi/IBuffer.h>
+#include <nnapi/Result.h>
+#include <nnapi/Types.h>
+#include <nnapi/hal/aidl/Conversions.h>
+
+namespace aidl::android::hardware::neuralnetworks::adapter {
+namespace {
+
+template <typename Type>
+auto convertInput(const Type& object) -> decltype(nn::convert(std::declval<Type>())) {
+    auto result = nn::convert(object);
+    if (!result.has_value()) {
+        result.error().code = nn::ErrorStatus::INVALID_ARGUMENT;
+    }
+    return result;
+}
+
+nn::GeneralResult<std::vector<uint32_t>> inputToUnsigned(const std::vector<int32_t>& dims) {
+    auto result = nn::toUnsigned(dims);
+    if (!result.has_value()) {
+        result.error().code = nn::ErrorStatus::INVALID_ARGUMENT;
+    }
+    return result;
+}
+
+nn::GeneralResult<void> copyTo(const nn::IBuffer& buffer, const Memory& dst) {
+    const auto nnDst = NN_TRY(convertInput(dst));
+    return buffer.copyTo(nnDst);
+}
+
+nn::GeneralResult<void> copyFrom(const nn::IBuffer& buffer, const Memory& src,
+                                 const std::vector<int32_t>& dimensions) {
+    const auto nnSrc = NN_TRY(convertInput(src));
+    const auto nnDims = NN_TRY(inputToUnsigned(dimensions));
+    return buffer.copyFrom(nnSrc, nnDims);
+}
+
+}  // namespace
+
+Buffer::Buffer(nn::SharedBuffer buffer) : kBuffer(std::move(buffer)) {
+    CHECK(kBuffer != nullptr);
+}
+
+ndk::ScopedAStatus Buffer::copyTo(const Memory& dst) {
+    const auto result = adapter::copyTo(*kBuffer, dst);
+    if (!result.has_value()) {
+        const auto& [message, code] = result.error();
+        const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE);
+        return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                static_cast<int32_t>(aidlCode), message.c_str());
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Buffer::copyFrom(const Memory& src, const std::vector<int32_t>& dimensions) {
+    const auto result = adapter::copyFrom(*kBuffer, src, dimensions);
+    if (!result.has_value()) {
+        const auto& [message, code] = result.error();
+        const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE);
+        return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                static_cast<int32_t>(aidlCode), message.c_str());
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace aidl::android::hardware::neuralnetworks::adapter
diff --git a/neuralnetworks/utils/adapter/aidl/src/Burst.cpp b/neuralnetworks/utils/adapter/aidl/src/Burst.cpp
new file mode 100644
index 0000000..4fabb20
--- /dev/null
+++ b/neuralnetworks/utils/adapter/aidl/src/Burst.cpp
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2021 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 "Burst.h"
+
+#include <android-base/logging.h>
+#include <android-base/thread_annotations.h>
+#include <android/binder_auto_utils.h>
+#include <nnapi/IBurst.h>
+#include <nnapi/Result.h>
+#include <nnapi/Types.h>
+#include <nnapi/Validation.h>
+#include <nnapi/hal/aidl/Conversions.h>
+#include <nnapi/hal/aidl/Utils.h>
+
+#include <algorithm>
+#include <chrono>
+#include <memory>
+#include <mutex>
+#include <unordered_map>
+#include <utility>
+#include <variant>
+
+namespace aidl::android::hardware::neuralnetworks::adapter {
+namespace {
+
+using Value = Burst::ThreadSafeMemoryCache::Value;
+
+template <typename Type>
+auto convertInput(const Type& object) -> decltype(nn::convert(std::declval<Type>())) {
+    auto result = nn::convert(object);
+    if (!result.has_value()) {
+        result.error().code = nn::ErrorStatus::INVALID_ARGUMENT;
+    }
+    return result;
+}
+
+nn::Duration makeDuration(int64_t durationNs) {
+    return nn::Duration(std::chrono::nanoseconds(durationNs));
+}
+
+nn::GeneralResult<nn::OptionalDuration> makeOptionalDuration(int64_t durationNs) {
+    if (durationNs < -1) {
+        return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid duration " << durationNs;
+    }
+    return durationNs < 0 ? nn::OptionalDuration{} : makeDuration(durationNs);
+}
+
+nn::GeneralResult<nn::OptionalTimePoint> makeOptionalTimePoint(int64_t durationNs) {
+    if (durationNs < -1) {
+        return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid time point " << durationNs;
+    }
+    return durationNs < 0 ? nn::OptionalTimePoint{} : nn::TimePoint(makeDuration(durationNs));
+}
+
+std::vector<nn::IBurst::OptionalCacheHold> ensureAllMemoriesAreCached(
+        nn::Request* request, const std::vector<int64_t>& memoryIdentifierTokens,
+        const nn::IBurst& burst, const Burst::ThreadSafeMemoryCache& cache) {
+    std::vector<nn::IBurst::OptionalCacheHold> holds;
+    holds.reserve(memoryIdentifierTokens.size());
+
+    for (size_t i = 0; i < memoryIdentifierTokens.size(); ++i) {
+        const auto& pool = request->pools[i];
+        const auto token = memoryIdentifierTokens[i];
+        constexpr int64_t kNoToken = -1;
+        if (token == kNoToken || !std::holds_alternative<nn::SharedMemory>(pool)) {
+            continue;
+        }
+
+        const auto& memory = std::get<nn::SharedMemory>(pool);
+        auto [storedMemory, hold] = cache.add(token, memory, burst);
+
+        request->pools[i] = std::move(storedMemory);
+        holds.push_back(std::move(hold));
+    }
+
+    return holds;
+}
+
+nn::ExecutionResult<ExecutionResult> executeSynchronously(
+        const nn::IBurst& burst, const Burst::ThreadSafeMemoryCache& cache, const Request& request,
+        const std::vector<int64_t>& memoryIdentifierTokens, bool measureTiming, int64_t deadlineNs,
+        int64_t loopTimeoutDurationNs) {
+    if (request.pools.size() != memoryIdentifierTokens.size()) {
+        return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT)
+               << "request.pools.size() != memoryIdentifierTokens.size()";
+    }
+    if (!std::all_of(memoryIdentifierTokens.begin(), memoryIdentifierTokens.end(),
+                     [](int64_t token) { return token >= -1; })) {
+        return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid memoryIdentifierTokens";
+    }
+
+    auto nnRequest = NN_TRY(convertInput(request));
+    const auto nnMeasureTiming = measureTiming ? nn::MeasureTiming::YES : nn::MeasureTiming::NO;
+    const auto nnDeadline = NN_TRY(makeOptionalTimePoint(deadlineNs));
+    const auto nnLoopTimeoutDuration = NN_TRY(makeOptionalDuration(loopTimeoutDurationNs));
+
+    const auto hold = ensureAllMemoriesAreCached(&nnRequest, memoryIdentifierTokens, burst, cache);
+
+    const auto result =
+            burst.execute(nnRequest, nnMeasureTiming, nnDeadline, nnLoopTimeoutDuration);
+
+    if (!result.ok() && result.error().code == nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE) {
+        const auto& [message, code, outputShapes] = result.error();
+        return ExecutionResult{.outputSufficientSize = false,
+                               .outputShapes = utils::convert(outputShapes).value(),
+                               .timing = {.timeInDriverNs = -1, .timeOnDeviceNs = -1}};
+    }
+
+    const auto& [outputShapes, timing] = NN_TRY(result);
+    return ExecutionResult{.outputSufficientSize = true,
+                           .outputShapes = utils::convert(outputShapes).value(),
+                           .timing = utils::convert(timing).value()};
+}
+
+}  // namespace
+
+Value Burst::ThreadSafeMemoryCache::add(int64_t token, const nn::SharedMemory& memory,
+                                        const nn::IBurst& burst) const {
+    std::lock_guard guard(mMutex);
+    if (const auto it = mCache.find(token); it != mCache.end()) {
+        return it->second;
+    }
+    auto hold = burst.cacheMemory(memory);
+    auto [it, _] = mCache.emplace(token, std::make_pair(memory, std::move(hold)));
+    return it->second;
+}
+
+void Burst::ThreadSafeMemoryCache::remove(int64_t token) const {
+    std::lock_guard guard(mMutex);
+    mCache.erase(token);
+}
+
+Burst::Burst(nn::SharedBurst burst) : kBurst(std::move(burst)) {
+    CHECK(kBurst != nullptr);
+}
+
+ndk::ScopedAStatus Burst::executeSynchronously(const Request& request,
+                                               const std::vector<int64_t>& memoryIdentifierTokens,
+                                               bool measureTiming, int64_t deadlineNs,
+                                               int64_t loopTimeoutDurationNs,
+                                               ExecutionResult* executionResult) {
+    auto result =
+            adapter::executeSynchronously(*kBurst, kMemoryCache, request, memoryIdentifierTokens,
+                                          measureTiming, deadlineNs, loopTimeoutDurationNs);
+    if (!result.has_value()) {
+        auto [message, code, _] = std::move(result).error();
+        const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE);
+        return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                static_cast<int32_t>(aidlCode), message.c_str());
+    }
+    *executionResult = std::move(result).value();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Burst::releaseMemoryResource(int64_t memoryIdentifierToken) {
+    if (memoryIdentifierToken < -1) {
+        return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                static_cast<int32_t>(ErrorStatus::INVALID_ARGUMENT),
+                "Invalid memoryIdentifierToken");
+    }
+    kMemoryCache.remove(memoryIdentifierToken);
+    return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace aidl::android::hardware::neuralnetworks::adapter
diff --git a/neuralnetworks/utils/adapter/aidl/src/Device.cpp b/neuralnetworks/utils/adapter/aidl/src/Device.cpp
new file mode 100644
index 0000000..763be7f
--- /dev/null
+++ b/neuralnetworks/utils/adapter/aidl/src/Device.cpp
@@ -0,0 +1,304 @@
+/*
+ * Copyright (C) 2021 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 "Device.h"
+
+#include "Adapter.h"
+#include "Buffer.h"
+#include "PreparedModel.h"
+
+#include <aidl/android/hardware/neuralnetworks/BnDevice.h>
+#include <aidl/android/hardware/neuralnetworks/BufferDesc.h>
+#include <aidl/android/hardware/neuralnetworks/BufferRole.h>
+#include <aidl/android/hardware/neuralnetworks/DeviceBuffer.h>
+#include <aidl/android/hardware/neuralnetworks/DeviceType.h>
+#include <aidl/android/hardware/neuralnetworks/ErrorStatus.h>
+#include <aidl/android/hardware/neuralnetworks/ExecutionPreference.h>
+#include <aidl/android/hardware/neuralnetworks/Extension.h>
+#include <aidl/android/hardware/neuralnetworks/IPreparedModelCallback.h>
+#include <aidl/android/hardware/neuralnetworks/IPreparedModelParcel.h>
+#include <aidl/android/hardware/neuralnetworks/Model.h>
+#include <aidl/android/hardware/neuralnetworks/NumberOfCacheFiles.h>
+#include <aidl/android/hardware/neuralnetworks/Priority.h>
+#include <android-base/logging.h>
+#include <android/binder_auto_utils.h>
+#include <android/binder_interface_utils.h>
+#include <nnapi/IDevice.h>
+#include <nnapi/Result.h>
+#include <nnapi/TypeUtils.h>
+#include <nnapi/Types.h>
+#include <nnapi/hal/aidl/Conversions.h>
+
+#include <chrono>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace aidl::android::hardware::neuralnetworks::adapter {
+namespace {
+
+template <typename Type>
+auto convertInput(const Type& object) -> decltype(nn::convert(std::declval<Type>())) {
+    auto result = nn::convert(object);
+    if (!result.has_value()) {
+        result.error().code = nn::ErrorStatus::INVALID_ARGUMENT;
+    }
+    return result;
+}
+
+nn::Duration makeDuration(int64_t durationNs) {
+    return nn::Duration(std::chrono::nanoseconds(durationNs));
+}
+
+nn::GeneralResult<nn::OptionalTimePoint> makeOptionalTimePoint(int64_t durationNs) {
+    if (durationNs < -1) {
+        return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid time point " << durationNs;
+    }
+    return durationNs < 0 ? nn::OptionalTimePoint{} : nn::TimePoint(makeDuration(durationNs));
+}
+
+nn::GeneralResult<nn::CacheToken> convertCacheToken(const std::vector<uint8_t>& token) {
+    nn::CacheToken nnToken;
+    if (token.size() != nnToken.size()) {
+        return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid token";
+    }
+    std::copy(token.begin(), token.end(), nnToken.begin());
+    return nnToken;
+}
+
+nn::GeneralResult<nn::SharedPreparedModel> downcast(const IPreparedModelParcel& preparedModel) {
+    if (preparedModel.preparedModel == nullptr) {
+        return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "preparedModel is nullptr";
+    }
+    if (preparedModel.preparedModel->isRemote()) {
+        return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Cannot convert remote models";
+    }
+
+    // This static_cast is safe because adapter::PreparedModel is the only class that implements
+    // the IPreparedModel interface in the adapter service code.
+    const auto* casted = static_cast<const PreparedModel*>(preparedModel.preparedModel.get());
+    return casted->getUnderlyingPreparedModel();
+}
+
+nn::GeneralResult<std::vector<nn::SharedPreparedModel>> downcastAll(
+        const std::vector<IPreparedModelParcel>& preparedModels) {
+    std::vector<nn::SharedPreparedModel> canonical;
+    canonical.reserve(preparedModels.size());
+    for (const auto& preparedModel : preparedModels) {
+        canonical.push_back(NN_TRY(downcast(preparedModel)));
+    }
+    return canonical;
+}
+
+nn::GeneralResult<DeviceBuffer> allocate(const nn::IDevice& device, const BufferDesc& desc,
+                                         const std::vector<IPreparedModelParcel>& preparedModels,
+                                         const std::vector<BufferRole>& inputRoles,
+                                         const std::vector<BufferRole>& outputRoles) {
+    auto nnDesc = NN_TRY(convertInput(desc));
+    auto nnPreparedModels = NN_TRY(downcastAll(preparedModels));
+    auto nnInputRoles = NN_TRY(convertInput(inputRoles));
+    auto nnOutputRoles = NN_TRY(convertInput(outputRoles));
+
+    auto buffer = NN_TRY(device.allocate(nnDesc, nnPreparedModels, nnInputRoles, nnOutputRoles));
+    CHECK(buffer != nullptr);
+
+    const nn::Request::MemoryDomainToken token = buffer->getToken();
+    auto aidlBuffer = ndk::SharedRefBase::make<Buffer>(std::move(buffer));
+    return DeviceBuffer{.buffer = std::move(aidlBuffer), .token = static_cast<int32_t>(token)};
+}
+
+nn::GeneralResult<std::vector<bool>> getSupportedOperations(const nn::IDevice& device,
+                                                            const Model& model) {
+    const auto nnModel = NN_TRY(convertInput(model));
+    return device.getSupportedOperations(nnModel);
+}
+
+using PrepareModelResult = nn::GeneralResult<nn::SharedPreparedModel>;
+
+std::shared_ptr<PreparedModel> adaptPreparedModel(nn::SharedPreparedModel preparedModel) {
+    if (preparedModel == nullptr) {
+        return nullptr;
+    }
+    return ndk::SharedRefBase::make<PreparedModel>(std::move(preparedModel));
+}
+
+void notify(IPreparedModelCallback* callback, PrepareModelResult result) {
+    if (!result.has_value()) {
+        const auto& [message, status] = result.error();
+        LOG(ERROR) << message;
+        const auto aidlCode = utils::convert(status).value_or(ErrorStatus::GENERAL_FAILURE);
+        callback->notify(aidlCode, nullptr);
+    } else {
+        auto preparedModel = std::move(result).value();
+        auto aidlPreparedModel = adaptPreparedModel(std::move(preparedModel));
+        callback->notify(ErrorStatus::NONE, std::move(aidlPreparedModel));
+    }
+}
+
+nn::GeneralResult<void> prepareModel(const nn::SharedDevice& device, const Executor& executor,
+                                     const Model& model, ExecutionPreference preference,
+                                     Priority priority, int64_t deadlineNs,
+                                     const std::vector<ndk::ScopedFileDescriptor>& modelCache,
+                                     const std::vector<ndk::ScopedFileDescriptor>& dataCache,
+                                     const std::vector<uint8_t>& token,
+                                     const std::shared_ptr<IPreparedModelCallback>& callback) {
+    if (callback.get() == nullptr) {
+        return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid callback";
+    }
+
+    auto nnModel = NN_TRY(convertInput(model));
+    const auto nnPreference = NN_TRY(convertInput(preference));
+    const auto nnPriority = NN_TRY(convertInput(priority));
+    const auto nnDeadline = NN_TRY(makeOptionalTimePoint(deadlineNs));
+    auto nnModelCache = NN_TRY(convertInput(modelCache));
+    auto nnDataCache = NN_TRY(convertInput(dataCache));
+    const auto nnToken = NN_TRY(convertCacheToken(token));
+
+    Task task = [device, nnModel = std::move(nnModel), nnPreference, nnPriority, nnDeadline,
+                 nnModelCache = std::move(nnModelCache), nnDataCache = std::move(nnDataCache),
+                 nnToken, callback] {
+        auto result = device->prepareModel(nnModel, nnPreference, nnPriority, nnDeadline,
+                                           nnModelCache, nnDataCache, nnToken);
+        notify(callback.get(), std::move(result));
+    };
+    executor(std::move(task), nnDeadline);
+
+    return {};
+}
+
+nn::GeneralResult<void> prepareModelFromCache(
+        const nn::SharedDevice& device, const Executor& executor, int64_t deadlineNs,
+        const std::vector<ndk::ScopedFileDescriptor>& modelCache,
+        const std::vector<ndk::ScopedFileDescriptor>& dataCache, const std::vector<uint8_t>& token,
+        const std::shared_ptr<IPreparedModelCallback>& callback) {
+    if (callback.get() == nullptr) {
+        return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid callback";
+    }
+
+    const auto nnDeadline = NN_TRY(makeOptionalTimePoint(deadlineNs));
+    auto nnModelCache = NN_TRY(convertInput(modelCache));
+    auto nnDataCache = NN_TRY(convertInput(dataCache));
+    const auto nnToken = NN_TRY(convertCacheToken(token));
+
+    auto task = [device, nnDeadline, nnModelCache = std::move(nnModelCache),
+                 nnDataCache = std::move(nnDataCache), nnToken, callback] {
+        auto result = device->prepareModelFromCache(nnDeadline, nnModelCache, nnDataCache, nnToken);
+        notify(callback.get(), std::move(result));
+    };
+    executor(std::move(task), nnDeadline);
+
+    return {};
+}
+
+}  // namespace
+
+Device::Device(::android::nn::SharedDevice device, Executor executor)
+    : kDevice(std::move(device)), kExecutor(std::move(executor)) {
+    CHECK(kDevice != nullptr);
+    CHECK(kExecutor != nullptr);
+}
+
+ndk::ScopedAStatus Device::allocate(const BufferDesc& desc,
+                                    const std::vector<IPreparedModelParcel>& preparedModels,
+                                    const std::vector<BufferRole>& inputRoles,
+                                    const std::vector<BufferRole>& outputRoles,
+                                    DeviceBuffer* buffer) {
+    auto result = adapter::allocate(*kDevice, desc, preparedModels, inputRoles, outputRoles);
+    if (!result.has_value()) {
+        const auto& [message, code] = result.error();
+        const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE);
+        return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                static_cast<int32_t>(aidlCode), message.c_str());
+    }
+    *buffer = std::move(result).value();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Device::getCapabilities(Capabilities* capabilities) {
+    *capabilities = utils::convert(kDevice->getCapabilities()).value();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Device::getNumberOfCacheFilesNeeded(NumberOfCacheFiles* numberOfCacheFiles) {
+    const auto [numModelCache, numDataCache] = kDevice->getNumberOfCacheFilesNeeded();
+    *numberOfCacheFiles = NumberOfCacheFiles{.numModelCache = static_cast<int32_t>(numModelCache),
+                                             .numDataCache = static_cast<int32_t>(numDataCache)};
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Device::getSupportedExtensions(std::vector<Extension>* extensions) {
+    *extensions = utils::convert(kDevice->getSupportedExtensions()).value();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Device::getSupportedOperations(const Model& model,
+                                                  std::vector<bool>* supported) {
+    auto result = adapter::getSupportedOperations(*kDevice, model);
+    if (!result.has_value()) {
+        const auto& [message, code] = result.error();
+        const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE);
+        return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                static_cast<int32_t>(aidlCode), message.c_str());
+    }
+    *supported = std::move(result).value();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Device::getType(DeviceType* deviceType) {
+    *deviceType = utils::convert(kDevice->getType()).value();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Device::getVersionString(std::string* version) {
+    *version = kDevice->getVersionString();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Device::prepareModel(const Model& model, ExecutionPreference preference,
+                                        Priority priority, int64_t deadlineNs,
+                                        const std::vector<ndk::ScopedFileDescriptor>& modelCache,
+                                        const std::vector<ndk::ScopedFileDescriptor>& dataCache,
+                                        const std::vector<uint8_t>& token,
+                                        const std::shared_ptr<IPreparedModelCallback>& callback) {
+    const auto result = adapter::prepareModel(kDevice, kExecutor, model, preference, priority,
+                                              deadlineNs, modelCache, dataCache, token, callback);
+    if (!result.has_value()) {
+        const auto& [message, code] = result.error();
+        const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE);
+        callback->notify(aidlCode, nullptr);
+        return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                static_cast<int32_t>(aidlCode), message.c_str());
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Device::prepareModelFromCache(
+        int64_t deadlineNs, const std::vector<ndk::ScopedFileDescriptor>& modelCache,
+        const std::vector<ndk::ScopedFileDescriptor>& dataCache, const std::vector<uint8_t>& token,
+        const std::shared_ptr<IPreparedModelCallback>& callback) {
+    const auto result = adapter::prepareModelFromCache(kDevice, kExecutor, deadlineNs, modelCache,
+                                                       dataCache, token, callback);
+    if (!result.has_value()) {
+        const auto& [message, code] = result.error();
+        const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE);
+        callback->notify(aidlCode, nullptr);
+        return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                static_cast<int32_t>(aidlCode), message.c_str());
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace aidl::android::hardware::neuralnetworks::adapter
diff --git a/neuralnetworks/utils/adapter/aidl/src/PreparedModel.cpp b/neuralnetworks/utils/adapter/aidl/src/PreparedModel.cpp
new file mode 100644
index 0000000..71ed1a8
--- /dev/null
+++ b/neuralnetworks/utils/adapter/aidl/src/PreparedModel.cpp
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2021 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 "PreparedModel.h"
+
+#include "Burst.h"
+
+#include <aidl/android/hardware/neuralnetworks/BnFencedExecutionCallback.h>
+#include <aidl/android/hardware/neuralnetworks/BnPreparedModel.h>
+#include <aidl/android/hardware/neuralnetworks/ExecutionResult.h>
+#include <aidl/android/hardware/neuralnetworks/FencedExecutionResult.h>
+#include <aidl/android/hardware/neuralnetworks/IBurst.h>
+#include <aidl/android/hardware/neuralnetworks/Request.h>
+#include <android-base/logging.h>
+#include <android/binder_auto_utils.h>
+#include <nnapi/IPreparedModel.h>
+#include <nnapi/Result.h>
+#include <nnapi/SharedMemory.h>
+#include <nnapi/Types.h>
+#include <nnapi/Validation.h>
+#include <nnapi/hal/aidl/Conversions.h>
+#include <nnapi/hal/aidl/Utils.h>
+
+#include <memory>
+#include <utility>
+#include <vector>
+
+namespace aidl::android::hardware::neuralnetworks::adapter {
+namespace {
+
+class FencedExecutionCallback : public BnFencedExecutionCallback {
+  public:
+    FencedExecutionCallback(nn::ExecuteFencedInfoCallback callback)
+        : kCallback(std::move(callback)) {}
+
+    ndk::ScopedAStatus getExecutionInfo(Timing* timingLaunched, Timing* timingFenced,
+                                        ErrorStatus* errorStatus) override {
+        const auto result = kCallback();
+        if (result.ok()) {
+            const auto& [nnTimingLaunched, nnTimingFenced] = result.value();
+            *timingLaunched = utils::convert(nnTimingLaunched).value();
+            *timingFenced = utils::convert(nnTimingFenced).value();
+            *errorStatus = ErrorStatus::NONE;
+        } else {
+            constexpr auto kNoTiming = Timing{.timeOnDeviceNs = -1, .timeInDriverNs = -1};
+            const auto& [message, code] = result.error();
+            LOG(ERROR) << "getExecutionInfo failed with " << code << ": " << message;
+            const auto aidlStatus = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE);
+            *timingLaunched = kNoTiming;
+            *timingFenced = kNoTiming;
+            *errorStatus = aidlStatus;
+        }
+        return ndk::ScopedAStatus::ok();
+    }
+
+  private:
+    const nn::ExecuteFencedInfoCallback kCallback;
+};
+
+template <typename Type>
+auto convertInput(const Type& object) -> decltype(nn::convert(std::declval<Type>())) {
+    auto result = nn::convert(object);
+    if (!result.has_value()) {
+        result.error().code = nn::ErrorStatus::INVALID_ARGUMENT;
+    }
+    return result;
+}
+
+nn::GeneralResult<std::vector<nn::SyncFence>> convertSyncFences(
+        const std::vector<ndk::ScopedFileDescriptor>& waitFor) {
+    auto handles = NN_TRY(convertInput(waitFor));
+
+    constexpr auto valid = [](const nn::SharedHandle& handle) {
+        return handle != nullptr && handle->ok();
+    };
+    if (!std::all_of(handles.begin(), handles.end(), valid)) {
+        return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid sync fence";
+    }
+
+    std::vector<nn::SyncFence> syncFences;
+    syncFences.reserve(waitFor.size());
+    for (auto& handle : handles) {
+        syncFences.push_back(nn::SyncFence::create(std::move(handle)).value());
+    }
+    return syncFences;
+}
+
+nn::Duration makeDuration(int64_t durationNs) {
+    return nn::Duration(std::chrono::nanoseconds(durationNs));
+}
+
+nn::GeneralResult<nn::OptionalDuration> makeOptionalDuration(int64_t durationNs) {
+    if (durationNs < -1) {
+        return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid duration " << durationNs;
+    }
+    return durationNs < 0 ? nn::OptionalDuration{} : makeDuration(durationNs);
+}
+
+nn::GeneralResult<nn::OptionalTimePoint> makeOptionalTimePoint(int64_t durationNs) {
+    if (durationNs < -1) {
+        return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) << "Invalid time point " << durationNs;
+    }
+    return durationNs < 0 ? nn::OptionalTimePoint{} : nn::TimePoint(makeDuration(durationNs));
+}
+
+nn::ExecutionResult<ExecutionResult> executeSynchronously(const nn::IPreparedModel& preparedModel,
+                                                          const Request& request,
+                                                          bool measureTiming, int64_t deadlineNs,
+                                                          int64_t loopTimeoutDurationNs) {
+    const auto nnRequest = NN_TRY(convertInput(request));
+    const auto nnMeasureTiming = measureTiming ? nn::MeasureTiming::YES : nn::MeasureTiming::NO;
+    const auto nnDeadline = NN_TRY(makeOptionalTimePoint(deadlineNs));
+    const auto nnLoopTimeoutDuration = NN_TRY(makeOptionalDuration(loopTimeoutDurationNs));
+
+    const auto result =
+            preparedModel.execute(nnRequest, nnMeasureTiming, nnDeadline, nnLoopTimeoutDuration);
+
+    if (!result.ok() && result.error().code == nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE) {
+        const auto& [message, code, outputShapes] = result.error();
+        LOG(ERROR) << "executeSynchronously failed with " << code << ": " << message;
+        return ExecutionResult{.outputSufficientSize = false,
+                               .outputShapes = utils::convert(outputShapes).value(),
+                               .timing = {.timeInDriverNs = -1, .timeOnDeviceNs = -1}};
+    }
+
+    const auto& [outputShapes, timing] = NN_TRY(result);
+    return ExecutionResult{.outputSufficientSize = true,
+                           .outputShapes = utils::convert(outputShapes).value(),
+                           .timing = utils::convert(timing).value()};
+}
+
+nn::GeneralResult<FencedExecutionResult> executeFenced(
+        const nn::IPreparedModel& preparedModel, const Request& request,
+        const std::vector<ndk::ScopedFileDescriptor>& waitFor, bool measureTiming,
+        int64_t deadlineNs, int64_t loopTimeoutDurationNs, int64_t durationNs) {
+    const auto nnRequest = NN_TRY(convertInput(request));
+    const auto nnWaitFor = NN_TRY(convertSyncFences(waitFor));
+    const auto nnMeasureTiming = measureTiming ? nn::MeasureTiming::YES : nn::MeasureTiming::NO;
+    const auto nnDeadline = NN_TRY(makeOptionalTimePoint(deadlineNs));
+    const auto nnLoopTimeoutDuration = NN_TRY(makeOptionalDuration(loopTimeoutDurationNs));
+    const auto nnDuration = NN_TRY(makeOptionalDuration(durationNs));
+
+    auto [syncFence, executeFencedInfoCallback] = NN_TRY(preparedModel.executeFenced(
+            nnRequest, nnWaitFor, nnMeasureTiming, nnDeadline, nnLoopTimeoutDuration, nnDuration));
+
+    ndk::ScopedFileDescriptor fileDescriptor;
+    if (syncFence.hasFd()) {
+        auto uniqueFd = NN_TRY(nn::dupFd(syncFence.getFd()));
+        fileDescriptor = ndk::ScopedFileDescriptor(uniqueFd.release());
+    }
+
+    return FencedExecutionResult{.callback = ndk::SharedRefBase::make<FencedExecutionCallback>(
+                                         std::move(executeFencedInfoCallback)),
+                                 .syncFence = std::move(fileDescriptor)};
+}
+
+}  // namespace
+
+PreparedModel::PreparedModel(nn::SharedPreparedModel preparedModel)
+    : kPreparedModel(std::move(preparedModel)) {
+    CHECK(kPreparedModel != nullptr);
+}
+
+ndk::ScopedAStatus PreparedModel::executeSynchronously(const Request& request, bool measureTiming,
+                                                       int64_t deadlineNs,
+                                                       int64_t loopTimeoutDurationNs,
+                                                       ExecutionResult* executionResult) {
+    auto result = adapter::executeSynchronously(*kPreparedModel, request, measureTiming, deadlineNs,
+                                                loopTimeoutDurationNs);
+    if (!result.has_value()) {
+        const auto& [message, code, _] = result.error();
+        const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE);
+        return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                static_cast<int32_t>(aidlCode), message.c_str());
+    }
+    *executionResult = std::move(result).value();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus PreparedModel::executeFenced(
+        const Request& request, const std::vector<ndk::ScopedFileDescriptor>& waitFor,
+        bool measureTiming, int64_t deadlineNs, int64_t loopTimeoutDurationNs, int64_t durationNs,
+        FencedExecutionResult* executionResult) {
+    auto result = adapter::executeFenced(*kPreparedModel, request, waitFor, measureTiming,
+                                         deadlineNs, loopTimeoutDurationNs, durationNs);
+    if (!result.has_value()) {
+        const auto& [message, code] = result.error();
+        const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE);
+        return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                static_cast<int32_t>(aidlCode), message.c_str());
+    }
+    *executionResult = std::move(result).value();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus PreparedModel::configureExecutionBurst(std::shared_ptr<IBurst>* burst) {
+    auto result = kPreparedModel->configureExecutionBurst();
+    if (!result.has_value()) {
+        const auto& [message, code] = result.error();
+        const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE);
+        return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                static_cast<int32_t>(aidlCode), message.c_str());
+    }
+    *burst = ndk::SharedRefBase::make<Burst>(std::move(result).value());
+    return ndk::ScopedAStatus::ok();
+}
+
+nn::SharedPreparedModel PreparedModel::getUnderlyingPreparedModel() const {
+    return kPreparedModel;
+}
+
+}  // namespace aidl::android::hardware::neuralnetworks::adapter
diff --git a/neuralnetworks/utils/adapter/Android.bp b/neuralnetworks/utils/adapter/hidl/Android.bp
similarity index 100%
rename from neuralnetworks/utils/adapter/Android.bp
rename to neuralnetworks/utils/adapter/hidl/Android.bp
diff --git a/neuralnetworks/utils/adapter/include/nnapi/hal/Adapter.h b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Adapter.h
similarity index 86%
rename from neuralnetworks/utils/adapter/include/nnapi/hal/Adapter.h
rename to neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Adapter.h
index da00a09..6fba4ab 100644
--- a/neuralnetworks/utils/adapter/include/nnapi/hal/Adapter.h
+++ b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Adapter.h
@@ -20,7 +20,6 @@
 #include <android/hardware/neuralnetworks/1.3/IDevice.h>
 #include <nnapi/IDevice.h>
 #include <nnapi/Types.h>
-#include <sys/types.h>
 #include <functional>
 #include <memory>
 
@@ -37,10 +36,12 @@
 /**
  * A type-erased executor which executes a task asynchronously.
  *
- * This executor is also provided with an Application ID (Android User ID) and an optional deadline
- * for when the caller expects is the upper bound for the amount of time to complete the task.
+ * This executor is also provided an optional deadline for when the caller expects is the upper
+ * bound for the amount of time to complete the task. If needed, the Executor can retrieve the
+ * Application ID (Android User ID) by calling IPCThreadState::self()->getCallingUid() in
+ * hwbinder/IPCThreadState.h.
  */
-using Executor = std::function<void(Task, uid_t, nn::OptionalTimePoint)>;
+using Executor = std::function<void(Task, nn::OptionalTimePoint)>;
 
 /**
  * Adapt an NNAPI canonical interface object to a HIDL NN HAL interface object.
diff --git a/neuralnetworks/utils/adapter/include/nnapi/hal/Buffer.h b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Buffer.h
similarity index 100%
rename from neuralnetworks/utils/adapter/include/nnapi/hal/Buffer.h
rename to neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Buffer.h
diff --git a/neuralnetworks/utils/adapter/include/nnapi/hal/Burst.h b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Burst.h
similarity index 100%
rename from neuralnetworks/utils/adapter/include/nnapi/hal/Burst.h
rename to neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Burst.h
diff --git a/neuralnetworks/utils/adapter/include/nnapi/hal/Device.h b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Device.h
similarity index 100%
rename from neuralnetworks/utils/adapter/include/nnapi/hal/Device.h
rename to neuralnetworks/utils/adapter/hidl/include/nnapi/hal/Device.h
diff --git a/neuralnetworks/utils/adapter/include/nnapi/hal/PreparedModel.h b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/PreparedModel.h
similarity index 98%
rename from neuralnetworks/utils/adapter/include/nnapi/hal/PreparedModel.h
rename to neuralnetworks/utils/adapter/hidl/include/nnapi/hal/PreparedModel.h
index 65763b8..9482b0d 100644
--- a/neuralnetworks/utils/adapter/include/nnapi/hal/PreparedModel.h
+++ b/neuralnetworks/utils/adapter/hidl/include/nnapi/hal/PreparedModel.h
@@ -39,7 +39,7 @@
 // Class that adapts nn::IPreparedModel to V1_3::IPreparedModel.
 class PreparedModel final : public V1_3::IPreparedModel {
   public:
-    PreparedModel(nn::SharedPreparedModel preparedModel, Executor executor, uid_t userId);
+    PreparedModel(nn::SharedPreparedModel preparedModel, Executor executor);
 
     Return<V1_0::ErrorStatus> execute(const V1_0::Request& request,
                                       const sp<V1_0::IExecutionCallback>& callback) override;
@@ -71,7 +71,6 @@
   private:
     const nn::SharedPreparedModel kPreparedModel;
     const Executor kExecutor;
-    const uid_t kUserId;
 };
 
 }  // namespace android::hardware::neuralnetworks::adapter
diff --git a/neuralnetworks/utils/adapter/src/Adapter.cpp b/neuralnetworks/utils/adapter/hidl/src/Adapter.cpp
similarity index 92%
rename from neuralnetworks/utils/adapter/src/Adapter.cpp
rename to neuralnetworks/utils/adapter/hidl/src/Adapter.cpp
index d6f53f0..782e815 100644
--- a/neuralnetworks/utils/adapter/src/Adapter.cpp
+++ b/neuralnetworks/utils/adapter/hidl/src/Adapter.cpp
@@ -21,7 +21,6 @@
 #include <android/hardware/neuralnetworks/1.3/IDevice.h>
 #include <nnapi/IDevice.h>
 #include <nnapi/Types.h>
-#include <sys/types.h>
 
 #include <functional>
 #include <memory>
@@ -37,7 +36,7 @@
 }
 
 sp<V1_3::IDevice> adapt(nn::SharedDevice device) {
-    Executor defaultExecutor = [](Task task, uid_t /*uid*/, nn::OptionalTimePoint /*deadline*/) {
+    Executor defaultExecutor = [](Task task, nn::OptionalTimePoint /*deadline*/) {
         std::thread(std::move(task)).detach();
     };
     return adapt(std::move(device), std::move(defaultExecutor));
diff --git a/neuralnetworks/utils/adapter/src/Buffer.cpp b/neuralnetworks/utils/adapter/hidl/src/Buffer.cpp
similarity index 100%
rename from neuralnetworks/utils/adapter/src/Buffer.cpp
rename to neuralnetworks/utils/adapter/hidl/src/Buffer.cpp
diff --git a/neuralnetworks/utils/adapter/src/Burst.cpp b/neuralnetworks/utils/adapter/hidl/src/Burst.cpp
similarity index 100%
rename from neuralnetworks/utils/adapter/src/Burst.cpp
rename to neuralnetworks/utils/adapter/hidl/src/Burst.cpp
diff --git a/neuralnetworks/utils/adapter/src/Device.cpp b/neuralnetworks/utils/adapter/hidl/src/Device.cpp
similarity index 92%
rename from neuralnetworks/utils/adapter/src/Device.cpp
rename to neuralnetworks/utils/adapter/hidl/src/Device.cpp
index 96142c3..4993a80 100644
--- a/neuralnetworks/utils/adapter/src/Device.cpp
+++ b/neuralnetworks/utils/adapter/hidl/src/Device.cpp
@@ -28,7 +28,6 @@
 #include <android/hardware/neuralnetworks/1.3/IDevice.h>
 #include <android/hardware/neuralnetworks/1.3/IPreparedModelCallback.h>
 #include <android/hardware/neuralnetworks/1.3/types.h>
-#include <hwbinder/IPCThreadState.h>
 #include <nnapi/IBuffer.h>
 #include <nnapi/IDevice.h>
 #include <nnapi/IPreparedModel.h>
@@ -43,7 +42,6 @@
 #include <nnapi/hal/1.2/Utils.h>
 #include <nnapi/hal/1.3/Conversions.h>
 #include <nnapi/hal/1.3/Utils.h>
-#include <sys/types.h>
 
 #include <memory>
 
@@ -64,12 +62,11 @@
 
 using PrepareModelResult = nn::GeneralResult<nn::SharedPreparedModel>;
 
-sp<PreparedModel> adaptPreparedModel(nn::SharedPreparedModel preparedModel, Executor executor,
-                                     uid_t userId) {
+sp<PreparedModel> adaptPreparedModel(nn::SharedPreparedModel preparedModel, Executor executor) {
     if (preparedModel == nullptr) {
         return nullptr;
     }
-    return sp<PreparedModel>::make(std::move(preparedModel), std::move(executor), userId);
+    return sp<PreparedModel>::make(std::move(preparedModel), std::move(executor));
 }
 
 void notify(V1_0::IPreparedModelCallback* callback, nn::ErrorStatus status,
@@ -108,15 +105,14 @@
 }
 
 template <typename CallbackType>
-void notify(CallbackType* callback, PrepareModelResult result, Executor executor, uid_t userId) {
+void notify(CallbackType* callback, PrepareModelResult result, Executor executor) {
     if (!result.has_value()) {
         const auto [message, status] = std::move(result).error();
         LOG(ERROR) << message;
         notify(callback, status, nullptr);
     } else {
         auto preparedModel = std::move(result).value();
-        auto hidlPreparedModel =
-                adaptPreparedModel(std::move(preparedModel), std::move(executor), userId);
+        auto hidlPreparedModel = adaptPreparedModel(std::move(preparedModel), std::move(executor));
         notify(callback, nn::ErrorStatus::NONE, std::move(hidlPreparedModel));
     }
 }
@@ -137,13 +133,12 @@
 
     auto nnModel = NN_TRY(convertInput(model));
 
-    const uid_t userId = hardware::IPCThreadState::self()->getCallingUid();
-    Task task = [device, nnModel = std::move(nnModel), userId, executor, callback] {
+    Task task = [device, nnModel = std::move(nnModel), executor, callback] {
         auto result = device->prepareModel(nnModel, nn::ExecutionPreference::DEFAULT,
                                            nn::Priority::DEFAULT, {}, {}, {}, {});
-        notify(callback.get(), std::move(result), executor, userId);
+        notify(callback.get(), std::move(result), executor);
     };
-    executor(std::move(task), userId, {});
+    executor(std::move(task), {});
 
     return {};
 }
@@ -159,13 +154,12 @@
     auto nnModel = NN_TRY(convertInput(model));
     const auto nnPreference = NN_TRY(convertInput(preference));
 
-    const uid_t userId = hardware::IPCThreadState::self()->getCallingUid();
-    Task task = [device, nnModel = std::move(nnModel), nnPreference, userId, executor, callback] {
+    Task task = [device, nnModel = std::move(nnModel), nnPreference, executor, callback] {
         auto result =
                 device->prepareModel(nnModel, nnPreference, nn::Priority::DEFAULT, {}, {}, {}, {});
-        notify(callback.get(), std::move(result), executor, userId);
+        notify(callback.get(), std::move(result), executor);
     };
-    executor(std::move(task), userId, {});
+    executor(std::move(task), {});
 
     return {};
 }
@@ -187,15 +181,14 @@
     auto nnDataCache = NN_TRY(convertInput(dataCache));
     const auto nnToken = nn::CacheToken(token);
 
-    const uid_t userId = hardware::IPCThreadState::self()->getCallingUid();
     Task task = [device, nnModel = std::move(nnModel), nnPreference,
                  nnModelCache = std::move(nnModelCache), nnDataCache = std::move(nnDataCache),
-                 nnToken, userId, executor, callback] {
+                 nnToken, executor, callback] {
         auto result = device->prepareModel(nnModel, nnPreference, nn::Priority::DEFAULT, {},
                                            nnModelCache, nnDataCache, nnToken);
-        notify(callback.get(), std::move(result), executor, userId);
+        notify(callback.get(), std::move(result), executor);
     };
-    executor(std::move(task), userId, {});
+    executor(std::move(task), {});
 
     return {};
 }
@@ -218,15 +211,14 @@
     auto nnDataCache = NN_TRY(convertInput(dataCache));
     const auto nnToken = nn::CacheToken(token);
 
-    const uid_t userId = hardware::IPCThreadState::self()->getCallingUid();
     Task task = [device, nnModel = std::move(nnModel), nnPreference, nnPriority, nnDeadline,
                  nnModelCache = std::move(nnModelCache), nnDataCache = std::move(nnDataCache),
-                 nnToken, userId, executor, callback] {
+                 nnToken, executor, callback] {
         auto result = device->prepareModel(nnModel, nnPreference, nnPriority, nnDeadline,
                                            nnModelCache, nnDataCache, nnToken);
-        notify(callback.get(), std::move(result), executor, userId);
+        notify(callback.get(), std::move(result), executor);
     };
-    executor(std::move(task), userId, nnDeadline);
+    executor(std::move(task), nnDeadline);
 
     return {};
 }
@@ -245,13 +237,12 @@
     auto nnDataCache = NN_TRY(convertInput(dataCache));
     const auto nnToken = nn::CacheToken(token);
 
-    const uid_t userId = hardware::IPCThreadState::self()->getCallingUid();
     Task task = [device, nnModelCache = std::move(nnModelCache),
-                 nnDataCache = std::move(nnDataCache), nnToken, userId, executor, callback] {
+                 nnDataCache = std::move(nnDataCache), nnToken, executor, callback] {
         auto result = device->prepareModelFromCache({}, nnModelCache, nnDataCache, nnToken);
-        notify(callback.get(), std::move(result), executor, userId);
+        notify(callback.get(), std::move(result), executor);
     };
-    executor(std::move(task), userId, {});
+    executor(std::move(task), {});
 
     return {};
 }
@@ -270,13 +261,12 @@
     auto nnDataCache = NN_TRY(convertInput(dataCache));
     const auto nnToken = nn::CacheToken(token);
 
-    const uid_t userId = hardware::IPCThreadState::self()->getCallingUid();
     auto task = [device, nnDeadline, nnModelCache = std::move(nnModelCache),
-                 nnDataCache = std::move(nnDataCache), nnToken, userId, executor, callback] {
+                 nnDataCache = std::move(nnDataCache), nnToken, executor, callback] {
         auto result = device->prepareModelFromCache(nnDeadline, nnModelCache, nnDataCache, nnToken);
-        notify(callback.get(), std::move(result), executor, userId);
+        notify(callback.get(), std::move(result), executor);
     };
-    executor(std::move(task), userId, nnDeadline);
+    executor(std::move(task), nnDeadline);
 
     return {};
 }
diff --git a/neuralnetworks/utils/adapter/src/PreparedModel.cpp b/neuralnetworks/utils/adapter/hidl/src/PreparedModel.cpp
similarity index 96%
rename from neuralnetworks/utils/adapter/src/PreparedModel.cpp
rename to neuralnetworks/utils/adapter/hidl/src/PreparedModel.cpp
index a14e782..71060d5 100644
--- a/neuralnetworks/utils/adapter/src/PreparedModel.cpp
+++ b/neuralnetworks/utils/adapter/hidl/src/PreparedModel.cpp
@@ -28,7 +28,6 @@
 #include <android/hardware/neuralnetworks/1.3/IFencedExecutionCallback.h>
 #include <android/hardware/neuralnetworks/1.3/IPreparedModel.h>
 #include <android/hardware/neuralnetworks/1.3/types.h>
-#include <hwbinder/IPCThreadState.h>
 #include <nnapi/IPreparedModel.h>
 #include <nnapi/TypeUtils.h>
 #include <nnapi/Types.h>
@@ -37,7 +36,6 @@
 #include <nnapi/hal/1.2/Utils.h>
 #include <nnapi/hal/1.3/Conversions.h>
 #include <nnapi/hal/1.3/Utils.h>
-#include <sys/types.h>
 
 #include <memory>
 #include <thread>
@@ -145,7 +143,7 @@
     }
 }
 
-nn::GeneralResult<void> execute(const nn::SharedPreparedModel& preparedModel, uid_t userId,
+nn::GeneralResult<void> execute(const nn::SharedPreparedModel& preparedModel,
                                 const Executor& executor, const V1_0::Request& request,
                                 const sp<V1_0::IExecutionCallback>& callback) {
     if (callback.get() == nullptr) {
@@ -164,12 +162,12 @@
         auto result = preparedModel->execute(nnRequest, nn::MeasureTiming::NO, {}, {});
         notify(callback.get(), std::move(result));
     };
-    executor(std::move(task), userId, {});
+    executor(std::move(task), {});
 
     return {};
 }
 
-nn::GeneralResult<void> execute_1_2(const nn::SharedPreparedModel& preparedModel, uid_t userId,
+nn::GeneralResult<void> execute_1_2(const nn::SharedPreparedModel& preparedModel,
                                     const Executor& executor, const V1_0::Request& request,
                                     V1_2::MeasureTiming measure,
                                     const sp<V1_2::IExecutionCallback>& callback) {
@@ -190,12 +188,12 @@
         auto result = preparedModel->execute(nnRequest, nnMeasure, {}, {});
         notify(callback.get(), std::move(result));
     };
-    executor(std::move(task), userId, {});
+    executor(std::move(task), {});
 
     return {};
 }
 
-nn::GeneralResult<void> execute_1_3(const nn::SharedPreparedModel& preparedModel, uid_t userId,
+nn::GeneralResult<void> execute_1_3(const nn::SharedPreparedModel& preparedModel,
                                     const Executor& executor, const V1_3::Request& request,
                                     V1_2::MeasureTiming measure,
                                     const V1_3::OptionalTimePoint& deadline,
@@ -222,7 +220,7 @@
                 preparedModel->execute(nnRequest, nnMeasure, nnDeadline, nnLoopTimeoutDuration);
         notify(callback.get(), std::move(result));
     };
-    executor(std::move(task), userId, nnDeadline);
+    executor(std::move(task), nnDeadline);
 
     return {};
 }
@@ -305,8 +303,8 @@
 
 }  // namespace
 
-PreparedModel::PreparedModel(nn::SharedPreparedModel preparedModel, Executor executor, uid_t userId)
-    : kPreparedModel(std::move(preparedModel)), kExecutor(std::move(executor)), kUserId(userId) {
+PreparedModel::PreparedModel(nn::SharedPreparedModel preparedModel, Executor executor)
+    : kPreparedModel(std::move(preparedModel)), kExecutor(std::move(executor)) {
     CHECK(kPreparedModel != nullptr);
     CHECK(kExecutor != nullptr);
 }
@@ -317,7 +315,7 @@
 
 Return<V1_0::ErrorStatus> PreparedModel::execute(const V1_0::Request& request,
                                                  const sp<V1_0::IExecutionCallback>& callback) {
-    auto result = adapter::execute(kPreparedModel, kUserId, kExecutor, request, callback);
+    auto result = adapter::execute(kPreparedModel, kExecutor, request, callback);
     if (!result.has_value()) {
         auto [message, code] = std::move(result).error();
         LOG(ERROR) << "adapter::PreparedModel::execute failed with " << code << ": " << message;
@@ -330,8 +328,7 @@
 Return<V1_0::ErrorStatus> PreparedModel::execute_1_2(const V1_0::Request& request,
                                                      V1_2::MeasureTiming measure,
                                                      const sp<V1_2::IExecutionCallback>& callback) {
-    auto result =
-            adapter::execute_1_2(kPreparedModel, kUserId, kExecutor, request, measure, callback);
+    auto result = adapter::execute_1_2(kPreparedModel, kExecutor, request, measure, callback);
     if (!result.has_value()) {
         auto [message, code] = std::move(result).error();
         LOG(ERROR) << "adapter::PreparedModel::execute_1_2 failed with " << code << ": " << message;
@@ -346,8 +343,8 @@
         const V1_3::OptionalTimePoint& deadline,
         const V1_3::OptionalTimeoutDuration& loopTimeoutDuration,
         const sp<V1_3::IExecutionCallback>& callback) {
-    auto result = adapter::execute_1_3(kPreparedModel, kUserId, kExecutor, request, measure,
-                                       deadline, loopTimeoutDuration, callback);
+    auto result = adapter::execute_1_3(kPreparedModel, kExecutor, request, measure, deadline,
+                                       loopTimeoutDuration, callback);
     if (!result.has_value()) {
         auto [message, code] = std::move(result).error();
         LOG(ERROR) << "adapter::PreparedModel::execute_1_3 failed with " << code << ": " << message;
diff --git a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
index d108951..152858f 100644
--- a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
@@ -1271,8 +1271,12 @@
     EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
 
     int32_t firstApiLevel = android::base::GetIntProperty<int32_t>("ro.product.first_api_level", 0);
+    int32_t boardApiLevel = android::base::GetIntProperty<int32_t>("ro.board.first_api_level", 0);
     // Allow devices shipping with Radio::1_5 and Android 11 to not support barring info.
-    if (firstApiLevel > 0 && firstApiLevel <= 30) {
+    // b/212384410 Some GRF targets lauched with S release but with vendor R release
+    // do not support getBarringInfo API. Allow these devices to not support barring info.
+    if ((firstApiLevel > 0 && firstApiLevel <= 30) ||
+        (boardApiLevel > 0 && boardApiLevel <= 30)) {
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_5->rspInfo.error,
                                      {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
         // Early exit for devices that don't support barring info.
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataProfileInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataProfileInfo.aidl
index 9df687c..c8efea0 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataProfileInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataProfileInfo.aidl
@@ -46,13 +46,14 @@
   int maxConns;
   int waitTime;
   boolean enabled;
-  android.hardware.radio.data.ApnTypes supportedApnTypesBitmap;
-  android.hardware.radio.RadioAccessFamily bearerBitmap;
+  int supportedApnTypesBitmap;
+  int bearerBitmap;
   int mtuV4;
   int mtuV6;
   boolean preferred;
   boolean persistent;
   boolean alwaysOn;
+  @nullable android.hardware.radio.data.TrafficDescriptor trafficDescriptor;
   const int ID_DEFAULT = 0;
   const int ID_TETHERED = 1;
   const int ID_IMS = 2;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioData.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioData.aidl
index a648675..dc6092a 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioData.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioData.aidl
@@ -46,7 +46,7 @@
   oneway void setDataThrottling(in int serial, in android.hardware.radio.data.DataThrottlingAction dataThrottlingAction, in long completionDurationMillis);
   oneway void setInitialAttachApn(in int serial, in android.hardware.radio.data.DataProfileInfo dataProfileInfo);
   oneway void setResponseFunctions(in android.hardware.radio.data.IRadioDataResponse radioDataResponse, in android.hardware.radio.data.IRadioDataIndication radioDataIndication);
-  oneway void setupDataCall(in int serial, in android.hardware.radio.AccessNetwork accessNetwork, in android.hardware.radio.data.DataProfileInfo dataProfileInfo, in boolean roamingAllowed, in android.hardware.radio.data.DataRequestReason reason, in android.hardware.radio.data.LinkAddress[] addresses, in String[] dnses, in int pduSessionId, in @nullable android.hardware.radio.data.SliceInfo sliceInfo, in @nullable android.hardware.radio.data.TrafficDescriptor trafficDescriptor, in boolean matchAllRuleAllowed);
+  oneway void setupDataCall(in int serial, in android.hardware.radio.AccessNetwork accessNetwork, in android.hardware.radio.data.DataProfileInfo dataProfileInfo, in boolean roamingAllowed, in android.hardware.radio.data.DataRequestReason reason, in android.hardware.radio.data.LinkAddress[] addresses, in String[] dnses, in int pduSessionId, in @nullable android.hardware.radio.data.SliceInfo sliceInfo, in boolean matchAllRuleAllowed);
   oneway void startHandover(in int serial, in int callId);
   oneway void startKeepalive(in int serial, in android.hardware.radio.data.KeepaliveRequest keepalive);
   oneway void stopKeepalive(in int serial, in int sessionHandle);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioDataIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioDataIndication.aidl
index e496c7b..0ffa1f7 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioDataIndication.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioDataIndication.aidl
@@ -37,5 +37,6 @@
   oneway void dataCallListChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.data.SetupDataCallResult[] dcList);
   oneway void keepaliveStatus(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.data.KeepaliveStatus status);
   oneway void pcoData(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.data.PcoDataInfo pco);
-  oneway void unthrottleApn(in android.hardware.radio.RadioIndicationType type, in String apn);
+  oneway void unthrottleApn(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.data.DataProfileInfo dataProfileInfo);
+  oneway void slicingConfigChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.data.SlicingConfig slicingConfig);
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/RadioCapability.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/RadioCapability.aidl
index d5716ac..5aaf5a7 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/RadioCapability.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/RadioCapability.aidl
@@ -36,7 +36,7 @@
 parcelable RadioCapability {
   int session;
   int phase;
-  android.hardware.radio.RadioAccessFamily raf;
+  int raf;
   String logicalModemUuid;
   int status;
   const int PHASE_CONFIGURED = 0;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl
index 16433be..2b70e45 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl
@@ -50,12 +50,12 @@
   oneway void getVoiceRegistrationState(in int serial);
   oneway void isNrDualConnectivityEnabled(in int serial);
   oneway void responseAcknowledgement();
-  oneway void setAllowedNetworkTypesBitmap(in int serial, in android.hardware.radio.RadioAccessFamily networkTypeBitmap);
+  oneway void setAllowedNetworkTypesBitmap(in int serial, in int networkTypeBitmap);
   oneway void setBandMode(in int serial, in android.hardware.radio.network.RadioBandMode mode);
   oneway void setBarringPassword(in int serial, in String facility, in String oldPassword, in String newPassword);
   oneway void setCdmaRoamingPreference(in int serial, in android.hardware.radio.network.CdmaRoamingType type);
   oneway void setCellInfoListRate(in int serial, in int rate);
-  oneway void setIndicationFilter(in int serial, in android.hardware.radio.network.IndicationFilter indicationFilter);
+  oneway void setIndicationFilter(in int serial, in int indicationFilter);
   oneway void setLinkCapacityReportingCriteria(in int serial, in int hysteresisMs, in int hysteresisDlKbps, in int hysteresisUlKbps, in int[] thresholdsDownlinkKbps, in int[] thresholdsUplinkKbps, in android.hardware.radio.AccessNetwork accessNetwork);
   oneway void setLocationUpdates(in int serial, in boolean enable);
   oneway void setNetworkSelectionModeAutomatic(in int serial);
@@ -68,4 +68,6 @@
   oneway void startNetworkScan(in int serial, in android.hardware.radio.network.NetworkScanRequest request);
   oneway void stopNetworkScan(in int serial);
   oneway void supplyNetworkDepersonalization(in int serial, in String netPin);
+  oneway void setUsageSetting(in int serial, in android.hardware.radio.network.UsageSetting usageSetting);
+  oneway void getUsageSetting(in int serial);
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkIndication.aidl
index d135a69..bd03c51 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkIndication.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkIndication.aidl
@@ -44,7 +44,7 @@
   oneway void networkScanResult(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.NetworkScanResult result);
   oneway void networkStateChanged(in android.hardware.radio.RadioIndicationType type);
   oneway void nitzTimeReceived(in android.hardware.radio.RadioIndicationType type, in String nitzTime, in long receivedTimeMs, in long ageMs);
-  oneway void registrationFailed(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.CellIdentity cellIdentity, in String chosenPlmn, in android.hardware.radio.network.Domain domain, in int causeCode, in int additionalCauseCode);
+  oneway void registrationFailed(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.CellIdentity cellIdentity, in String chosenPlmn, in int domain, in int causeCode, in int additionalCauseCode);
   oneway void restrictedStateChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.PhoneRestrictedState state);
   oneway void suppSvcNotify(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.SuppSvcNotification suppSvc);
   oneway void voiceRadioTechChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.RadioTechnology rat);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl
index ff95396..5f6c736 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl
@@ -35,7 +35,7 @@
 @VintfStability
 interface IRadioNetworkResponse {
   oneway void acknowledgeRequest(in int serial);
-  oneway void getAllowedNetworkTypesBitmapResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.RadioAccessFamily networkTypeBitmap);
+  oneway void getAllowedNetworkTypesBitmapResponse(in android.hardware.radio.RadioResponseInfo info, in int networkTypeBitmap);
   oneway void getAvailableBandModesResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.RadioBandMode[] bandModes);
   oneway void getAvailableNetworksResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.OperatorInfo[] networkInfos);
   oneway void getBarringInfoResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.CellIdentity cellIdentity, in android.hardware.radio.network.BarringInfo[] barringInfos);
@@ -67,4 +67,6 @@
   oneway void startNetworkScanResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void stopNetworkScanResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void supplyNetworkDepersonalizationResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries);
+  oneway void setUsageSettingResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void getUsageSettingResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.UsageSetting usageSetting);
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/UsageSetting.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/UsageSetting.aidl
new file mode 100644
index 0000000..7fdf831
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/UsageSetting.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 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.radio.network;
+@Backing(type="int") @VintfStability
+enum UsageSetting {
+  VOICE_CENTRIC = 1,
+  DATA_CENTRIC = 2,
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyNumber.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyNumber.aidl
index 4f415ee..39bcf1a 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyNumber.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyNumber.aidl
@@ -37,7 +37,7 @@
   String number;
   String mcc;
   String mnc;
-  android.hardware.radio.voice.EmergencyServiceCategory categories;
+  int categories;
   String[] urns;
   int sources;
   const int SOURCE_NETWORK_SIGNALING = 1;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoice.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoice.aidl
index 68c82fa..34d155a 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoice.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoice.aidl
@@ -37,7 +37,7 @@
   oneway void acceptCall(in int serial);
   oneway void conference(in int serial);
   oneway void dial(in int serial, in android.hardware.radio.voice.Dial dialInfo);
-  oneway void emergencyDial(in int serial, in android.hardware.radio.voice.Dial dialInfo, in android.hardware.radio.voice.EmergencyServiceCategory categories, in String[] urns, in android.hardware.radio.voice.EmergencyCallRouting routing, in boolean hasKnownUserIntentEmergency, in boolean isTesting);
+  oneway void emergencyDial(in int serial, in android.hardware.radio.voice.Dial dialInfo, in int categories, in String[] urns, in android.hardware.radio.voice.EmergencyCallRouting routing, in boolean hasKnownUserIntentEmergency, in boolean isTesting);
   oneway void exitEmergencyCallbackMode(in int serial);
   oneway void explicitCallTransfer(in int serial);
   oneway void getCallForwardStatus(in int serial, in android.hardware.radio.voice.CallForwardInfo callInfo);
diff --git a/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl b/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
index a1c3c27..b5cf633 100644
--- a/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
+++ b/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
@@ -42,7 +42,13 @@
      */
     String eid;
     /**
-     * PortInfo contains the ICCID, logical slot ID, and port state
+     * PortInfo contains the ICCID, logical slot ID, and port state.
+     * Cardstate has no relationship with whether the slot is active or inactive. Should always
+     * report up at least 1 port otherwise the logicalSlotIndex and portActive info will be lost.
+     * For example, the pSIM can be removed, but the slot can still be active. In that case, the
+     * SIM_STATUS reported for the corresponding logical stack will show CARDSTATE_ABSENT.
+     * Similarly, even if there is no profile enabled on the eSIM, that port can still be the
+     * active port in the slot mapping.
      */
     SimPortInfo[] portInfo;
 }
diff --git a/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl b/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl
index a14963f..7360202 100644
--- a/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl
+++ b/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl
@@ -20,6 +20,7 @@
 import android.hardware.radio.data.ApnAuthType;
 import android.hardware.radio.data.ApnTypes;
 import android.hardware.radio.data.PdpProtocolType;
+import android.hardware.radio.data.TrafficDescriptor;
 
 @VintfStability
 parcelable DataProfileInfo {
@@ -92,11 +93,11 @@
     /**
      * Supported APN types bitmap. See ApnTypes for the value of each bit.
      */
-    ApnTypes supportedApnTypesBitmap;
+    int supportedApnTypesBitmap;
     /**
      * The bearer bitmap. See RadioAccessFamily for the value of each bit.
      */
-    RadioAccessFamily bearerBitmap;
+    int bearerBitmap;
     /**
      * Maximum transmission unit (MTU) size in bytes for IPv4.
      */
@@ -122,4 +123,12 @@
      * See 3GPP TS 23.501 section 5.6.13 for the details.
      */
     boolean alwaysOn;
+    /**
+     * TrafficDescriptor for which data connection needs to be established.
+     * It is used for URSP traffic matching as described in TS 24.526 Section 4.2.2.
+     * It includes an optional DNN which, if present, must be used for traffic matching --
+     * it does not specify the end point to be used for the data call. The end point is specified by
+     * apn; apn must be used as the end point if one is not specified through URSP rules.
+     */
+    @nullable TrafficDescriptor trafficDescriptor;
 }
diff --git a/radio/aidl/android/hardware/radio/data/IRadioData.aidl b/radio/aidl/android/hardware/radio/data/IRadioData.aidl
index 9f5ba4c..54a045c 100644
--- a/radio/aidl/android/hardware/radio/data/IRadioData.aidl
+++ b/radio/aidl/android/hardware/radio/data/IRadioData.aidl
@@ -219,12 +219,6 @@
      *        EPDG to 5G. It is valid only when accessNetwork is AccessNetwork:NGRAN. If the slice
      *        passed from EPDG is rejected, then the data failure cause must be
      *        DataCallFailCause:SLICE_REJECTED.
-     * @param trafficDescriptor TrafficDescriptor for which data connection needs to be established.
-     *        It is used for URSP traffic matching as described in TS 24.526 Section 4.2.2.
-     *        It includes an optional DNN which, if present, must be used for traffic matching --
-     *        it does not specify the end point to be used for the data call. The end point is
-     *        specified by DataProfileInfo.apn; DataProfileInfo.apn must be used as the end point if
-     *        one is not specified through URSP rules.
      * @param matchAllRuleAllowed bool to indicate if using default match-all URSP rule for this
      *        request is allowed. If false, this request must not use the match-all URSP rule and if
      *        a non-match-all rule is not found (or if URSP rules are not available) it should
@@ -238,7 +232,6 @@
             in DataProfileInfo dataProfileInfo, in boolean roamingAllowed,
             in DataRequestReason reason, in LinkAddress[] addresses, in String[] dnses,
             in int pduSessionId, in @nullable SliceInfo sliceInfo,
-            in @nullable TrafficDescriptor trafficDescriptor,
             in boolean matchAllRuleAllowed);
 
     /**
diff --git a/radio/aidl/android/hardware/radio/data/IRadioDataIndication.aidl b/radio/aidl/android/hardware/radio/data/IRadioDataIndication.aidl
index 8e73ee3..938c695 100644
--- a/radio/aidl/android/hardware/radio/data/IRadioDataIndication.aidl
+++ b/radio/aidl/android/hardware/radio/data/IRadioDataIndication.aidl
@@ -17,9 +17,11 @@
 package android.hardware.radio.data;
 
 import android.hardware.radio.RadioIndicationType;
+import android.hardware.radio.data.DataProfileInfo;
 import android.hardware.radio.data.KeepaliveStatus;
 import android.hardware.radio.data.PcoDataInfo;
 import android.hardware.radio.data.SetupDataCallResult;
+import android.hardware.radio.data.SlicingConfig;
 
 /**
  * Interface declaring unsolicited radio indications for data APIs.
@@ -68,7 +70,20 @@
      * is sent, AOSP will no longer throttle calls to IRadioData.SetupDataCall for the given APN.
      *
      * @param type Type of radio indication
-     * @param apn Apn to unthrottle
+     * @param dataProfileInfo Data profile info.
      */
-    void unthrottleApn(in RadioIndicationType type, in String apn);
+    void unthrottleApn(in RadioIndicationType type, in DataProfileInfo dataProfileInfo);
+
+    /**
+     * Indicates the current slicing configuration including URSP rules and NSSAIs
+     * (configured, allowed and rejected). URSP stands for UE route selection policy and is defined
+     * in 3GPP TS 24.526 Section 4.2. An NSSAI is a collection of network slices. Each network slice
+     * is identified by an S-NSSAI and is represented by the struct SliceInfo. NSSAI and S-NSSAI
+     * are defined in 3GPP TS 24.501.
+     *
+     * @param type Type of radio indication
+     * @param slicingConfig Current slicing configuration
+     *
+     */
+    void slicingConfigChanged(in RadioIndicationType type, in SlicingConfig slicingConfig);
 }
diff --git a/radio/aidl/android/hardware/radio/modem/RadioCapability.aidl b/radio/aidl/android/hardware/radio/modem/RadioCapability.aidl
index b7b8ef3..9bd5f21 100644
--- a/radio/aidl/android/hardware/radio/modem/RadioCapability.aidl
+++ b/radio/aidl/android/hardware/radio/modem/RadioCapability.aidl
@@ -71,7 +71,7 @@
     /**
      * 32-bit bitmap of RadioAccessFamily.
      */
-    RadioAccessFamily raf;
+    int raf;
     /**
      * A UUID typically "com.xxxx.lmX" where X is the logical modem.
      * RadioConst:MAX_UUID_LENGTH is the max length.
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
index 1081a75..7a22a9a 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
@@ -27,6 +27,7 @@
 import android.hardware.radio.network.RadioAccessSpecifier;
 import android.hardware.radio.network.RadioBandMode;
 import android.hardware.radio.network.SignalThresholdInfo;
+import android.hardware.radio.network.UsageSetting;
 
 /**
  * This interface is used by telephony and telecom to talk to cellular radio for network APIs.
@@ -194,7 +195,7 @@
      *
      * Response function is IRadioNetworkResponse.setAllowedNetworkTypesBitmapResponse()
      */
-    void setAllowedNetworkTypesBitmap(in int serial, in RadioAccessFamily networkTypeBitmap);
+    void setAllowedNetworkTypesBitmap(in int serial, in int networkTypeBitmap);
 
     /**
      * Assign a specified band for RF configuration.
@@ -252,7 +253,7 @@
      *
      * Response function is IRadioNetworkResponse.setIndicationFilterResponse()
      */
-    void setIndicationFilter(in int serial, in IndicationFilter indicationFilter);
+    void setIndicationFilter(in int serial, in int indicationFilter);
 
     /**
      * Sets the link capacity reporting criteria. The resulting reporting criteria are the AND of
@@ -416,4 +417,25 @@
      * Response function is IRadioNetworkResponse.supplyNetworkDepersonalizationResponse()
      */
     void supplyNetworkDepersonalization(in int serial, in String netPin);
+
+    /**
+     * Set the UE usage setting for data/voice centric usage.
+     *
+     * <p>Sets the usage setting in accordance with 3gpp 24.301 sec 4.3 and 3gpp 24.501 sec 4.3.
+     * <p>This value must be independently preserved for each SIM; (setting the value is not a
+     * "global" override).
+     *
+     * @param serial Serial number of request.
+     * @param usageSetting the usage setting for the current SIM.
+     */
+    oneway void setUsageSetting(in int serial, in UsageSetting usageSetting);
+
+    /**
+     * Get the UE usage setting for data/voice centric usage.
+     *
+     * <p>Gets the usage setting in accordance with 3gpp 24.301 sec 4.3 and 3gpp 24.501 sec 4.3.
+     *
+     * @param serial Serial number of request.
+     */
+    oneway void getUsageSetting(in int serial);
 }
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl
index ba7610d..6863ac3 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl
@@ -136,8 +136,8 @@
      *        include the time spend in sleep / low power states. If it can not be guaranteed,
      *        there must not be any caching done at the modem and should fill in 0 for ageMs
      */
-    void nitzTimeReceived(in RadioIndicationType type, in String nitzTime,
-            in long receivedTimeMs, in long ageMs);
+    void nitzTimeReceived(
+            in RadioIndicationType type, in String nitzTime, in long receivedTimeMs, in long ageMs);
 
     /**
      * Report that Registration or a Location/Routing/Tracking Area update has failed.
@@ -165,7 +165,7 @@
      *        MAX_INT if this value is unused.
      */
     void registrationFailed(in RadioIndicationType type, in CellIdentity cellIdentity,
-            in String chosenPlmn, in Domain domain, in int causeCode, in int additionalCauseCode);
+            in String chosenPlmn, in int domain, in int causeCode, in int additionalCauseCode);
 
     /**
      * Indicates a restricted state change (eg, for Domain Specific Access Control).
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
index 429b5a8..e650321 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
@@ -31,6 +31,7 @@
 import android.hardware.radio.network.RadioBandMode;
 import android.hardware.radio.network.RegStateResult;
 import android.hardware.radio.network.SignalStrength;
+import android.hardware.radio.network.UsageSetting;
 
 /**
  * Interface declaring response functions to solicited radio requests for network APIs.
@@ -61,8 +62,7 @@
      *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      */
-    void getAllowedNetworkTypesBitmapResponse(
-            in RadioResponseInfo info, in RadioAccessFamily networkTypeBitmap);
+    void getAllowedNetworkTypesBitmapResponse(in RadioResponseInfo info, in int networkTypeBitmap);
 
     /**
      * @param info Response info struct containing response type, serial no. and error
@@ -549,4 +549,30 @@
      *   RadioError:SIM_ABSENT
      */
     void supplyNetworkDepersonalizationResponse(in RadioResponseInfo info, in int remainingRetries);
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error.
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INVALID_STATE
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:SIM_ABSENT
+     */
+    oneway void setUsageSettingResponse(in RadioResponseInfo info);
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error.
+     * @param usageSetting the usage setting for the current SIM.
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INVALID_STATE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:SIM_ABSENT
+     */
+    oneway void getUsageSettingResponse(in RadioResponseInfo info, in UsageSetting usageSetting);
 }
diff --git a/radio/aidl/android/hardware/radio/network/UsageSetting.aidl b/radio/aidl/android/hardware/radio/network/UsageSetting.aidl
new file mode 100644
index 0000000..ba8fe93
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/network/UsageSetting.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 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.radio.network;
+
+/**
+ * Cellular usage setting with values according to 3gpp 24.301 sec 4.3 and 3gpp 24.501 sec 4.3.
+ *
+ * <p>Also refer to "UE's usage setting" as defined in 3gpp 24.301 section 3.1 and 3gpp 23.221
+ * Annex A.
+ */
+@VintfStability
+@Backing(type="int")
+enum UsageSetting {
+    /**
+     * UE operates in voice-centric mode. Generally speaking, in this mode of operation, the UE
+     * will not remain camped on a cell or attached to a network unless that cell/network provides
+     * voice service.
+     */
+    VOICE_CENTRIC = 1,
+
+    /**
+     * UE operates in data-centric mode. Generally speaking, in this mode of operation, the UE
+     * will not reselect away from a cell/network that only provides data services.
+     */
+    DATA_CENTRIC = 2,
+}
diff --git a/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl b/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl
index c731caf..7923b14 100644
--- a/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl
+++ b/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl
@@ -205,6 +205,12 @@
      * Open a new logical channel and select the given application. This command
      * reflects TS 27.007 "open logical channel" operation (+CCHO).
      *
+     * For MEP-A(Multiple enabled profile), only dedicated port 0 is ISDR selectable.
+     * e.g., Port0 - for ISDR access and Port1/Port2 - the currently active ports/subscriptions.
+     * Port 0 should be transparent to AP and iccLogicalChannel API should remain the same.
+     * Even if the ISDR request comes over port1 or port2, Modem would just internally convert the
+     * portID to port0 and add the real port index as the payload of MANAGE_CHANNEL command.
+     *
      * @param serial Serial number of request.
      * @param aid AID value, See ETSI 102.221 and 101.220.
      * @param p2 P2 value, described in ISO 7816-4. Ignore if equal to RadioConst:P2_CONSTANT_NO_P2
diff --git a/radio/aidl/android/hardware/radio/voice/EmergencyNumber.aidl b/radio/aidl/android/hardware/radio/voice/EmergencyNumber.aidl
index aa4dde2..ddc5d76 100644
--- a/radio/aidl/android/hardware/radio/voice/EmergencyNumber.aidl
+++ b/radio/aidl/android/hardware/radio/voice/EmergencyNumber.aidl
@@ -78,7 +78,7 @@
      * The bitfield of EmergencyServiceCategory(s). See EmergencyServiceCategory for the value of
      * each bit.
      */
-    EmergencyServiceCategory categories;
+    int categories;
     /**
      * The list of emergency Uniform Resource Names (URN).
      */
diff --git a/radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl b/radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl
index a012be4..b25e63d 100644
--- a/radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl
+++ b/radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl
@@ -117,9 +117,9 @@
      *
      * Response function is IRadioVoiceResponse.emergencyDialResponse()
      */
-    void emergencyDial(in int serial, in Dial dialInfo, in EmergencyServiceCategory categories,
-            in String[] urns, in EmergencyCallRouting routing,
-            in boolean hasKnownUserIntentEmergency, in boolean isTesting);
+    void emergencyDial(in int serial, in Dial dialInfo, in int categories, in String[] urns,
+            in EmergencyCallRouting routing, in boolean hasKnownUserIntentEmergency,
+            in boolean isTesting);
 
     /**
      * Request the radio's system selection module to exit emergency callback mode. Radio must not
diff --git a/radio/aidl/compat/libradiocompat/Android.bp b/radio/aidl/compat/libradiocompat/Android.bp
index 43d9378..487d91b 100644
--- a/radio/aidl/compat/libradiocompat/Android.bp
+++ b/radio/aidl/compat/libradiocompat/Android.bp
@@ -28,7 +28,6 @@
     cflags: [
         "-Wall",
         "-Wextra",
-        //"-Wold-style-cast",  // TODO(b/203699028) enable after aosp/1900880 gets merged
         "-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION",
     ],
     shared_libs: [
@@ -56,7 +55,10 @@
         "libutils",
     ],
     srcs: [
+        "CallbackManager.cpp",
+        "DriverContext.cpp",
         "RadioCompatBase.cpp",
+        "RadioIndication.cpp",
         "RadioResponse.cpp",
         "commonStructs.cpp",
         "config/RadioConfig.cpp",
diff --git a/radio/aidl/compat/libradiocompat/CallbackManager.cpp b/radio/aidl/compat/libradiocompat/CallbackManager.cpp
new file mode 100644
index 0000000..c2eaed1
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/CallbackManager.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2021 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 <libradiocompat/CallbackManager.h>
+
+#include <android-base/logging.h>
+
+using namespace std::literals::chrono_literals;
+
+namespace android::hardware::radio::compat {
+
+/**
+ * How much setter thread will wait with setting response functions after the last
+ * setResponseFunctions call from the framework. Subsequent calls from the framework reset the
+ * clock, so this number should be larger than the longest time between setResponseFunctions calls
+ * from the framework.
+ *
+ * Real world measurements with Cuttlefish give <10ms delay between Modem and Data and <2ms delays
+ * between all others.
+ */
+static constexpr auto kDelayedSetterDelay = 100ms;
+
+CallbackManager::CallbackManager(std::shared_ptr<DriverContext> context, sp<V1_5::IRadio> hidlHal)
+    : mHidlHal(hidlHal),
+      mRadioResponse(sp<compat::RadioResponse>::make(context)),
+      mRadioIndication(sp<compat::RadioIndication>::make(context)),
+      mDelayedSetterThread(&CallbackManager::delayedSetterThread, this) {}
+
+CallbackManager::~CallbackManager() {
+    {
+        std::unique_lock<std::mutex> lock(mDelayedSetterGuard);
+        mDelayedSetterDeadline = std::nullopt;
+        mDestroy = true;
+        mDelayedSetterCv.notify_all();
+    }
+    mDelayedSetterThread.join();
+}
+
+RadioResponse& CallbackManager::response() const {
+    return *mRadioResponse;
+}
+
+void CallbackManager::setResponseFunctionsDelayed() {
+    std::unique_lock<std::mutex> lock(mDelayedSetterGuard);
+    mDelayedSetterDeadline = std::chrono::steady_clock::now() + kDelayedSetterDelay;
+    mDelayedSetterCv.notify_all();
+}
+
+void CallbackManager::delayedSetterThread() {
+    while (!mDestroy) {
+        std::unique_lock<std::mutex> lock(mDelayedSetterGuard);
+        auto deadline = mDelayedSetterDeadline;
+
+        // not waiting to set response functions
+        if (!deadline) {
+            mDelayedSetterCv.wait(lock);
+            continue;
+        }
+
+        // waiting to set response functions, but not yet
+        if (*deadline > std::chrono::steady_clock::now()) {
+            mDelayedSetterCv.wait_until(lock, *deadline);
+            continue;
+        }
+
+        mHidlHal->setResponseFunctions(mRadioResponse, mRadioIndication).assertOk();
+        mDelayedSetterDeadline = std::nullopt;
+    }
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/DriverContext.cpp b/radio/aidl/compat/libradiocompat/DriverContext.cpp
new file mode 100644
index 0000000..a07173e
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/DriverContext.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2021 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 <libradiocompat/DriverContext.h>
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio;
+
+void DriverContext::addDataProfile(const aidl::data::DataProfileInfo& profile) {
+    mDataProfiles[profile.apn] = profile;
+}
+
+aidl::data::DataProfileInfo DriverContext::getDataProfile(const std::string& apn) {
+    const auto it = mDataProfiles.find(apn);
+    if (it != mDataProfiles.end()) return it->second;
+
+    // if not found in cache, return a made up default
+    return {
+            .apn = apn,
+    };
+}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/RadioCompatBase.cpp b/radio/aidl/compat/libradiocompat/RadioCompatBase.cpp
index a9eac68..2a2d7a3 100644
--- a/radio/aidl/compat/libradiocompat/RadioCompatBase.cpp
+++ b/radio/aidl/compat/libradiocompat/RadioCompatBase.cpp
@@ -20,16 +20,11 @@
 
 namespace android::hardware::radio::compat {
 
-RadioCompatBase::RadioCompatBase(sp<V1_5::IRadio> hidlHal, sp<RadioResponse> radioResponse,
-                                 sp<RadioIndication> radioIndication)
-    : mHal1_5(hidlHal),
+RadioCompatBase::RadioCompatBase(std::shared_ptr<DriverContext> context, sp<V1_5::IRadio> hidlHal,
+                                 std::shared_ptr<CallbackManager> cbMgr)
+    : mContext(context),
+      mHal1_5(hidlHal),
       mHal1_6(V1_6::IRadio::castFrom(hidlHal)),
-      mRadioResponse(radioResponse),
-      mRadioIndication(radioIndication) {}
-
-V1_6::IRadioResponse& RadioCompatBase::respond() {
-    CHECK(mRadioResponse) << "This shouldn't happen (response functions are passed in constructor)";
-    return *mRadioResponse;
-}
+      mCallbackManager(cbMgr) {}
 
 }  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/RadioIndication.cpp b/radio/aidl/compat/libradiocompat/RadioIndication.cpp
new file mode 100644
index 0000000..30ef6a0
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/RadioIndication.cpp
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2021 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 <libradiocompat/RadioIndication.h>
+
+namespace android::hardware::radio::compat {
+
+RadioIndication::RadioIndication(std::shared_ptr<DriverContext> context) : mContext(context) {}
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/RadioResponse.cpp b/radio/aidl/compat/libradiocompat/RadioResponse.cpp
index 35b0ac1..dab70cc 100644
--- a/radio/aidl/compat/libradiocompat/RadioResponse.cpp
+++ b/radio/aidl/compat/libradiocompat/RadioResponse.cpp
@@ -22,15 +22,20 @@
 
 namespace android::hardware::radio::compat {
 
+RadioResponse::RadioResponse(std::shared_ptr<DriverContext> context) : mContext(context) {}
+
 Return<void> RadioResponse::acknowledgeRequest(int32_t serial) {
     LOG_CALL << serial;
-    // TODO(b/203699028): send to correct requestor or confirm if spam is not a problem
-    if (mDataCb) mDataCb->acknowledgeRequest(serial);
-    if (mMessagingCb) mMessagingCb->acknowledgeRequest(serial);
-    if (mModemCb) mModemCb->acknowledgeRequest(serial);
-    if (mNetworkCb) mNetworkCb->acknowledgeRequest(serial);
-    if (mSimCb) mSimCb->acknowledgeRequest(serial);
-    if (mVoiceCb) mVoiceCb->acknowledgeRequest(serial);
+    /* We send ACKs to all callbacks instead of the one requested it to make implementation simpler.
+     * If it turns out to be a problem, we would have to track where serials come from and make sure
+     * this tracking data (e.g. a map) doesn't grow indefinitely.
+     */
+    if (mDataCb) mDataCb.get()->acknowledgeRequest(serial);
+    if (mMessagingCb) mMessagingCb.get()->acknowledgeRequest(serial);
+    if (mModemCb) mModemCb.get()->acknowledgeRequest(serial);
+    if (mNetworkCb) mNetworkCb.get()->acknowledgeRequest(serial);
+    if (mSimCb) mSimCb.get()->acknowledgeRequest(serial);
+    if (mVoiceCb) mVoiceCb.get()->acknowledgeRequest(serial);
     return {};
 }
 
diff --git a/radio/aidl/compat/libradiocompat/commonStructs.cpp b/radio/aidl/compat/libradiocompat/commonStructs.cpp
index c25768d..6e4c873 100644
--- a/radio/aidl/compat/libradiocompat/commonStructs.cpp
+++ b/radio/aidl/compat/libradiocompat/commonStructs.cpp
@@ -20,11 +20,11 @@
 
 namespace aidl = ::aidl::android::hardware::radio;
 
-V1_6::RadioResponseInfo notSupported(int32_t serial) {
+aidl::RadioResponseInfo notSupported(int32_t serial) {
     return {
-            .type = V1_0::RadioResponseType::SOLICITED,
+            .type = aidl::RadioResponseType::SOLICITED,
             .serial = serial,
-            .error = V1_6::RadioError::REQUEST_NOT_SUPPORTED,
+            .error = aidl::RadioError::REQUEST_NOT_SUPPORTED,
     };
 }
 
diff --git a/radio/aidl/compat/libradiocompat/commonStructs.h b/radio/aidl/compat/libradiocompat/commonStructs.h
index b859916..a4a4869 100644
--- a/radio/aidl/compat/libradiocompat/commonStructs.h
+++ b/radio/aidl/compat/libradiocompat/commonStructs.h
@@ -21,7 +21,7 @@
 
 namespace android::hardware::radio::compat {
 
-V1_6::RadioResponseInfo notSupported(int32_t serial);
+aidl::android::hardware::radio::RadioResponseInfo notSupported(int32_t serial);
 
 std::string toAidl(const hidl_string& str);
 hidl_string toHidl(const std::string& str);
diff --git a/radio/aidl/compat/libradiocompat/config/RadioConfig.cpp b/radio/aidl/compat/libradiocompat/config/RadioConfig.cpp
index d0d6f7a..b450418 100644
--- a/radio/aidl/compat/libradiocompat/config/RadioConfig.cpp
+++ b/radio/aidl/compat/libradiocompat/config/RadioConfig.cpp
@@ -16,12 +16,12 @@
 
 #include <libradiocompat/RadioConfig.h>
 
-#include "RadioConfigIndication.h"
-#include "RadioConfigResponse.h"
 #include "commonStructs.h"
 #include "debug.h"
 #include "structs.h"
 
+#include "collections.h"
+
 #define RADIO_MODULE "Config"
 
 namespace android::hardware::radio::compat {
@@ -31,11 +31,13 @@
 constexpr auto ok = &ScopedAStatus::ok;
 
 RadioConfig::RadioConfig(sp<config::V1_1::IRadioConfig> hidlHal)
-    : mHal1_1(hidlHal), mHal1_3(config::V1_3::IRadioConfig::castFrom(hidlHal)) {}
+    : mHal1_1(hidlHal),
+      mHal1_3(config::V1_3::IRadioConfig::castFrom(hidlHal)),
+      mRadioConfigResponse(sp<RadioConfigResponse>::make()),
+      mRadioConfigIndication(sp<RadioConfigIndication>::make()) {}
 
-config::V1_3::IRadioConfigResponse& RadioConfig::respond() {
-    CHECK(mRadioConfigResponse) << "setResponseFunctions was not called yet";
-    return *mRadioConfigResponse;
+std::shared_ptr<aidl::IRadioConfigResponse> RadioConfig::respond() {
+    return mRadioConfigResponse->respond();
 }
 
 ScopedAStatus RadioConfig::getHalDeviceCapabilities(int32_t serial) {
@@ -43,7 +45,7 @@
     if (mHal1_3) {
         mHal1_3->getHalDeviceCapabilities(serial);
     } else {
-        respond().getHalDeviceCapabilitiesResponse(notSupported(serial), false);
+        respond()->getHalDeviceCapabilitiesResponse(notSupported(serial), false);
     }
     return ok();
 }
@@ -86,9 +88,9 @@
     CHECK(radioConfigResponse);
     CHECK(radioConfigIndication);
 
-    mRadioConfigResponse = sp<RadioConfigResponse>::make(radioConfigResponse);
-    mRadioConfigIndication = sp<RadioConfigIndication>::make(radioConfigIndication);
-    mHal1_1->setResponseFunctions(mRadioConfigResponse, mRadioConfigIndication);
+    mRadioConfigResponse->setResponseFunction(radioConfigResponse);
+    mRadioConfigIndication->setResponseFunction(radioConfigIndication);
+    mHal1_1->setResponseFunctions(mRadioConfigResponse, mRadioConfigIndication).assertOk();
 
     return ok();
 }
diff --git a/radio/aidl/compat/libradiocompat/config/RadioConfigIndication.cpp b/radio/aidl/compat/libradiocompat/config/RadioConfigIndication.cpp
index 0320ad7..c1e32c1 100644
--- a/radio/aidl/compat/libradiocompat/config/RadioConfigIndication.cpp
+++ b/radio/aidl/compat/libradiocompat/config/RadioConfigIndication.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "RadioConfigIndication.h"
+#include <libradiocompat/RadioConfigIndication.h>
 
 #include "commonStructs.h"
 #include "debug.h"
@@ -28,20 +28,26 @@
 
 namespace aidl = ::aidl::android::hardware::radio::config;
 
-RadioConfigIndication::RadioConfigIndication(std::shared_ptr<aidl::IRadioConfigIndication> callback)
-    : mCallback(callback) {}
+void RadioConfigIndication::setResponseFunction(
+        std::shared_ptr<aidl::IRadioConfigIndication> callback) {
+    mCallback = callback;
+}
+
+std::shared_ptr<aidl::IRadioConfigIndication> RadioConfigIndication::indicate() {
+    return mCallback.get();
+}
 
 Return<void> RadioConfigIndication::simSlotsStatusChanged(
         V1_0::RadioIndicationType type, const hidl_vec<config::V1_0::SimSlotStatus>& slotStatus) {
     LOG_CALL << type;
-    mCallback->simSlotsStatusChanged(toAidl(type), toAidl(slotStatus));
+    indicate()->simSlotsStatusChanged(toAidl(type), toAidl(slotStatus));
     return {};
 }
 
 Return<void> RadioConfigIndication::simSlotsStatusChanged_1_2(
         V1_0::RadioIndicationType type, const hidl_vec<config::V1_2::SimSlotStatus>& slotStatus) {
     LOG_CALL << type;
-    mCallback->simSlotsStatusChanged(toAidl(type), toAidl(slotStatus));
+    indicate()->simSlotsStatusChanged(toAidl(type), toAidl(slotStatus));
     return {};
 }
 
diff --git a/radio/aidl/compat/libradiocompat/config/RadioConfigResponse.cpp b/radio/aidl/compat/libradiocompat/config/RadioConfigResponse.cpp
index 7066ae4..523c504 100644
--- a/radio/aidl/compat/libradiocompat/config/RadioConfigResponse.cpp
+++ b/radio/aidl/compat/libradiocompat/config/RadioConfigResponse.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "RadioConfigResponse.h"
+#include <libradiocompat/RadioConfigResponse.h>
 
 #include "commonStructs.h"
 #include "debug.h"
@@ -28,14 +28,20 @@
 
 namespace aidl = ::aidl::android::hardware::radio::config;
 
-RadioConfigResponse::RadioConfigResponse(std::shared_ptr<aidl::IRadioConfigResponse> callback)
-    : mCallback(callback) {}
+void RadioConfigResponse::setResponseFunction(
+        std::shared_ptr<aidl::IRadioConfigResponse> callback) {
+    mCallback = callback;
+}
+
+std::shared_ptr<aidl::IRadioConfigResponse> RadioConfigResponse::respond() {
+    return mCallback.get();
+}
 
 Return<void> RadioConfigResponse::getSimSlotsStatusResponse(
         const V1_0::RadioResponseInfo& info,
         const hidl_vec<config::V1_0::SimSlotStatus>& slotStatus) {
     LOG_CALL << info.serial;
-    mCallback->getSimSlotsStatusResponse(toAidl(info), toAidl(slotStatus));
+    respond()->getSimSlotsStatusResponse(toAidl(info), toAidl(slotStatus));
     return {};
 };
 
@@ -43,47 +49,47 @@
         const V1_0::RadioResponseInfo& info,
         const hidl_vec<config::V1_2::SimSlotStatus>& slotStatus) {
     LOG_CALL << info.serial;
-    mCallback->getSimSlotsStatusResponse(toAidl(info), toAidl(slotStatus));
+    respond()->getSimSlotsStatusResponse(toAidl(info), toAidl(slotStatus));
     return {};
 };
 
 Return<void> RadioConfigResponse::setSimSlotsMappingResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    mCallback->setSimSlotsMappingResponse(toAidl(info));
+    respond()->setSimSlotsMappingResponse(toAidl(info));
     return {};
 };
 
 Return<void> RadioConfigResponse::getPhoneCapabilityResponse(
         const V1_0::RadioResponseInfo& info, const config::V1_1::PhoneCapability& phoneCapability) {
     LOG_CALL << info.serial;
-    mCallback->getPhoneCapabilityResponse(toAidl(info), toAidl(phoneCapability));
+    respond()->getPhoneCapabilityResponse(toAidl(info), toAidl(phoneCapability));
     return {};
 };
 
 Return<void> RadioConfigResponse::setPreferredDataModemResponse(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    mCallback->setPreferredDataModemResponse(toAidl(info));
+    respond()->setPreferredDataModemResponse(toAidl(info));
     return {};
 };
 
 Return<void> RadioConfigResponse::setModemsConfigResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    mCallback->setNumOfLiveModemsResponse(toAidl(info));
+    respond()->setNumOfLiveModemsResponse(toAidl(info));
     return {};
 };
 
 Return<void> RadioConfigResponse::getModemsConfigResponse(
         const V1_0::RadioResponseInfo& info, const config::V1_1::ModemsConfig& modemsConfig) {
     LOG_CALL << info.serial;
-    mCallback->getNumOfLiveModemsResponse(toAidl(info), modemsConfig.numOfLiveModems);
+    respond()->getNumOfLiveModemsResponse(toAidl(info), modemsConfig.numOfLiveModems);
     return {};
 };
 
 Return<void> RadioConfigResponse::getHalDeviceCapabilitiesResponse(
         const V1_6::RadioResponseInfo& info, bool modemReducedFeatureSet1) {
     LOG_CALL << info.serial;
-    mCallback->getHalDeviceCapabilitiesResponse(toAidl(info), modemReducedFeatureSet1);
+    respond()->getHalDeviceCapabilitiesResponse(toAidl(info), modemReducedFeatureSet1);
     return {};
 };
 
diff --git a/radio/aidl/compat/libradiocompat/config/structs.cpp b/radio/aidl/compat/libradiocompat/config/structs.cpp
index 9ba5623..39ad944 100644
--- a/radio/aidl/compat/libradiocompat/config/structs.cpp
+++ b/radio/aidl/compat/libradiocompat/config/structs.cpp
@@ -24,14 +24,11 @@
 
 namespace aidl = ::aidl::android::hardware::radio::config;
 
-hidl_vec<uint32_t> toHidl(const std::vector<aidl::SlotPortMapping>& slotMap) {
-    hidl_vec<uint32_t> out(slotMap.size());
-    for (const auto& el : slotMap) {
-        CHECK_GE(el.portId, 0);
-        CHECK_LT(static_cast<size_t>(el.portId), out.size());
-        out[el.portId] = el.physicalSlotId;
+uint32_t toHidl(const aidl::SlotPortMapping& slotPortMapping) {
+    if (slotPortMapping.portId != 0) {
+        LOG(ERROR) << "Port ID " << slotPortMapping.portId << " != 0 not supported by HIDL HAL";
     }
-    return out;
+    return slotPortMapping.physicalSlotId;
 }
 
 aidl::SimSlotStatus toAidl(const config::V1_0::SimSlotStatus& sst) {
diff --git a/radio/aidl/compat/libradiocompat/config/structs.h b/radio/aidl/compat/libradiocompat/config/structs.h
index b8a0385..6ea4e4a 100644
--- a/radio/aidl/compat/libradiocompat/config/structs.h
+++ b/radio/aidl/compat/libradiocompat/config/structs.h
@@ -23,8 +23,7 @@
 
 namespace android::hardware::radio::compat {
 
-hidl_vec<uint32_t>  //
-toHidl(const std::vector<aidl::android::hardware::radio::config::SlotPortMapping>& slotMap);
+uint32_t toHidl(const aidl::android::hardware::radio::config::SlotPortMapping& slotPortMapping);
 
 aidl::android::hardware::radio::config::SimSlotStatus  //
 toAidl(const config::V1_0::SimSlotStatus& sst);
diff --git a/radio/aidl/compat/libradiocompat/data/RadioData.cpp b/radio/aidl/compat/libradiocompat/data/RadioData.cpp
index fdb1273..d2f3687 100644
--- a/radio/aidl/compat/libradiocompat/data/RadioData.cpp
+++ b/radio/aidl/compat/libradiocompat/data/RadioData.cpp
@@ -31,12 +31,16 @@
 namespace aidlCommon = ::aidl::android::hardware::radio;
 constexpr auto ok = &ScopedAStatus::ok;
 
+std::shared_ptr<aidl::IRadioDataResponse> RadioData::respond() {
+    return mCallbackManager->response().dataCb();
+}
+
 ScopedAStatus RadioData::allocatePduSessionId(int32_t serial) {
     LOG_CALL << serial;
     if (mHal1_6) {
         mHal1_6->allocatePduSessionId(serial);
     } else {
-        respond().allocatePduSessionIdResponse(notSupported(serial), 0);
+        respond()->allocatePduSessionIdResponse(notSupported(serial), 0);
     }
     return ok();
 }
@@ -46,7 +50,7 @@
     if (mHal1_6) {
         mHal1_6->cancelHandover(serial, callId);
     } else {
-        respond().cancelHandoverResponse(notSupported(serial));
+        respond()->cancelHandoverResponse(notSupported(serial));
     }
     return ok();
 }
@@ -60,7 +64,11 @@
 
 ScopedAStatus RadioData::getDataCallList(int32_t serial) {
     LOG_CALL << serial;
-    mHal1_5->getDataCallList(serial);
+    if (mHal1_6) {
+        mHal1_6->getDataCallList_1_6(serial);
+    } else {
+        mHal1_5->getDataCallList(serial);
+    }
     return ok();
 }
 
@@ -69,7 +77,7 @@
     if (mHal1_6) {
         mHal1_6->getSlicingConfig(serial);
     } else {
-        respond().getSlicingConfigResponse(notSupported(serial), {});
+        respond()->getSlicingConfigResponse(notSupported(serial), {});
     }
     return ok();
 }
@@ -79,7 +87,7 @@
     if (mHal1_6) {
         mHal1_6->releasePduSessionId(serial, id);
     } else {
-        respond().releasePduSessionIdResponse(notSupported(serial));
+        respond()->releasePduSessionIdResponse(notSupported(serial));
     }
     return ok();
 }
@@ -109,7 +117,7 @@
     if (mHal1_6) {
         mHal1_6->setDataThrottling(serial, V1_6::DataThrottlingAction(dta), completionDurationMs);
     } else {
-        respond().setDataThrottlingResponse(notSupported(serial));
+        respond()->setDataThrottlingResponse(notSupported(serial));
     }
     return ok();
 }
@@ -121,16 +129,10 @@
 }
 
 ScopedAStatus RadioData::setResponseFunctions(
-        const std::shared_ptr<aidl::IRadioDataResponse>& dataResponse,
-        const std::shared_ptr<aidl::IRadioDataIndication>& dataIndication) {
-    LOG_CALL << dataResponse << ' ' << dataIndication;
-
-    CHECK(dataResponse);
-    CHECK(dataIndication);
-
-    mRadioResponse->setResponseFunction(dataResponse);
-    mRadioIndication->setResponseFunction(dataIndication);
-
+        const std::shared_ptr<aidl::IRadioDataResponse>& response,
+        const std::shared_ptr<aidl::IRadioDataIndication>& indication) {
+    LOG_CALL << response << ' ' << indication;
+    mCallbackManager->setResponseFunctions(response, indication);
     return ok();
 }
 
@@ -139,14 +141,15 @@
         const aidl::DataProfileInfo& dataProfileInfo, bool roamingAllowed,
         aidl::DataRequestReason reason, const std::vector<aidl::LinkAddress>& addresses,
         const std::vector<std::string>& dnses, int32_t pduSessId,
-        const std::optional<aidl::SliceInfo>& sliceInfo,
-        const std::optional<aidl::TrafficDescriptor>& trDesc, bool matchAllRuleAllowed) {
+        const std::optional<aidl::SliceInfo>& sliceInfo, bool matchAllRuleAllowed) {
     if (mHal1_6) {
         mHal1_6->setupDataCall_1_6(  //
                 serial, V1_5::AccessNetwork(accessNetwork), toHidl(dataProfileInfo), roamingAllowed,
                 V1_2::DataRequestReason(reason), toHidl(addresses), toHidl(dnses), pduSessId,
                 toHidl<V1_6::OptionalSliceInfo>(sliceInfo),
-                toHidl<V1_6::OptionalTrafficDescriptor>(trDesc), matchAllRuleAllowed);
+                toHidl<V1_6::OptionalTrafficDescriptor>(dataProfileInfo.trafficDescriptor),
+                matchAllRuleAllowed);
+        mContext->addDataProfile(dataProfileInfo);
     } else {
         mHal1_5->setupDataCall_1_5(  //
                 serial, V1_5::AccessNetwork(accessNetwork), toHidl(dataProfileInfo), roamingAllowed,
@@ -160,7 +163,7 @@
     if (mHal1_6) {
         mHal1_6->startHandover(serial, callId);
     } else {
-        respond().startHandoverResponse(notSupported(serial));
+        respond()->startHandoverResponse(notSupported(serial));
     }
     return ok();
 }
diff --git a/radio/aidl/compat/libradiocompat/data/RadioIndication-data.cpp b/radio/aidl/compat/libradiocompat/data/RadioIndication-data.cpp
index f51d1a8..602bb39 100644
--- a/radio/aidl/compat/libradiocompat/data/RadioIndication-data.cpp
+++ b/radio/aidl/compat/libradiocompat/data/RadioIndication-data.cpp
@@ -29,10 +29,13 @@
 namespace aidl = ::aidl::android::hardware::radio::data;
 
 void RadioIndication::setResponseFunction(std::shared_ptr<aidl::IRadioDataIndication> dataCb) {
-    CHECK(dataCb);
     mDataCb = dataCb;
 }
 
+std::shared_ptr<aidl::IRadioDataIndication> RadioIndication::dataCb() {
+    return mDataCb.get();
+}
+
 Return<void> RadioIndication::dataCallListChanged(V1_0::RadioIndicationType type,
                                                   const hidl_vec<V1_0::SetupDataCallResult>&) {
     LOG_CALL << type;
@@ -50,40 +53,42 @@
 Return<void> RadioIndication::dataCallListChanged_1_5(
         V1_0::RadioIndicationType type, const hidl_vec<V1_5::SetupDataCallResult>& dcList) {
     LOG_CALL << type;
-    CHECK_CB(mDataCb);
-    mDataCb->dataCallListChanged(toAidl(type), toAidl(dcList));
+    dataCb()->dataCallListChanged(toAidl(type), toAidl(dcList));
     return {};
 }
 
 Return<void> RadioIndication::dataCallListChanged_1_6(
         V1_0::RadioIndicationType type, const hidl_vec<V1_6::SetupDataCallResult>& dcList) {
     LOG_CALL << type;
-    CHECK_CB(mDataCb);
-    mDataCb->dataCallListChanged(toAidl(type), toAidl(dcList));
+    dataCb()->dataCallListChanged(toAidl(type), toAidl(dcList));
     return {};
 }
 
 Return<void> RadioIndication::keepaliveStatus(V1_0::RadioIndicationType type,
                                               const V1_1::KeepaliveStatus& status) {
     LOG_CALL << type;
-    CHECK_CB(mDataCb);
-    mDataCb->keepaliveStatus(toAidl(type), toAidl(status));
+    dataCb()->keepaliveStatus(toAidl(type), toAidl(status));
     return {};
 }
 
 Return<void> RadioIndication::pcoData(V1_0::RadioIndicationType type,
                                       const V1_0::PcoDataInfo& pco) {
     LOG_CALL << type;
-    CHECK_CB(mDataCb);
-    mDataCb->pcoData(toAidl(type), toAidl(pco));
+    dataCb()->pcoData(toAidl(type), toAidl(pco));
     return {};
 }
 
 Return<void> RadioIndication::unthrottleApn(V1_0::RadioIndicationType type,
                                             const hidl_string& apn) {
     LOG_CALL << type;
-    CHECK_CB(mDataCb);
-    mDataCb->unthrottleApn(toAidl(type), apn);
+    dataCb()->unthrottleApn(toAidl(type), mContext->getDataProfile(apn));
+    return {};
+}
+
+Return<void> RadioIndication::slicingConfigChanged(V1_0::RadioIndicationType type,
+                                                   const V1_6::SlicingConfig& slicingConfig) {
+    LOG_CALL << type;
+    dataCb()->slicingConfigChanged(toAidl(type), toAidl(slicingConfig));
     return {};
 }
 
diff --git a/radio/aidl/compat/libradiocompat/data/RadioResponse-data.cpp b/radio/aidl/compat/libradiocompat/data/RadioResponse-data.cpp
index 171f692..0bfa2df 100644
--- a/radio/aidl/compat/libradiocompat/data/RadioResponse-data.cpp
+++ b/radio/aidl/compat/libradiocompat/data/RadioResponse-data.cpp
@@ -29,29 +29,29 @@
 namespace aidl = ::aidl::android::hardware::radio::data;
 
 void RadioResponse::setResponseFunction(std::shared_ptr<aidl::IRadioDataResponse> dataCb) {
-    CHECK(dataCb);
     mDataCb = dataCb;
 }
 
+std::shared_ptr<aidl::IRadioDataResponse> RadioResponse::dataCb() {
+    return mDataCb.get();
+}
+
 Return<void> RadioResponse::allocatePduSessionIdResponse(const V1_6::RadioResponseInfo& info,
                                                          int32_t id) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->allocatePduSessionIdResponse(toAidl(info), id);
+    dataCb()->allocatePduSessionIdResponse(toAidl(info), id);
     return {};
 }
 
 Return<void> RadioResponse::cancelHandoverResponse(const V1_6::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->cancelHandoverResponse(toAidl(info));
+    dataCb()->cancelHandoverResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::deactivateDataCallResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->deactivateDataCallResponse(toAidl(info));
+    dataCb()->deactivateDataCallResponse(toAidl(info));
     return {};
 }
 
@@ -73,8 +73,7 @@
         const V1_0::RadioResponseInfo& info,
         const hidl_vec<V1_5::SetupDataCallResult>& dcResponse) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->getDataCallListResponse(toAidl(info), toAidl(dcResponse));
+    dataCb()->getDataCallListResponse(toAidl(info), toAidl(dcResponse));
     return {};
 }
 
@@ -82,65 +81,56 @@
         const V1_6::RadioResponseInfo& info,
         const hidl_vec<V1_6::SetupDataCallResult>& dcResponse) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->getDataCallListResponse(toAidl(info), toAidl(dcResponse));
+    dataCb()->getDataCallListResponse(toAidl(info), toAidl(dcResponse));
     return {};
 }
 
 Return<void> RadioResponse::getSlicingConfigResponse(const V1_6::RadioResponseInfo& info,
                                                      const V1_6::SlicingConfig& slicingConfig) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->getSlicingConfigResponse(toAidl(info), toAidl(slicingConfig));
+    dataCb()->getSlicingConfigResponse(toAidl(info), toAidl(slicingConfig));
     return {};
 }
 
 Return<void> RadioResponse::releasePduSessionIdResponse(const V1_6::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->releasePduSessionIdResponse(toAidl(info));
+    dataCb()->releasePduSessionIdResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setDataAllowedResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->setDataAllowedResponse(toAidl(info));
+    dataCb()->setDataAllowedResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setDataProfileResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->setDataProfileResponse(toAidl(info));
+    dataCb()->setDataProfileResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setDataProfileResponse_1_5(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->setDataProfileResponse(toAidl(info));
+    dataCb()->setDataProfileResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setDataThrottlingResponse(const V1_6::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->setDataThrottlingResponse(toAidl(info));
+    dataCb()->setDataThrottlingResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setInitialAttachApnResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->setInitialAttachApnResponse(toAidl(info));
+    dataCb()->setInitialAttachApnResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setInitialAttachApnResponse_1_5(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->setInitialAttachApnResponse(toAidl(info));
+    dataCb()->setInitialAttachApnResponse(toAidl(info));
     return {};
 }
 
@@ -161,38 +151,33 @@
 Return<void> RadioResponse::setupDataCallResponse_1_5(const V1_0::RadioResponseInfo& info,
                                                       const V1_5::SetupDataCallResult& dcResponse) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->setupDataCallResponse(toAidl(info), toAidl(dcResponse));
+    dataCb()->setupDataCallResponse(toAidl(info), toAidl(dcResponse));
     return {};
 }
 
 Return<void> RadioResponse::setupDataCallResponse_1_6(const V1_6::RadioResponseInfo& info,
                                                       const V1_6::SetupDataCallResult& dcResponse) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->setupDataCallResponse(toAidl(info), toAidl(dcResponse));
+    dataCb()->setupDataCallResponse(toAidl(info), toAidl(dcResponse));
     return {};
 }
 
 Return<void> RadioResponse::startHandoverResponse(const V1_6::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->startHandoverResponse(toAidl(info));
+    dataCb()->startHandoverResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::startKeepaliveResponse(const V1_0::RadioResponseInfo& info,
                                                    const V1_1::KeepaliveStatus& status) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->startKeepaliveResponse(toAidl(info), toAidl(status));
+    dataCb()->startKeepaliveResponse(toAidl(info), toAidl(status));
     return {};
 }
 
 Return<void> RadioResponse::stopKeepaliveResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mDataCb);
-    mDataCb->stopKeepaliveResponse(toAidl(info));
+    dataCb()->stopKeepaliveResponse(toAidl(info));
     return {};
 }
 
diff --git a/radio/aidl/compat/libradiocompat/debug.h b/radio/aidl/compat/libradiocompat/debug.h
index 4158059..cb773bf 100644
--- a/radio/aidl/compat/libradiocompat/debug.h
+++ b/radio/aidl/compat/libradiocompat/debug.h
@@ -26,12 +26,6 @@
 #define LOG_CALL \
     if constexpr (debug::kSuperVerbose) LOG(VERBOSE) << (RADIO_MODULE ".") << __func__ << ' '
 
-#define CHECK_CB(field)                     \
-    if (!field) {                           \
-        LOG(WARNING) << "Callback not set"; \
-        return {};                          \
-    }
-
 }  // namespace debug
 
 inline std::ostream& operator<<(std::ostream& os, const V1_0::RadioIndicationType& type) {
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/CallbackManager.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/CallbackManager.h
new file mode 100644
index 0000000..f1a7b49
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/CallbackManager.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+#pragma once
+
+#include "DriverContext.h"
+#include "RadioIndication.h"
+#include "RadioResponse.h"
+
+#include <android-base/logging.h>
+#include <android/hardware/radio/1.6/IRadio.h>
+
+#include <thread>
+
+namespace android::hardware::radio::compat {
+
+class CallbackManager {
+    sp<V1_5::IRadio> mHidlHal;
+    sp<RadioResponse> mRadioResponse;
+    sp<RadioIndication> mRadioIndication;
+
+    std::thread mDelayedSetterThread;
+    std::mutex mDelayedSetterGuard;
+    std::optional<std::chrono::time_point<std::chrono::steady_clock>> mDelayedSetterDeadline
+            GUARDED_BY(mDelayedSetterGuard);
+    std::condition_variable mDelayedSetterCv GUARDED_BY(mDelayedSetterGuard);
+    bool mDestroy GUARDED_BY(mDelayedSetterGuard) = false;
+
+    void setResponseFunctionsDelayed();
+    void delayedSetterThread();
+
+  public:
+    CallbackManager(std::shared_ptr<DriverContext> context, sp<V1_5::IRadio> hidlHal);
+    ~CallbackManager();
+
+    RadioResponse& response() const;
+
+    template <typename ResponseType, typename IndicationType>
+    void setResponseFunctions(const std::shared_ptr<ResponseType>& response,
+                              const std::shared_ptr<IndicationType>& indication) {
+        CHECK(response);
+        CHECK(indication);
+
+        mRadioResponse->setResponseFunction(response);
+        mRadioIndication->setResponseFunction(indication);
+        setResponseFunctionsDelayed();
+    }
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/DriverContext.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/DriverContext.h
new file mode 100644
index 0000000..6833aca
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/DriverContext.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/data/DataProfileInfo.h>
+
+#include <map>
+
+namespace android::hardware::radio::compat {
+
+class DriverContext {
+    std::map<std::string, ::aidl::android::hardware::radio::data::DataProfileInfo> mDataProfiles;
+
+  public:
+    void addDataProfile(const ::aidl::android::hardware::radio::data::DataProfileInfo& profile);
+    ::aidl::android::hardware::radio::data::DataProfileInfo getDataProfile(const std::string& apn);
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/GuaranteedCallback.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/GuaranteedCallback.h
new file mode 100644
index 0000000..0b6ee11
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/GuaranteedCallback.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+#pragma once
+
+#include <android-base/logging.h>
+#include <android/binder_interface_utils.h>
+#include <utils/Mutex.h>
+
+namespace android::hardware::radio::compat {
+
+template <typename Interface, typename DefaultImplementation, bool isIndication = false>
+class GuaranteedCallback {
+    mutable std::mutex mCallbackGuard;
+    std::shared_ptr<Interface> mCallback GUARDED_BY(mCallbackGuard);
+
+  public:
+    GuaranteedCallback<Interface, DefaultImplementation, isIndication>& operator=(
+            const std::shared_ptr<Interface>& callback) {
+        CHECK(callback);
+        const std::lock_guard<std::mutex> lock(mCallbackGuard);
+        mCallback = callback;
+        return *this;
+    }
+
+    std::shared_ptr<Interface> get() {
+        if (mCallback) return mCallback;
+        const std::lock_guard<std::mutex> lock(mCallbackGuard);
+        if (mCallback) return mCallback;
+
+        LOG(isIndication ? WARNING : ERROR) << "Callback is not set";
+        return mCallback = ndk::SharedRefBase::make<DefaultImplementation>();
+    }
+
+    operator bool() const { return mCallback != nullptr; }
+};
+
+}  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioCompatBase.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioCompatBase.h
index a412c34..eb22fff 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioCompatBase.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioCompatBase.h
@@ -15,8 +15,8 @@
  */
 #pragma once
 
-#include "RadioIndication.h"
-#include "RadioResponse.h"
+#include "CallbackManager.h"
+#include "DriverContext.h"
 
 #include <android/hardware/radio/1.6/IRadio.h>
 
@@ -24,17 +24,16 @@
 
 class RadioCompatBase {
   protected:
+    std::shared_ptr<DriverContext> mContext;
+
     sp<V1_5::IRadio> mHal1_5;
     sp<V1_6::IRadio> mHal1_6;
 
-    sp<RadioResponse> mRadioResponse;
-    sp<RadioIndication> mRadioIndication;
-
-    V1_6::IRadioResponse& respond();
+    std::shared_ptr<CallbackManager> mCallbackManager;
 
   public:
-    RadioCompatBase(sp<V1_5::IRadio> hidlHal, sp<RadioResponse> radioResponse,
-                    sp<RadioIndication> radioIndication);
+    RadioCompatBase(std::shared_ptr<DriverContext> context, sp<V1_5::IRadio> hidlHal,
+                    std::shared_ptr<CallbackManager> cbMgr);
 };
 
 }  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfig.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfig.h
index 31ad207..bbfff61 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfig.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfig.h
@@ -15,6 +15,9 @@
  */
 #pragma once
 
+#include "RadioConfigIndication.h"
+#include "RadioConfigResponse.h"
+
 #include <aidl/android/hardware/radio/config/BnRadioConfig.h>
 #include <android/hardware/radio/config/1.2/IRadioConfigIndication.h>
 #include <android/hardware/radio/config/1.3/IRadioConfig.h>
@@ -30,11 +33,13 @@
  * fetch source implementation and publish resulting HAL instance.
  */
 class RadioConfig : public aidl::android::hardware::radio::config::BnRadioConfig {
-    sp<config::V1_1::IRadioConfig> mHal1_1;
-    sp<config::V1_3::IRadioConfig> mHal1_3;
+    const sp<config::V1_1::IRadioConfig> mHal1_1;
+    const sp<config::V1_3::IRadioConfig> mHal1_3;
 
-    sp<config::V1_3::IRadioConfigResponse> mRadioConfigResponse;
-    sp<config::V1_2::IRadioConfigIndication> mRadioConfigIndication;
+    const sp<RadioConfigResponse> mRadioConfigResponse;
+    const sp<RadioConfigIndication> mRadioConfigIndication;
+
+    std::shared_ptr<::aidl::android::hardware::radio::config::IRadioConfigResponse> respond();
 
     ::ndk::ScopedAStatus getHalDeviceCapabilities(int32_t serial) override;
     ::ndk::ScopedAStatus getNumOfLiveModems(int32_t serial) override;
@@ -52,8 +57,6 @@
             const std::vector<aidl::android::hardware::radio::config::SlotPortMapping>& slotMap)
             override;
 
-    config::V1_3::IRadioConfigResponse& respond();
-
   public:
     /**
      * Constructs AIDL IRadioConfig instance wrapping existing HIDL IRadioConfig instance.
diff --git a/radio/aidl/compat/libradiocompat/config/RadioConfigIndication.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfigIndication.h
similarity index 82%
rename from radio/aidl/compat/libradiocompat/config/RadioConfigIndication.h
rename to radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfigIndication.h
index 3d8d971..d256a87 100644
--- a/radio/aidl/compat/libradiocompat/config/RadioConfigIndication.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfigIndication.h
@@ -15,13 +15,17 @@
  */
 #pragma once
 
+#include "GuaranteedCallback.h"
+
 #include <aidl/android/hardware/radio/config/IRadioConfigIndication.h>
 #include <android/hardware/radio/config/1.2/IRadioConfigIndication.h>
 
 namespace android::hardware::radio::compat {
 
 class RadioConfigIndication : public config::V1_2::IRadioConfigIndication {
-    std::shared_ptr<aidl::android::hardware::radio::config::IRadioConfigIndication> mCallback;
+    GuaranteedCallback<aidl::android::hardware::radio::config::IRadioConfigIndication,
+                       aidl::android::hardware::radio::config::IRadioConfigIndicationDefault, true>
+            mCallback;
 
     Return<void> simSlotsStatusChanged(
             V1_0::RadioIndicationType type,
@@ -31,8 +35,10 @@
             const hidl_vec<config::V1_2::SimSlotStatus>& slotStatus) override;
 
   public:
-    RadioConfigIndication(
+    void setResponseFunction(
             std::shared_ptr<aidl::android::hardware::radio::config::IRadioConfigIndication> cb);
+
+    std::shared_ptr<aidl::android::hardware::radio::config::IRadioConfigIndication> indicate();
 };
 
 }  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/config/RadioConfigResponse.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfigResponse.h
similarity index 88%
rename from radio/aidl/compat/libradiocompat/config/RadioConfigResponse.h
rename to radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfigResponse.h
index 1461dd2..dc86da2 100644
--- a/radio/aidl/compat/libradiocompat/config/RadioConfigResponse.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfigResponse.h
@@ -15,13 +15,17 @@
  */
 #pragma once
 
+#include "GuaranteedCallback.h"
+
 #include <aidl/android/hardware/radio/config/IRadioConfigResponse.h>
 #include <android/hardware/radio/config/1.3/IRadioConfigResponse.h>
 
 namespace android::hardware::radio::compat {
 
 class RadioConfigResponse : public config::V1_3::IRadioConfigResponse {
-    std::shared_ptr<aidl::android::hardware::radio::config::IRadioConfigResponse> mCallback;
+    GuaranteedCallback<aidl::android::hardware::radio::config::IRadioConfigResponse,
+                       aidl::android::hardware::radio::config::IRadioConfigResponseDefault>
+            mCallback;
 
     Return<void> getSimSlotsStatusResponse(
             const V1_0::RadioResponseInfo& info,
@@ -41,8 +45,10 @@
                                                   bool modemReducedFeatureSet1) override;
 
   public:
-    RadioConfigResponse(
+    void setResponseFunction(
             std::shared_ptr<aidl::android::hardware::radio::config::IRadioConfigResponse> callback);
+
+    std::shared_ptr<aidl::android::hardware::radio::config::IRadioConfigResponse> respond();
 };
 
 }  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioData.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioData.h
index 900a669..c617ec2 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioData.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioData.h
@@ -22,6 +22,8 @@
 namespace android::hardware::radio::compat {
 
 class RadioData : public RadioCompatBase, public aidl::android::hardware::radio::data::BnRadioData {
+    std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataResponse> respond();
+
     ::ndk::ScopedAStatus allocatePduSessionId(int32_t serial) override;
     ::ndk::ScopedAStatus cancelHandover(int32_t serial, int32_t callId) override;
     ::ndk::ScopedAStatus deactivateDataCall(
@@ -55,7 +57,6 @@
             const std::vector<::aidl::android::hardware::radio::data::LinkAddress>& addresses,
             const std::vector<std::string>& dnses, int32_t pduSessionId,
             const std::optional<::aidl::android::hardware::radio::data::SliceInfo>& sliceInfo,
-            const std::optional<::aidl::android::hardware::radio::data::TrafficDescriptor>& trDescr,
             bool matchAllRuleAllowed) override;
     ::ndk::ScopedAStatus startHandover(int32_t serial, int32_t callId) override;
     ::ndk::ScopedAStatus startKeepalive(
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h
index 20e0973..6cfd59c 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h
@@ -15,6 +15,9 @@
  */
 #pragma once
 
+#include "DriverContext.h"
+#include "GuaranteedCallback.h"
+
 #include <aidl/android/hardware/radio/data/IRadioDataIndication.h>
 #include <aidl/android/hardware/radio/messaging/IRadioMessagingIndication.h>
 #include <aidl/android/hardware/radio/modem/IRadioModemIndication.h>
@@ -26,13 +29,32 @@
 namespace android::hardware::radio::compat {
 
 class RadioIndication : public V1_6::IRadioIndication {
-    std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataIndication> mDataCb;
-    std::shared_ptr<::aidl::android::hardware::radio::messaging::IRadioMessagingIndication>
+    std::shared_ptr<DriverContext> mContext;
+
+    GuaranteedCallback<  //
+            ::aidl::android::hardware::radio::data::IRadioDataIndication,
+            ::aidl::android::hardware::radio::data::IRadioDataIndicationDefault, true>
+            mDataCb;
+    GuaranteedCallback<  //
+            ::aidl::android::hardware::radio::messaging::IRadioMessagingIndication,
+            ::aidl::android::hardware::radio::messaging::IRadioMessagingIndicationDefault, true>
             mMessagingCb;
-    std::shared_ptr<::aidl::android::hardware::radio::modem::IRadioModemIndication> mModemCb;
-    std::shared_ptr<::aidl::android::hardware::radio::network::IRadioNetworkIndication> mNetworkCb;
-    std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimIndication> mSimCb;
-    std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceIndication> mVoiceCb;
+    GuaranteedCallback<  //
+            ::aidl::android::hardware::radio::modem::IRadioModemIndication,
+            ::aidl::android::hardware::radio::modem::IRadioModemIndicationDefault, true>
+            mModemCb;
+    GuaranteedCallback<  //
+            ::aidl::android::hardware::radio::network::IRadioNetworkIndication,
+            ::aidl::android::hardware::radio::network::IRadioNetworkIndicationDefault, true>
+            mNetworkCb;
+    GuaranteedCallback<  //
+            ::aidl::android::hardware::radio::sim::IRadioSimIndication,
+            ::aidl::android::hardware::radio::sim::IRadioSimIndicationDefault, true>
+            mSimCb;
+    GuaranteedCallback<  //
+            ::aidl::android::hardware::radio::voice::IRadioVoiceIndication,
+            ::aidl::android::hardware::radio::voice::IRadioVoiceIndicationDefault, true>
+            mVoiceCb;
 
     // IRadioIndication @ 1.0
     Return<void> radioStateChanged(V1_0::RadioIndicationType type,
@@ -164,6 +186,8 @@
             V1_0::RadioIndicationType type,
             const hidl_vec<V1_6::SetupDataCallResult>& dcList) override;
     Return<void> unthrottleApn(V1_0::RadioIndicationType type, const hidl_string& apn) override;
+    Return<void> slicingConfigChanged(V1_0::RadioIndicationType type,
+                                      const V1_6::SlicingConfig& slicingConfig);
     Return<void> currentLinkCapacityEstimate_1_6(V1_0::RadioIndicationType type,
                                                  const V1_6::LinkCapacityEstimate& lce) override;
     Return<void> currentSignalStrength_1_6(V1_0::RadioIndicationType type,
@@ -181,6 +205,8 @@
             const hidl_vec<V1_6::PhonebookRecordInfo>& records) override;
 
   public:
+    RadioIndication(std::shared_ptr<DriverContext> context);
+
     void setResponseFunction(
             std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataIndication> dataCb);
     void setResponseFunction(
@@ -194,6 +220,14 @@
             std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimIndication> simCb);
     void setResponseFunction(
             std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceIndication> voicCb);
+
+    std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataIndication> dataCb();
+    std::shared_ptr<::aidl::android::hardware::radio::messaging::IRadioMessagingIndication>
+    messagingCb();
+    std::shared_ptr<::aidl::android::hardware::radio::modem::IRadioModemIndication> modemCb();
+    std::shared_ptr<::aidl::android::hardware::radio::network::IRadioNetworkIndication> networkCb();
+    std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimIndication> simCb();
+    std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceIndication> voiceCb();
 };
 
 }  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioMessaging.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioMessaging.h
index 0cd3381..419e9fb 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioMessaging.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioMessaging.h
@@ -23,6 +23,8 @@
 
 class RadioMessaging : public RadioCompatBase,
                        public aidl::android::hardware::radio::messaging::BnRadioMessaging {
+    std::shared_ptr<::aidl::android::hardware::radio::messaging::IRadioMessagingResponse> respond();
+
     ::ndk::ScopedAStatus acknowledgeIncomingGsmSmsWithPdu(int32_t serial, bool success,
                                                           const std::string& ackPdu) override;
     ::ndk::ScopedAStatus acknowledgeLastIncomingCdmaSms(
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioModem.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioModem.h
index 666ff47..fdca124 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioModem.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioModem.h
@@ -23,6 +23,8 @@
 
 class RadioModem : public RadioCompatBase,
                    public aidl::android::hardware::radio::modem::BnRadioModem {
+    std::shared_ptr<::aidl::android::hardware::radio::modem::IRadioModemResponse> respond();
+
     ::ndk::ScopedAStatus enableModem(int32_t serial, bool on) override;
     ::ndk::ScopedAStatus getBasebandVersion(int32_t serial) override;
     ::ndk::ScopedAStatus getDeviceIdentity(int32_t serial) override;
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h
index c776fd1..1731b78 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h
@@ -23,6 +23,8 @@
 
 class RadioNetwork : public RadioCompatBase,
                      public aidl::android::hardware::radio::network::BnRadioNetwork {
+    std::shared_ptr<::aidl::android::hardware::radio::network::IRadioNetworkResponse> respond();
+
     ::ndk::ScopedAStatus getAllowedNetworkTypesBitmap(int32_t serial) override;
     ::ndk::ScopedAStatus getAvailableBandModes(int32_t serial) override;
     ::ndk::ScopedAStatus getAvailableNetworks(int32_t serial) override;
@@ -39,9 +41,8 @@
     ::ndk::ScopedAStatus getVoiceRegistrationState(int32_t serial) override;
     ::ndk::ScopedAStatus isNrDualConnectivityEnabled(int32_t serial) override;
     ::ndk::ScopedAStatus responseAcknowledgement() override;
-    ::ndk::ScopedAStatus setAllowedNetworkTypesBitmap(
-            int32_t serial,
-            ::aidl::android::hardware::radio::RadioAccessFamily networkTypeBitmap) override;
+    ::ndk::ScopedAStatus setAllowedNetworkTypesBitmap(int32_t serial,
+                                                      int32_t networkTypeBitmap) override;
     ::ndk::ScopedAStatus setBandMode(
             int32_t serial, ::aidl::android::hardware::radio::network::RadioBandMode mode) override;
     ::ndk::ScopedAStatus setBarringPassword(int32_t serial, const std::string& facility,
@@ -51,9 +52,7 @@
             int32_t serial,
             ::aidl::android::hardware::radio::network::CdmaRoamingType type) override;
     ::ndk::ScopedAStatus setCellInfoListRate(int32_t serial, int32_t rate) override;
-    ::ndk::ScopedAStatus setIndicationFilter(
-            int32_t serial,
-            ::aidl::android::hardware::radio::network::IndicationFilter indicationFilter) override;
+    ::ndk::ScopedAStatus setIndicationFilter(int32_t serial, int32_t indicationFilter) override;
     ::ndk::ScopedAStatus setLinkCapacityReportingCriteria(
             int32_t serial, int32_t hysteresisMs, int32_t hysteresisDlKbps,
             int32_t hysteresisUlKbps, const std::vector<int32_t>& thresholdsDownlinkKbps,
@@ -88,6 +87,10 @@
     ::ndk::ScopedAStatus stopNetworkScan(int32_t serial) override;
     ::ndk::ScopedAStatus supplyNetworkDepersonalization(int32_t serial,
                                                         const std::string& netPin) override;
+    ::ndk::ScopedAStatus setUsageSetting(
+            int32_t serial,
+            ::aidl::android::hardware::radio::network::UsageSetting usageSetting) override;
+    ::ndk::ScopedAStatus getUsageSetting(int32_t serial) override;
 
   public:
     using RadioCompatBase::RadioCompatBase;
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioResponse.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioResponse.h
index 5db963f..1f82dd1 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioResponse.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioResponse.h
@@ -15,6 +15,9 @@
  */
 #pragma once
 
+#include "DriverContext.h"
+#include "GuaranteedCallback.h"
+
 #include <aidl/android/hardware/radio/data/IRadioDataResponse.h>
 #include <aidl/android/hardware/radio/messaging/IRadioMessagingResponse.h>
 #include <aidl/android/hardware/radio/modem/IRadioModemResponse.h>
@@ -26,13 +29,26 @@
 namespace android::hardware::radio::compat {
 
 class RadioResponse : public V1_6::IRadioResponse {
-    std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataResponse> mDataCb;
-    std::shared_ptr<::aidl::android::hardware::radio::messaging::IRadioMessagingResponse>
+    std::shared_ptr<DriverContext> mContext;
+
+    GuaranteedCallback<::aidl::android::hardware::radio::data::IRadioDataResponse,
+                       ::aidl::android::hardware::radio::data::IRadioDataResponseDefault>
+            mDataCb;
+    GuaranteedCallback<::aidl::android::hardware::radio::messaging::IRadioMessagingResponse,
+                       ::aidl::android::hardware::radio::messaging::IRadioMessagingResponseDefault>
             mMessagingCb;
-    std::shared_ptr<::aidl::android::hardware::radio::modem::IRadioModemResponse> mModemCb;
-    std::shared_ptr<::aidl::android::hardware::radio::network::IRadioNetworkResponse> mNetworkCb;
-    std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimResponse> mSimCb;
-    std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceResponse> mVoiceCb;
+    GuaranteedCallback<::aidl::android::hardware::radio::modem::IRadioModemResponse,
+                       ::aidl::android::hardware::radio::modem::IRadioModemResponseDefault>
+            mModemCb;
+    GuaranteedCallback<::aidl::android::hardware::radio::network::IRadioNetworkResponse,
+                       ::aidl::android::hardware::radio::network::IRadioNetworkResponseDefault>
+            mNetworkCb;
+    GuaranteedCallback<::aidl::android::hardware::radio::sim::IRadioSimResponse,
+                       ::aidl::android::hardware::radio::sim::IRadioSimResponseDefault>
+            mSimCb;
+    GuaranteedCallback<::aidl::android::hardware::radio::voice::IRadioVoiceResponse,
+                       ::aidl::android::hardware::radio::voice::IRadioVoiceResponseDefault>
+            mVoiceCb;
 
     // IRadioResponse @ 1.0
     Return<void> getIccCardStatusResponse(const V1_0::RadioResponseInfo& info,
@@ -409,6 +425,8 @@
                                                    int32_t updatedRecordIndex) override;
 
   public:
+    RadioResponse(std::shared_ptr<DriverContext> context);
+
     void setResponseFunction(
             std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataResponse> dataCb);
     void setResponseFunction(
@@ -422,6 +440,14 @@
             std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimResponse> simCb);
     void setResponseFunction(
             std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceResponse> voiceCb);
+
+    std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataResponse> dataCb();
+    std::shared_ptr<::aidl::android::hardware::radio::messaging::IRadioMessagingResponse>
+    messagingCb();
+    std::shared_ptr<::aidl::android::hardware::radio::modem::IRadioModemResponse> modemCb();
+    std::shared_ptr<::aidl::android::hardware::radio::network::IRadioNetworkResponse> networkCb();
+    std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimResponse> simCb();
+    std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceResponse> voiceCb();
 };
 
 }  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioSim.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioSim.h
index a6b77fd..84bb68b 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioSim.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioSim.h
@@ -22,6 +22,8 @@
 namespace android::hardware::radio::compat {
 
 class RadioSim : public RadioCompatBase, public aidl::android::hardware::radio::sim::BnRadioSim {
+    std::shared_ptr<::aidl::android::hardware::radio::sim::IRadioSimResponse> respond();
+
     ::ndk::ScopedAStatus areUiccApplicationsEnabled(int32_t serial) override;
     ::ndk::ScopedAStatus changeIccPin2ForApp(int32_t serial, const std::string& oldPin2,
                                              const std::string& newPin2,
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioVoice.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioVoice.h
index 5bf93e0..a0e1e82 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioVoice.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioVoice.h
@@ -23,14 +23,15 @@
 
 class RadioVoice : public RadioCompatBase,
                    public aidl::android::hardware::radio::voice::BnRadioVoice {
+    std::shared_ptr<::aidl::android::hardware::radio::voice::IRadioVoiceResponse> respond();
+
     ::ndk::ScopedAStatus acceptCall(int32_t serial) override;
     ::ndk::ScopedAStatus conference(int32_t serial) override;
     ::ndk::ScopedAStatus dial(
             int32_t serial, const ::aidl::android::hardware::radio::voice::Dial& dialInfo) override;
     ::ndk::ScopedAStatus emergencyDial(
             int32_t serial, const ::aidl::android::hardware::radio::voice::Dial& dialInfo,
-            ::aidl::android::hardware::radio::voice::EmergencyServiceCategory categories,
-            const std::vector<std::string>& urns,
+            int32_t categories, const std::vector<std::string>& urns,
             ::aidl::android::hardware::radio::voice::EmergencyCallRouting routing,
             bool hasKnownUserIntentEmergency, bool isTesting) override;
     ::ndk::ScopedAStatus exitEmergencyCallbackMode(int32_t serial) override;
diff --git a/radio/aidl/compat/libradiocompat/messaging/RadioIndication-messaging.cpp b/radio/aidl/compat/libradiocompat/messaging/RadioIndication-messaging.cpp
index c7342b1..e5c33b3 100644
--- a/radio/aidl/compat/libradiocompat/messaging/RadioIndication-messaging.cpp
+++ b/radio/aidl/compat/libradiocompat/messaging/RadioIndication-messaging.cpp
@@ -27,67 +27,62 @@
 namespace aidl = ::aidl::android::hardware::radio::messaging;
 
 void RadioIndication::setResponseFunction(std::shared_ptr<aidl::IRadioMessagingIndication> rmiCb) {
-    CHECK(rmiCb);
     mMessagingCb = rmiCb;
 }
 
+std::shared_ptr<aidl::IRadioMessagingIndication> RadioIndication::messagingCb() {
+    return mMessagingCb.get();
+}
+
 Return<void> RadioIndication::cdmaNewSms(V1_0::RadioIndicationType type,
                                          const V1_0::CdmaSmsMessage& msg) {
     LOG_CALL << type;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->cdmaNewSms(toAidl(type), toAidl(msg));
+    messagingCb()->cdmaNewSms(toAidl(type), toAidl(msg));
     return {};
 }
 
 Return<void> RadioIndication::cdmaRuimSmsStorageFull(V1_0::RadioIndicationType type) {
     LOG_CALL << type;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->cdmaRuimSmsStorageFull(toAidl(type));
+    messagingCb()->cdmaRuimSmsStorageFull(toAidl(type));
     return {};
 }
 
 Return<void> RadioIndication::newBroadcastSms(V1_0::RadioIndicationType type,
                                               const hidl_vec<uint8_t>& data) {
     LOG_CALL << type;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->newBroadcastSms(toAidl(type), data);
+    messagingCb()->newBroadcastSms(toAidl(type), data);
     return {};
 }
 
 Return<void> RadioIndication::newSms(V1_0::RadioIndicationType type, const hidl_vec<uint8_t>& pdu) {
     LOG_CALL << type;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->newSms(toAidl(type), pdu);
+    messagingCb()->newSms(toAidl(type), pdu);
     return {};
 }
 
 Return<void> RadioIndication::newSmsOnSim(V1_0::RadioIndicationType type, int32_t recordNumber) {
     LOG_CALL << type;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->newSmsOnSim(toAidl(type), recordNumber);
+    messagingCb()->newSmsOnSim(toAidl(type), recordNumber);
     return {};
 }
 
 Return<void> RadioIndication::newSmsStatusReport(V1_0::RadioIndicationType type,
                                                  const hidl_vec<uint8_t>& pdu) {
     LOG_CALL << type;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->newSmsStatusReport(toAidl(type), pdu);
+    messagingCb()->newSmsStatusReport(toAidl(type), pdu);
     return {};
 }
 
 Return<void> RadioIndication::onUssd(V1_0::RadioIndicationType type, V1_0::UssdModeType modeType,
                                      const hidl_string& msg) {
     LOG_CALL << type;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->onUssd(toAidl(type), aidl::UssdModeType(modeType), msg);
+    messagingCb()->onUssd(toAidl(type), aidl::UssdModeType(modeType), msg);
     return {};
 }
 
 Return<void> RadioIndication::simSmsStorageFull(V1_0::RadioIndicationType type) {
     LOG_CALL << type;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->simSmsStorageFull(toAidl(type));
+    messagingCb()->simSmsStorageFull(toAidl(type));
     return {};
 }
 
diff --git a/radio/aidl/compat/libradiocompat/messaging/RadioMessaging.cpp b/radio/aidl/compat/libradiocompat/messaging/RadioMessaging.cpp
index c1a82b5..4d94e17 100644
--- a/radio/aidl/compat/libradiocompat/messaging/RadioMessaging.cpp
+++ b/radio/aidl/compat/libradiocompat/messaging/RadioMessaging.cpp
@@ -29,6 +29,10 @@
 namespace aidl = ::aidl::android::hardware::radio::messaging;
 constexpr auto ok = &ScopedAStatus::ok;
 
+std::shared_ptr<aidl::IRadioMessagingResponse> RadioMessaging::respond() {
+    return mCallbackManager->response().messagingCb();
+}
+
 ScopedAStatus RadioMessaging::acknowledgeIncomingGsmSmsWithPdu(  //
         int32_t serial, bool success, const std::string& ackPdu) {
     LOG_CALL << serial << ' ' << success << ' ' << ackPdu;
@@ -100,13 +104,21 @@
 
 ScopedAStatus RadioMessaging::sendCdmaSms(int32_t serial, const aidl::CdmaSmsMessage& sms) {
     LOG_CALL << serial;
-    mHal1_5->sendCdmaSms(serial, toHidl(sms));
+    if (mHal1_6) {
+        mHal1_6->sendCdmaSms_1_6(serial, toHidl(sms));
+    } else {
+        mHal1_5->sendCdmaSms(serial, toHidl(sms));
+    }
     return ok();
 }
 
 ScopedAStatus RadioMessaging::sendCdmaSmsExpectMore(int32_t serial, const aidl::CdmaSmsMessage& m) {
     LOG_CALL << serial;
-    mHal1_5->sendCdmaSmsExpectMore(serial, toHidl(m));
+    if (mHal1_6) {
+        mHal1_6->sendCdmaSmsExpectMore_1_6(serial, toHidl(m));
+    } else {
+        mHal1_5->sendCdmaSmsExpectMore(serial, toHidl(m));
+    }
     return ok();
 }
 
@@ -118,13 +130,21 @@
 
 ScopedAStatus RadioMessaging::sendSms(int32_t serial, const aidl::GsmSmsMessage& message) {
     LOG_CALL << serial;
-    mHal1_5->sendSms(serial, toHidl(message));
+    if (mHal1_6) {
+        mHal1_6->sendSms_1_6(serial, toHidl(message));
+    } else {
+        mHal1_5->sendSms(serial, toHidl(message));
+    }
     return ok();
 }
 
 ScopedAStatus RadioMessaging::sendSmsExpectMore(int32_t serial, const aidl::GsmSmsMessage& msg) {
     LOG_CALL << serial;
-    mHal1_5->sendSMSExpectMore(serial, toHidl(msg));
+    if (mHal1_6) {
+        mHal1_6->sendSmsExpectMore_1_6(serial, toHidl(msg));
+    } else {
+        mHal1_5->sendSMSExpectMore(serial, toHidl(msg));
+    }
     return ok();
 }
 
@@ -161,16 +181,10 @@
 }
 
 ScopedAStatus RadioMessaging::setResponseFunctions(
-        const std::shared_ptr<aidl::IRadioMessagingResponse>& messagingResponse,
-        const std::shared_ptr<aidl::IRadioMessagingIndication>& messagingIndication) {
-    LOG_CALL << messagingResponse << ' ' << messagingIndication;
-
-    CHECK(messagingResponse);
-    CHECK(messagingIndication);
-
-    mRadioResponse->setResponseFunction(messagingResponse);
-    mRadioIndication->setResponseFunction(messagingIndication);
-
+        const std::shared_ptr<aidl::IRadioMessagingResponse>& response,
+        const std::shared_ptr<aidl::IRadioMessagingIndication>& indication) {
+    LOG_CALL << response << ' ' << indication;
+    mCallbackManager->setResponseFunctions(response, indication);
     return ok();
 }
 
diff --git a/radio/aidl/compat/libradiocompat/messaging/RadioResponse-messaging.cpp b/radio/aidl/compat/libradiocompat/messaging/RadioResponse-messaging.cpp
index 379e463..24ad3d7 100644
--- a/radio/aidl/compat/libradiocompat/messaging/RadioResponse-messaging.cpp
+++ b/radio/aidl/compat/libradiocompat/messaging/RadioResponse-messaging.cpp
@@ -29,52 +29,49 @@
 namespace aidl = ::aidl::android::hardware::radio::messaging;
 
 void RadioResponse::setResponseFunction(std::shared_ptr<aidl::IRadioMessagingResponse> rmrCb) {
-    CHECK(rmrCb);
     mMessagingCb = rmrCb;
 }
 
+std::shared_ptr<aidl::IRadioMessagingResponse> RadioResponse::messagingCb() {
+    return mMessagingCb.get();
+}
+
 Return<void> RadioResponse::acknowledgeIncomingGsmSmsWithPduResponse(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->acknowledgeIncomingGsmSmsWithPduResponse(toAidl(info));
+    messagingCb()->acknowledgeIncomingGsmSmsWithPduResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::acknowledgeLastIncomingCdmaSmsResponse(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->acknowledgeLastIncomingCdmaSmsResponse(toAidl(info));
+    messagingCb()->acknowledgeLastIncomingCdmaSmsResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::acknowledgeLastIncomingGsmSmsResponse(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->acknowledgeLastIncomingGsmSmsResponse(toAidl(info));
+    messagingCb()->acknowledgeLastIncomingGsmSmsResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::cancelPendingUssdResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->cancelPendingUssdResponse(toAidl(info));
+    messagingCb()->cancelPendingUssdResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::deleteSmsOnRuimResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->deleteSmsOnRuimResponse(toAidl(info));
+    messagingCb()->deleteSmsOnRuimResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::deleteSmsOnSimResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->deleteSmsOnSimResponse(toAidl(info));
+    messagingCb()->deleteSmsOnSimResponse(toAidl(info));
     return {};
 }
 
@@ -82,162 +79,141 @@
         const V1_0::RadioResponseInfo& info,
         const hidl_vec<V1_0::CdmaBroadcastSmsConfigInfo>& configs) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->getCdmaBroadcastConfigResponse(toAidl(info), toAidl(configs));
+    messagingCb()->getCdmaBroadcastConfigResponse(toAidl(info), toAidl(configs));
     return {};
 }
 
 Return<void> RadioResponse::getGsmBroadcastConfigResponse(
         const V1_0::RadioResponseInfo& info, const hidl_vec<V1_0::GsmBroadcastSmsConfigInfo>& cfg) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->getGsmBroadcastConfigResponse(toAidl(info), toAidl(cfg));
+    messagingCb()->getGsmBroadcastConfigResponse(toAidl(info), toAidl(cfg));
     return {};
 }
 
 Return<void> RadioResponse::getSmscAddressResponse(const V1_0::RadioResponseInfo& info,
                                                    const hidl_string& smsc) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->getSmscAddressResponse(toAidl(info), smsc);
+    messagingCb()->getSmscAddressResponse(toAidl(info), smsc);
     return {};
 }
 
 Return<void> RadioResponse::reportSmsMemoryStatusResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->reportSmsMemoryStatusResponse(toAidl(info));
+    messagingCb()->reportSmsMemoryStatusResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::sendCdmaSmsExpectMoreResponse(const V1_0::RadioResponseInfo& info,
                                                           const V1_0::SendSmsResult& sms) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->sendCdmaSmsExpectMoreResponse(toAidl(info), toAidl(sms));
+    messagingCb()->sendCdmaSmsExpectMoreResponse(toAidl(info), toAidl(sms));
     return {};
 }
 
 Return<void> RadioResponse::sendCdmaSmsExpectMoreResponse_1_6(const V1_6::RadioResponseInfo& info,
                                                               const V1_0::SendSmsResult& sms) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->sendCdmaSmsExpectMoreResponse(toAidl(info), toAidl(sms));
+    messagingCb()->sendCdmaSmsExpectMoreResponse(toAidl(info), toAidl(sms));
     return {};
 }
 
 Return<void> RadioResponse::sendCdmaSmsResponse(const V1_0::RadioResponseInfo& info,
                                                 const V1_0::SendSmsResult& sms) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->sendCdmaSmsResponse(toAidl(info), toAidl(sms));
+    messagingCb()->sendCdmaSmsResponse(toAidl(info), toAidl(sms));
     return {};
 }
 
 Return<void> RadioResponse::sendCdmaSmsResponse_1_6(const V1_6::RadioResponseInfo& info,
                                                     const V1_0::SendSmsResult& sms) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->sendCdmaSmsResponse(toAidl(info), toAidl(sms));
+    messagingCb()->sendCdmaSmsResponse(toAidl(info), toAidl(sms));
     return {};
 }
 
 Return<void> RadioResponse::sendImsSmsResponse(const V1_0::RadioResponseInfo& info,
                                                const V1_0::SendSmsResult& sms) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->sendImsSmsResponse(toAidl(info), toAidl(sms));
+    messagingCb()->sendImsSmsResponse(toAidl(info), toAidl(sms));
     return {};
 }
 
 Return<void> RadioResponse::sendSMSExpectMoreResponse(const V1_0::RadioResponseInfo& info,
                                                       const V1_0::SendSmsResult& sms) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->sendSmsExpectMoreResponse(toAidl(info), toAidl(sms));
+    messagingCb()->sendSmsExpectMoreResponse(toAidl(info), toAidl(sms));
     return {};
 }
 
 Return<void> RadioResponse::sendSmsExpectMoreResponse_1_6(const V1_6::RadioResponseInfo& info,
                                                           const V1_0::SendSmsResult& sms) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->sendSmsExpectMoreResponse(toAidl(info), toAidl(sms));
+    messagingCb()->sendSmsExpectMoreResponse(toAidl(info), toAidl(sms));
     return {};
 }
 
 Return<void> RadioResponse::sendSmsResponse(const V1_0::RadioResponseInfo& info,
                                             const V1_0::SendSmsResult& sms) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->sendSmsResponse(toAidl(info), toAidl(sms));
+    messagingCb()->sendSmsResponse(toAidl(info), toAidl(sms));
     return {};
 }
 
 Return<void> RadioResponse::sendSmsResponse_1_6(const V1_6::RadioResponseInfo& info,
                                                 const V1_0::SendSmsResult& sms) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->sendSmsResponse(toAidl(info), toAidl(sms));
+    messagingCb()->sendSmsResponse(toAidl(info), toAidl(sms));
     return {};
 }
 
 Return<void> RadioResponse::sendUssdResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->sendUssdResponse(toAidl(info));
+    messagingCb()->sendUssdResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setCdmaBroadcastActivationResponse(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->setCdmaBroadcastActivationResponse(toAidl(info));
+    messagingCb()->setCdmaBroadcastActivationResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setCdmaBroadcastConfigResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->setCdmaBroadcastConfigResponse(toAidl(info));
+    messagingCb()->setCdmaBroadcastConfigResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setGsmBroadcastActivationResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->setGsmBroadcastActivationResponse(toAidl(info));
+    messagingCb()->setGsmBroadcastActivationResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setGsmBroadcastConfigResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->setGsmBroadcastConfigResponse(toAidl(info));
+    messagingCb()->setGsmBroadcastConfigResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setSmscAddressResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->setSmscAddressResponse(toAidl(info));
+    messagingCb()->setSmscAddressResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::writeSmsToRuimResponse(const V1_0::RadioResponseInfo& info,
                                                    uint32_t index) {
     LOG_CALL << info.serial << ' ' << index;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->writeSmsToRuimResponse(toAidl(info), index);
+    messagingCb()->writeSmsToRuimResponse(toAidl(info), index);
     return {};
 }
 
 Return<void> RadioResponse::writeSmsToSimResponse(const V1_0::RadioResponseInfo& info,
                                                   int32_t index) {
     LOG_CALL << info.serial << ' ' << index;
-    CHECK_CB(mMessagingCb);
-    mMessagingCb->writeSmsToSimResponse(toAidl(info), index);
+    messagingCb()->writeSmsToSimResponse(toAidl(info), index);
     return {};
 }
 
diff --git a/radio/aidl/compat/libradiocompat/modem/RadioIndication-modem.cpp b/radio/aidl/compat/libradiocompat/modem/RadioIndication-modem.cpp
index 8fc4da6..851c93b 100644
--- a/radio/aidl/compat/libradiocompat/modem/RadioIndication-modem.cpp
+++ b/radio/aidl/compat/libradiocompat/modem/RadioIndication-modem.cpp
@@ -29,44 +29,42 @@
 namespace aidl = ::aidl::android::hardware::radio::modem;
 
 void RadioIndication::setResponseFunction(std::shared_ptr<aidl::IRadioModemIndication> modemCb) {
-    CHECK(modemCb);
     mModemCb = modemCb;
 }
 
+std::shared_ptr<aidl::IRadioModemIndication> RadioIndication::modemCb() {
+    return mModemCb.get();
+}
+
 Return<void> RadioIndication::hardwareConfigChanged(V1_0::RadioIndicationType type,
                                                     const hidl_vec<V1_0::HardwareConfig>& configs) {
     LOG_CALL << type;
-    CHECK_CB(mModemCb);
-    mModemCb->hardwareConfigChanged(toAidl(type), toAidl(configs));
+    modemCb()->hardwareConfigChanged(toAidl(type), toAidl(configs));
     return {};
 }
 
 Return<void> RadioIndication::modemReset(V1_0::RadioIndicationType type, const hidl_string& reasn) {
     LOG_CALL << type;
-    CHECK_CB(mModemCb);
-    mModemCb->modemReset(toAidl(type), reasn);
+    modemCb()->modemReset(toAidl(type), reasn);
     return {};
 }
 
 Return<void> RadioIndication::radioCapabilityIndication(V1_0::RadioIndicationType type,
                                                         const V1_0::RadioCapability& rc) {
     LOG_CALL << type;
-    CHECK_CB(mModemCb);
-    mModemCb->radioCapabilityIndication(toAidl(type), toAidl(rc));
+    modemCb()->radioCapabilityIndication(toAidl(type), toAidl(rc));
     return {};
 }
 
 Return<void> RadioIndication::radioStateChanged(V1_0::RadioIndicationType t, V1_0::RadioState st) {
     LOG_CALL << t;
-    CHECK_CB(mModemCb);
-    mModemCb->radioStateChanged(toAidl(t), aidl::RadioState(st));
+    modemCb()->radioStateChanged(toAidl(t), aidl::RadioState(st));
     return {};
 }
 
 Return<void> RadioIndication::rilConnected(V1_0::RadioIndicationType type) {
     LOG_CALL << type;
-    CHECK_CB(mModemCb);
-    mModemCb->rilConnected(toAidl(type));
+    modemCb()->rilConnected(toAidl(type));
     return {};
 }
 
diff --git a/radio/aidl/compat/libradiocompat/modem/RadioModem.cpp b/radio/aidl/compat/libradiocompat/modem/RadioModem.cpp
index 660ae9f..d28b940 100644
--- a/radio/aidl/compat/libradiocompat/modem/RadioModem.cpp
+++ b/radio/aidl/compat/libradiocompat/modem/RadioModem.cpp
@@ -27,6 +27,10 @@
 namespace aidl = ::aidl::android::hardware::radio::modem;
 constexpr auto ok = &ScopedAStatus::ok;
 
+std::shared_ptr<aidl::IRadioModemResponse> RadioModem::respond() {
+    return mCallbackManager->response().modemCb();
+}
+
 ScopedAStatus RadioModem::enableModem(int32_t serial, bool on) {
     LOG_CALL << serial;
     mHal1_5->enableModem(serial, on);
@@ -129,16 +133,10 @@
 }
 
 ScopedAStatus RadioModem::setResponseFunctions(
-        const std::shared_ptr<aidl::IRadioModemResponse>& modemResponse,
-        const std::shared_ptr<aidl::IRadioModemIndication>& modemIndication) {
-    LOG_CALL << modemResponse << ' ' << modemIndication;
-
-    CHECK(modemResponse);
-    CHECK(modemIndication);
-
-    mRadioResponse->setResponseFunction(modemResponse);
-    mRadioIndication->setResponseFunction(modemIndication);
-
+        const std::shared_ptr<aidl::IRadioModemResponse>& response,
+        const std::shared_ptr<aidl::IRadioModemIndication>& indication) {
+    LOG_CALL << response << ' ' << indication;
+    mCallbackManager->setResponseFunctions(response, indication);
     return ok();
 }
 
diff --git a/radio/aidl/compat/libradiocompat/modem/RadioResponse-modem.cpp b/radio/aidl/compat/libradiocompat/modem/RadioResponse-modem.cpp
index 300627c..6e1a962 100644
--- a/radio/aidl/compat/libradiocompat/modem/RadioResponse-modem.cpp
+++ b/radio/aidl/compat/libradiocompat/modem/RadioResponse-modem.cpp
@@ -29,22 +29,23 @@
 namespace aidl = ::aidl::android::hardware::radio::modem;
 
 void RadioResponse::setResponseFunction(std::shared_ptr<aidl::IRadioModemResponse> modemCb) {
-    CHECK(modemCb);
     mModemCb = modemCb;
 }
 
+std::shared_ptr<aidl::IRadioModemResponse> RadioResponse::modemCb() {
+    return mModemCb.get();
+}
+
 Return<void> RadioResponse::enableModemResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->enableModemResponse(toAidl(info));
+    modemCb()->enableModemResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::getBasebandVersionResponse(const V1_0::RadioResponseInfo& info,
                                                        const hidl_string& version) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->getBasebandVersionResponse(toAidl(info), version);
+    modemCb()->getBasebandVersionResponse(toAidl(info), version);
     return {};
 }
 
@@ -52,112 +53,97 @@
         const V1_0::RadioResponseInfo& info, const hidl_string& imei, const hidl_string& imeisv,
         const hidl_string& esn, const hidl_string& meid) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->getDeviceIdentityResponse(toAidl(info), imei, imeisv, esn, meid);
+    modemCb()->getDeviceIdentityResponse(toAidl(info), imei, imeisv, esn, meid);
     return {};
 }
 
 Return<void> RadioResponse::getHardwareConfigResponse(
         const V1_0::RadioResponseInfo& info, const hidl_vec<V1_0::HardwareConfig>& config) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->getHardwareConfigResponse(toAidl(info), toAidl(config));
+    modemCb()->getHardwareConfigResponse(toAidl(info), toAidl(config));
     return {};
 }
 
 Return<void> RadioResponse::getModemActivityInfoResponse(
         const V1_0::RadioResponseInfo& info, const V1_0::ActivityStatsInfo& activityInfo) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->getModemActivityInfoResponse(toAidl(info), toAidl(activityInfo));
+    modemCb()->getModemActivityInfoResponse(toAidl(info), toAidl(activityInfo));
     return {};
 }
 
 Return<void> RadioResponse::getModemStackStatusResponse(const V1_0::RadioResponseInfo& info,
                                                         bool isEnabled) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->getModemStackStatusResponse(toAidl(info), isEnabled);
+    modemCb()->getModemStackStatusResponse(toAidl(info), isEnabled);
     return {};
 }
 
 Return<void> RadioResponse::getRadioCapabilityResponse(const V1_0::RadioResponseInfo& info,
                                                        const V1_0::RadioCapability& rc) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->getRadioCapabilityResponse(toAidl(info), toAidl(rc));
+    modemCb()->getRadioCapabilityResponse(toAidl(info), toAidl(rc));
     return {};
 }
 
 Return<void> RadioResponse::nvReadItemResponse(const V1_0::RadioResponseInfo& info,
                                                const hidl_string& result) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->nvReadItemResponse(toAidl(info), result);
+    modemCb()->nvReadItemResponse(toAidl(info), result);
     return {};
 }
 
 Return<void> RadioResponse::nvResetConfigResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->nvResetConfigResponse(toAidl(info));
+    modemCb()->nvResetConfigResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::nvWriteCdmaPrlResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->nvWriteCdmaPrlResponse(toAidl(info));
+    modemCb()->nvWriteCdmaPrlResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::nvWriteItemResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->nvWriteItemResponse(toAidl(info));
+    modemCb()->nvWriteItemResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::requestShutdownResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->requestShutdownResponse(toAidl(info));
+    modemCb()->requestShutdownResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::sendDeviceStateResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->sendDeviceStateResponse(toAidl(info));
+    modemCb()->sendDeviceStateResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setRadioCapabilityResponse(const V1_0::RadioResponseInfo& info,
                                                        const V1_0::RadioCapability& rc) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->setRadioCapabilityResponse(toAidl(info), toAidl(rc));
+    modemCb()->setRadioCapabilityResponse(toAidl(info), toAidl(rc));
     return {};
 }
 
 Return<void> RadioResponse::setRadioPowerResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->setRadioPowerResponse(toAidl(info));
+    modemCb()->setRadioPowerResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setRadioPowerResponse_1_5(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->setRadioPowerResponse(toAidl(info));
+    modemCb()->setRadioPowerResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setRadioPowerResponse_1_6(const V1_6::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mModemCb);
-    mModemCb->setRadioPowerResponse(toAidl(info));
+    modemCb()->setRadioPowerResponse(toAidl(info));
     return {};
 }
 
diff --git a/radio/aidl/compat/libradiocompat/modem/structs.cpp b/radio/aidl/compat/libradiocompat/modem/structs.cpp
index 53d5753..69e651b 100644
--- a/radio/aidl/compat/libradiocompat/modem/structs.cpp
+++ b/radio/aidl/compat/libradiocompat/modem/structs.cpp
@@ -25,7 +25,6 @@
 namespace android::hardware::radio::compat {
 
 using ::aidl::android::hardware::radio::AccessNetwork;
-using ::aidl::android::hardware::radio::RadioAccessFamily;
 using ::aidl::android::hardware::radio::RadioTechnology;
 namespace aidl = ::aidl::android::hardware::radio::modem;
 
@@ -40,7 +39,7 @@
     return {
             .session = capa.session,
             .phase = static_cast<int32_t>(capa.phase),
-            .raf = RadioAccessFamily(capa.raf),
+            .raf = static_cast<int32_t>(capa.raf),
             .logicalModemUuid = capa.logicalModemUuid,
             .status = static_cast<int32_t>(capa.status),
     };
diff --git a/radio/aidl/compat/libradiocompat/network/RadioIndication-network.cpp b/radio/aidl/compat/libradiocompat/network/RadioIndication-network.cpp
index 899b133..4eb99f7 100644
--- a/radio/aidl/compat/libradiocompat/network/RadioIndication-network.cpp
+++ b/radio/aidl/compat/libradiocompat/network/RadioIndication-network.cpp
@@ -30,23 +30,24 @@
 namespace aidl = ::aidl::android::hardware::radio::network;
 
 void RadioIndication::setResponseFunction(std::shared_ptr<aidl::IRadioNetworkIndication> netCb) {
-    CHECK(netCb);
     mNetworkCb = netCb;
 }
 
+std::shared_ptr<aidl::IRadioNetworkIndication> RadioIndication::networkCb() {
+    return mNetworkCb.get();
+}
+
 Return<void> RadioIndication::barringInfoChanged(V1_0::RadioIndicationType type,
                                                  const V1_5::CellIdentity& cellIdentity,
                                                  const hidl_vec<V1_5::BarringInfo>& barringInfos) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->barringInfoChanged(toAidl(type), toAidl(cellIdentity), toAidl(barringInfos));
+    networkCb()->barringInfoChanged(toAidl(type), toAidl(cellIdentity), toAidl(barringInfos));
     return {};
 }
 
 Return<void> RadioIndication::cdmaPrlChanged(V1_0::RadioIndicationType type, int32_t version) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->cdmaPrlChanged(toAidl(type), version);
+    networkCb()->cdmaPrlChanged(toAidl(type), version);
     return {};
 }
 
@@ -74,32 +75,28 @@
 Return<void> RadioIndication::cellInfoList_1_5(V1_0::RadioIndicationType type,
                                                const hidl_vec<V1_5::CellInfo>& records) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->cellInfoList(toAidl(type), toAidl(records));
+    networkCb()->cellInfoList(toAidl(type), toAidl(records));
     return {};
 }
 
 Return<void> RadioIndication::cellInfoList_1_6(V1_0::RadioIndicationType type,
                                                const hidl_vec<V1_6::CellInfo>& records) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->cellInfoList(toAidl(type), toAidl(records));
+    networkCb()->cellInfoList(toAidl(type), toAidl(records));
     return {};
 }
 
 Return<void> RadioIndication::currentLinkCapacityEstimate(V1_0::RadioIndicationType type,
                                                           const V1_2::LinkCapacityEstimate& lce) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->currentLinkCapacityEstimate(toAidl(type), toAidl(lce));
+    networkCb()->currentLinkCapacityEstimate(toAidl(type), toAidl(lce));
     return {};
 }
 
 Return<void> RadioIndication::currentLinkCapacityEstimate_1_6(
         V1_0::RadioIndicationType type, const V1_6::LinkCapacityEstimate& lce) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->currentLinkCapacityEstimate(toAidl(type), toAidl(lce));
+    networkCb()->currentLinkCapacityEstimate(toAidl(type), toAidl(lce));
     return {};
 }
 
@@ -113,16 +110,14 @@
 Return<void> RadioIndication::currentPhysicalChannelConfigs_1_4(
         V1_0::RadioIndicationType type, const hidl_vec<V1_4::PhysicalChannelConfig>& configs) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->currentPhysicalChannelConfigs(toAidl(type), toAidl(configs));
+    networkCb()->currentPhysicalChannelConfigs(toAidl(type), toAidl(configs));
     return {};
 }
 
 Return<void> RadioIndication::currentPhysicalChannelConfigs_1_6(
         V1_0::RadioIndicationType type, const hidl_vec<V1_6::PhysicalChannelConfig>& configs) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->currentPhysicalChannelConfigs(toAidl(type), toAidl(configs));
+    networkCb()->currentPhysicalChannelConfigs(toAidl(type), toAidl(configs));
     return {};
 }
 
@@ -143,23 +138,20 @@
 Return<void> RadioIndication::currentSignalStrength_1_4(
         V1_0::RadioIndicationType type, const V1_4::SignalStrength& signalStrength) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->currentSignalStrength(toAidl(type), toAidl(signalStrength));
+    networkCb()->currentSignalStrength(toAidl(type), toAidl(signalStrength));
     return {};
 }
 
 Return<void> RadioIndication::currentSignalStrength_1_6(
         V1_0::RadioIndicationType type, const V1_6::SignalStrength& signalStrength) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->currentSignalStrength(toAidl(type), toAidl(signalStrength));
+    networkCb()->currentSignalStrength(toAidl(type), toAidl(signalStrength));
     return {};
 }
 
 Return<void> RadioIndication::imsNetworkStateChanged(V1_0::RadioIndicationType type) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->imsNetworkStateChanged(toAidl(type));
+    networkCb()->imsNetworkStateChanged(toAidl(type));
     return {};
 }
 
@@ -187,31 +179,27 @@
 Return<void> RadioIndication::networkScanResult_1_5(V1_0::RadioIndicationType type,
                                                     const V1_5::NetworkScanResult& result) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->networkScanResult(toAidl(type), toAidl(result));
+    networkCb()->networkScanResult(toAidl(type), toAidl(result));
     return {};
 }
 
 Return<void> RadioIndication::networkScanResult_1_6(V1_0::RadioIndicationType type,
                                                     const V1_6::NetworkScanResult& result) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->networkScanResult(toAidl(type), toAidl(result));
+    networkCb()->networkScanResult(toAidl(type), toAidl(result));
     return {};
 }
 
 Return<void> RadioIndication::networkStateChanged(V1_0::RadioIndicationType type) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->networkStateChanged(toAidl(type));
+    networkCb()->networkStateChanged(toAidl(type));
     return {};
 }
 
 Return<void> RadioIndication::nitzTimeReceived(V1_0::RadioIndicationType type,
                                                const hidl_string& nitzTime, uint64_t receivedTime) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->nitzTimeReceived(toAidl(type), nitzTime, receivedTime, 0);
+    networkCb()->nitzTimeReceived(toAidl(type), nitzTime, receivedTime, 0);
     return {};
 }
 
@@ -220,33 +208,29 @@
         const hidl_string& chosenPlmn, hidl_bitfield<V1_5::Domain> domain, int32_t causeCode,
         int32_t additionalCauseCode) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->registrationFailed(toAidl(type), toAidl(cellIdentity), chosenPlmn,
-                                   aidl::Domain(domain), causeCode, additionalCauseCode);
+    networkCb()->registrationFailed(toAidl(type), toAidl(cellIdentity), chosenPlmn, domain,
+                                    causeCode, additionalCauseCode);
     return {};
 }
 
 Return<void> RadioIndication::restrictedStateChanged(V1_0::RadioIndicationType type,
                                                      V1_0::PhoneRestrictedState state) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->restrictedStateChanged(toAidl(type), aidl::PhoneRestrictedState(state));
+    networkCb()->restrictedStateChanged(toAidl(type), aidl::PhoneRestrictedState(state));
     return {};
 }
 
 Return<void> RadioIndication::suppSvcNotify(V1_0::RadioIndicationType type,
                                             const V1_0::SuppSvcNotification& suppSvc) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->suppSvcNotify(toAidl(type), toAidl(suppSvc));
+    networkCb()->suppSvcNotify(toAidl(type), toAidl(suppSvc));
     return {};
 }
 
 Return<void> RadioIndication::voiceRadioTechChanged(V1_0::RadioIndicationType type,
                                                     V1_0::RadioTechnology rat) {
     LOG_CALL << type;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->voiceRadioTechChanged(toAidl(type), RadioTechnology(rat));
+    networkCb()->voiceRadioTechChanged(toAidl(type), RadioTechnology(rat));
     return {};
 }
 
diff --git a/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp b/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp
index af0bc46..22b9ede 100644
--- a/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp
+++ b/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp
@@ -28,11 +28,14 @@
 namespace android::hardware::radio::compat {
 
 using ::aidl::android::hardware::radio::AccessNetwork;
-using ::aidl::android::hardware::radio::RadioAccessFamily;
 using ::ndk::ScopedAStatus;
 namespace aidl = ::aidl::android::hardware::radio::network;
 constexpr auto ok = &ScopedAStatus::ok;
 
+std::shared_ptr<aidl::IRadioNetworkResponse> RadioNetwork::respond() {
+    return mCallbackManager->response().networkCb();
+}
+
 ScopedAStatus RadioNetwork::getAllowedNetworkTypesBitmap(int32_t serial) {
     LOG_CALL << serial;
     if (mHal1_6) {
@@ -69,13 +72,21 @@
 
 ScopedAStatus RadioNetwork::getCellInfoList(int32_t serial) {
     LOG_CALL << serial;
-    mHal1_5->getCellInfoList(serial);
+    if (mHal1_6) {
+        mHal1_6->getCellInfoList_1_6(serial);
+    } else {
+        mHal1_5->getCellInfoList(serial);
+    }
     return ok();
 }
 
 ScopedAStatus RadioNetwork::getDataRegistrationState(int32_t serial) {
     LOG_CALL << serial;
-    mHal1_5->getDataRegistrationState(serial);
+    if (mHal1_6) {
+        mHal1_6->getDataRegistrationState_1_6(serial);
+    } else {
+        mHal1_5->getDataRegistrationState_1_5(serial);
+    }
     return ok();
 }
 
@@ -99,7 +110,11 @@
 
 ScopedAStatus RadioNetwork::getSignalStrength(int32_t serial) {
     LOG_CALL << serial;
-    mHal1_5->getSignalStrength(serial);
+    if (mHal1_6) {
+        mHal1_6->getSignalStrength_1_6(serial);
+    } else {
+        mHal1_5->getSignalStrength_1_4(serial);
+    }
     return ok();
 }
 
@@ -108,7 +123,7 @@
     if (mHal1_6) {
         mHal1_6->getSystemSelectionChannels(serial);
     } else {
-        respond().getSystemSelectionChannelsResponse(notSupported(serial), {});
+        respond()->getSystemSelectionChannelsResponse(notSupported(serial), {});
     }
     return ok();
 }
@@ -121,7 +136,11 @@
 
 ScopedAStatus RadioNetwork::getVoiceRegistrationState(int32_t serial) {
     LOG_CALL << serial;
-    mHal1_5->getVoiceRegistrationState(serial);
+    if (mHal1_6) {
+        mHal1_6->getVoiceRegistrationState_1_6(serial);
+    } else {
+        mHal1_5->getVoiceRegistrationState_1_5(serial);
+    }
     return ok();
 }
 
@@ -130,7 +149,7 @@
     if (mHal1_6) {
         mHal1_6->isNrDualConnectivityEnabled(serial);
     } else {
-        respond().isNrDualConnectivityEnabledResponse(notSupported(serial), false);
+        respond()->isNrDualConnectivityEnabledResponse(notSupported(serial), false);
     }
     return ok();
 }
@@ -141,7 +160,7 @@
     return ok();
 }
 
-ScopedAStatus RadioNetwork::setAllowedNetworkTypesBitmap(int32_t serial, RadioAccessFamily ntype) {
+ScopedAStatus RadioNetwork::setAllowedNetworkTypesBitmap(int32_t serial, int32_t ntype) {
     LOG_CALL << serial;
     const auto raf = toHidlBitfield<V1_4::RadioAccessFamily>(ntype);
     if (mHal1_6) {
@@ -177,9 +196,9 @@
     return ok();
 }
 
-ScopedAStatus RadioNetwork::setIndicationFilter(int32_t serial, aidl::IndicationFilter indFilter) {
+ScopedAStatus RadioNetwork::setIndicationFilter(int32_t serial, int32_t indFilter) {
     LOG_CALL << serial;
-    mHal1_5->setIndicationFilter(serial, toHidlBitfield<V1_0::IndicationFilter>(indFilter));
+    mHal1_5->setIndicationFilter_1_5(serial, toHidlBitfield<V1_5::IndicationFilter>(indFilter));
     return ok();
 }
 
@@ -188,9 +207,9 @@
         const std::vector<int32_t>& thrDownlinkKbps, const std::vector<int32_t>& thrUplinkKbps,
         AccessNetwork accessNetwork) {
     LOG_CALL << serial;
-    mHal1_5->setLinkCapacityReportingCriteria(  //
+    mHal1_5->setLinkCapacityReportingCriteria_1_5(  //
             serial, hysteresisMs, hysteresisDlKbps, hysteresisUlKbps, thrDownlinkKbps,
-            thrUplinkKbps, V1_2::AccessNetwork(accessNetwork));
+            thrUplinkKbps, V1_5::AccessNetwork(accessNetwork));
     return ok();
 }
 
@@ -219,29 +238,29 @@
     if (mHal1_6) {
         mHal1_6->setNrDualConnectivityState(serial, V1_6::NrDualConnectivityState(st));
     } else {
-        respond().setNrDualConnectivityStateResponse(notSupported(serial));
+        respond()->setNrDualConnectivityStateResponse(notSupported(serial));
     }
     return ok();
 }
 
 ScopedAStatus RadioNetwork::setResponseFunctions(
-        const std::shared_ptr<aidl::IRadioNetworkResponse>& networkResponse,
-        const std::shared_ptr<aidl::IRadioNetworkIndication>& networkIndication) {
-    LOG_CALL << networkResponse << ' ' << networkIndication;
-
-    CHECK(networkResponse);
-    CHECK(networkIndication);
-
-    mRadioResponse->setResponseFunction(networkResponse);
-    mRadioIndication->setResponseFunction(networkIndication);
-
+        const std::shared_ptr<aidl::IRadioNetworkResponse>& response,
+        const std::shared_ptr<aidl::IRadioNetworkIndication>& indication) {
+    LOG_CALL << response << ' ' << indication;
+    mCallbackManager->setResponseFunctions(response, indication);
     return ok();
 }
 
 ScopedAStatus RadioNetwork::setSignalStrengthReportingCriteria(
         int32_t serial, const std::vector<aidl::SignalThresholdInfo>& infos) {
     LOG_CALL << serial;
-    // TODO(b/203699028): how about other infos?
+    if (infos.size() == 0) {
+        LOG(ERROR) << "Threshold info array is empty - dropping setSignalStrengthReportingCriteria";
+        return ok();
+    }
+    if (infos.size() > 1) {
+        LOG(WARNING) << "Multi-element reporting criteria are not supported with HIDL HAL";
+    }
     mHal1_5->setSignalStrengthReportingCriteria_1_5(serial, toHidl(infos[0]),
                                                     V1_5::AccessNetwork(infos[0].ran));
     return ok();
@@ -278,4 +297,18 @@
     return ok();
 }
 
+ScopedAStatus RadioNetwork::setUsageSetting(int32_t serial, aidl::UsageSetting) {
+    LOG_CALL << serial;
+    LOG(ERROR) << "setUsageSetting is unsupported by HIDL HALs";
+    respond()->setUsageSettingResponse(notSupported(serial));
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::getUsageSetting(int32_t serial) {
+    LOG_CALL << serial;
+    LOG(ERROR) << "getUsageSetting is unsupported by HIDL HALs";
+    respond()->getUsageSettingResponse(notSupported(serial), {});  // {} = neither voice nor data
+    return ok();
+}
+
 }  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/network/RadioResponse-network.cpp b/radio/aidl/compat/libradiocompat/network/RadioResponse-network.cpp
index 81f7775..5a98eb2 100644
--- a/radio/aidl/compat/libradiocompat/network/RadioResponse-network.cpp
+++ b/radio/aidl/compat/libradiocompat/network/RadioResponse-network.cpp
@@ -27,32 +27,30 @@
 
 namespace android::hardware::radio::compat {
 
-using ::aidl::android::hardware::radio::RadioAccessFamily;
 using ::aidl::android::hardware::radio::RadioTechnology;
 using ::aidl::android::hardware::radio::RadioTechnologyFamily;
 namespace aidl = ::aidl::android::hardware::radio::network;
 
 void RadioResponse::setResponseFunction(std::shared_ptr<aidl::IRadioNetworkResponse> netCb) {
-    CHECK(netCb);
     mNetworkCb = netCb;
 }
 
+std::shared_ptr<aidl::IRadioNetworkResponse> RadioResponse::networkCb() {
+    return mNetworkCb.get();
+}
+
 Return<void> RadioResponse::getAllowedNetworkTypesBitmapResponse(
         const V1_6::RadioResponseInfo& info,
         hidl_bitfield<V1_4::RadioAccessFamily> networkTypeBitmap) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getAllowedNetworkTypesBitmapResponse(toAidl(info),
-                                                     RadioAccessFamily(networkTypeBitmap));
+    networkCb()->getAllowedNetworkTypesBitmapResponse(toAidl(info), networkTypeBitmap);
     return {};
 }
 
 Return<void> RadioResponse::getPreferredNetworkTypeResponse(const V1_0::RadioResponseInfo& info,
                                                             V1_0::PreferredNetworkType nwType) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getAllowedNetworkTypesBitmapResponse(  //
-            toAidl(info), RadioAccessFamily(getRafFromNetworkType(nwType)));
+    networkCb()->getAllowedNetworkTypesBitmapResponse(toAidl(info), getRafFromNetworkType(nwType));
     return {};
 }
 
@@ -66,16 +64,14 @@
 Return<void> RadioResponse::getAvailableBandModesResponse(
         const V1_0::RadioResponseInfo& info, const hidl_vec<V1_0::RadioBandMode>& bandModes) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getAvailableBandModesResponse(toAidl(info), toAidl(bandModes));
+    networkCb()->getAvailableBandModesResponse(toAidl(info), toAidl(bandModes));
     return {};
 }
 
 Return<void> RadioResponse::getAvailableNetworksResponse(
         const V1_0::RadioResponseInfo& info, const hidl_vec<V1_0::OperatorInfo>& networkInfos) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getAvailableNetworksResponse(toAidl(info), toAidl(networkInfos));
+    networkCb()->getAvailableNetworksResponse(toAidl(info), toAidl(networkInfos));
     return {};
 }
 
@@ -83,16 +79,14 @@
         const V1_0::RadioResponseInfo& info, const V1_5::CellIdentity& cellIdentity,
         const hidl_vec<V1_5::BarringInfo>& barringInfos) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getBarringInfoResponse(toAidl(info), toAidl(cellIdentity), toAidl(barringInfos));
+    networkCb()->getBarringInfoResponse(toAidl(info), toAidl(cellIdentity), toAidl(barringInfos));
     return {};
 }
 
 Return<void> RadioResponse::getCdmaRoamingPreferenceResponse(const V1_0::RadioResponseInfo& info,
                                                              V1_0::CdmaRoamingType type) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getCdmaRoamingPreferenceResponse(toAidl(info), aidl::CdmaRoamingType(type));
+    networkCb()->getCdmaRoamingPreferenceResponse(toAidl(info), aidl::CdmaRoamingType(type));
     return {};
 }
 
@@ -120,16 +114,14 @@
 Return<void> RadioResponse::getCellInfoListResponse_1_5(const V1_0::RadioResponseInfo& info,
                                                         const hidl_vec<V1_5::CellInfo>& cellInfo) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getCellInfoListResponse(toAidl(info), toAidl(cellInfo));
+    networkCb()->getCellInfoListResponse(toAidl(info), toAidl(cellInfo));
     return {};
 }
 
 Return<void> RadioResponse::getCellInfoListResponse_1_6(const V1_6::RadioResponseInfo& info,
                                                         const hidl_vec<V1_6::CellInfo>& cellInfo) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getCellInfoListResponse(toAidl(info), toAidl(cellInfo));
+    networkCb()->getCellInfoListResponse(toAidl(info), toAidl(cellInfo));
     return {};
 }
 
@@ -157,25 +149,22 @@
 Return<void> RadioResponse::getDataRegistrationStateResponse_1_5(
         const V1_0::RadioResponseInfo& info, const V1_5::RegStateResult& dataRegResponse) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getDataRegistrationStateResponse(toAidl(info), toAidl(dataRegResponse));
+    networkCb()->getDataRegistrationStateResponse(toAidl(info), toAidl(dataRegResponse));
     return {};
 }
 
 Return<void> RadioResponse::getDataRegistrationStateResponse_1_6(
         const V1_6::RadioResponseInfo& info, const V1_6::RegStateResult& dataRegResponse) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getDataRegistrationStateResponse(toAidl(info), toAidl(dataRegResponse));
+    networkCb()->getDataRegistrationStateResponse(toAidl(info), toAidl(dataRegResponse));
     return {};
 }
 
 Return<void> RadioResponse::getImsRegistrationStateResponse(  //
         const V1_0::RadioResponseInfo& info, bool isRegd, V1_0::RadioTechnologyFamily ratFamily) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getImsRegistrationStateResponse(toAidl(info), isRegd,
-                                                RadioTechnologyFamily(ratFamily));
+    networkCb()->getImsRegistrationStateResponse(toAidl(info), isRegd,
+                                                 RadioTechnologyFamily(ratFamily));
     return {};
 }
 
@@ -189,8 +178,7 @@
 Return<void> RadioResponse::getNetworkSelectionModeResponse(const V1_0::RadioResponseInfo& info,
                                                             bool manual) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getNetworkSelectionModeResponse(toAidl(info), manual);
+    networkCb()->getNetworkSelectionModeResponse(toAidl(info), manual);
     return {};
 }
 
@@ -198,8 +186,7 @@
         const V1_0::RadioResponseInfo& info, const hidl_string& longName,
         const hidl_string& shortName, const hidl_string& numeric) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getOperatorResponse(toAidl(info), longName, shortName, numeric);
+    networkCb()->getOperatorResponse(toAidl(info), longName, shortName, numeric);
     return {};
 }
 
@@ -220,16 +207,14 @@
 Return<void> RadioResponse::getSignalStrengthResponse_1_4(
         const V1_0::RadioResponseInfo& info, const V1_4::SignalStrength& signalStrength) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getSignalStrengthResponse(toAidl(info), toAidl(signalStrength));
+    networkCb()->getSignalStrengthResponse(toAidl(info), toAidl(signalStrength));
     return {};
 }
 
 Return<void> RadioResponse::getSignalStrengthResponse_1_6(
         const V1_6::RadioResponseInfo& info, const V1_6::SignalStrength& signalStrength) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getSignalStrengthResponse(toAidl(info), toAidl(signalStrength));
+    networkCb()->getSignalStrengthResponse(toAidl(info), toAidl(signalStrength));
     return {};
 }
 
@@ -237,16 +222,14 @@
         const V1_6::RadioResponseInfo& info,
         const hidl_vec<V1_5::RadioAccessSpecifier>& specifiers) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getSystemSelectionChannelsResponse(toAidl(info), toAidl(specifiers));
+    networkCb()->getSystemSelectionChannelsResponse(toAidl(info), toAidl(specifiers));
     return {};
 }
 
 Return<void> RadioResponse::getVoiceRadioTechnologyResponse(const V1_0::RadioResponseInfo& info,
                                                             V1_0::RadioTechnology rat) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getVoiceRadioTechnologyResponse(toAidl(info), RadioTechnology(rat));
+    networkCb()->getVoiceRadioTechnologyResponse(toAidl(info), RadioTechnology(rat));
     return {};
 }
 
@@ -267,24 +250,21 @@
 Return<void> RadioResponse::getVoiceRegistrationStateResponse_1_5(
         const V1_0::RadioResponseInfo& info, const V1_5::RegStateResult& voiceRegResponse) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getVoiceRegistrationStateResponse(toAidl(info), toAidl(voiceRegResponse));
+    networkCb()->getVoiceRegistrationStateResponse(toAidl(info), toAidl(voiceRegResponse));
     return {};
 }
 
 Return<void> RadioResponse::getVoiceRegistrationStateResponse_1_6(
         const V1_6::RadioResponseInfo& info, const V1_6::RegStateResult& voiceRegResponse) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->getVoiceRegistrationStateResponse(toAidl(info), toAidl(voiceRegResponse));
+    networkCb()->getVoiceRegistrationStateResponse(toAidl(info), toAidl(voiceRegResponse));
     return {};
 }
 
 Return<void> RadioResponse::isNrDualConnectivityEnabledResponse(const V1_6::RadioResponseInfo& info,
                                                                 bool isEnabled) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->isNrDualConnectivityEnabledResponse(toAidl(info), isEnabled);
+    networkCb()->isNrDualConnectivityEnabledResponse(toAidl(info), isEnabled);
     return {};
 }
 
@@ -297,15 +277,13 @@
 
 Return<void> RadioResponse::setAllowedNetworkTypesBitmapResponse(const V1_6::RadioResponseInfo& i) {
     LOG_CALL << i.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setAllowedNetworkTypesBitmapResponse(toAidl(i));
+    networkCb()->setAllowedNetworkTypesBitmapResponse(toAidl(i));
     return {};
 }
 
 Return<void> RadioResponse::setPreferredNetworkTypeResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setAllowedNetworkTypesBitmapResponse(toAidl(info));
+    networkCb()->setAllowedNetworkTypesBitmapResponse(toAidl(info));
     return {};
 }
 
@@ -318,174 +296,151 @@
 
 Return<void> RadioResponse::setBandModeResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setBandModeResponse(toAidl(info));
+    networkCb()->setBandModeResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setBarringPasswordResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setBarringPasswordResponse(toAidl(info));
+    networkCb()->setBarringPasswordResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setCdmaRoamingPreferenceResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setCdmaRoamingPreferenceResponse(toAidl(info));
+    networkCb()->setCdmaRoamingPreferenceResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setCellInfoListRateResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setCellInfoListRateResponse(toAidl(info));
+    networkCb()->setCellInfoListRateResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setIndicationFilterResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setIndicationFilterResponse(toAidl(info));
+    networkCb()->setIndicationFilterResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setIndicationFilterResponse_1_5(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setIndicationFilterResponse(toAidl(info));
+    networkCb()->setIndicationFilterResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setLinkCapacityReportingCriteriaResponse(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setLinkCapacityReportingCriteriaResponse(toAidl(info));
+    networkCb()->setLinkCapacityReportingCriteriaResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setLinkCapacityReportingCriteriaResponse_1_5(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setLinkCapacityReportingCriteriaResponse(toAidl(info));
+    networkCb()->setLinkCapacityReportingCriteriaResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setLocationUpdatesResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setLocationUpdatesResponse(toAidl(info));
+    networkCb()->setLocationUpdatesResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setNetworkSelectionModeAutomaticResponse(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setNetworkSelectionModeAutomaticResponse(toAidl(info));
+    networkCb()->setNetworkSelectionModeAutomaticResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setNetworkSelectionModeManualResponse(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setNetworkSelectionModeManualResponse(toAidl(info));
+    networkCb()->setNetworkSelectionModeManualResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setNetworkSelectionModeManualResponse_1_5(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setNetworkSelectionModeManualResponse(toAidl(info));
+    networkCb()->setNetworkSelectionModeManualResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setNrDualConnectivityStateResponse(
         const V1_6::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setNrDualConnectivityStateResponse(toAidl(info));
+    networkCb()->setNrDualConnectivityStateResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setSignalStrengthReportingCriteriaResponse(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setSignalStrengthReportingCriteriaResponse(toAidl(info));
+    networkCb()->setSignalStrengthReportingCriteriaResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setSignalStrengthReportingCriteriaResponse_1_5(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setSignalStrengthReportingCriteriaResponse(toAidl(info));
+    networkCb()->setSignalStrengthReportingCriteriaResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setSuppServiceNotificationsResponse(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setSuppServiceNotificationsResponse(toAidl(info));
+    networkCb()->setSuppServiceNotificationsResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setSystemSelectionChannelsResponse(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setSystemSelectionChannelsResponse(toAidl(info));
+    networkCb()->setSystemSelectionChannelsResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setSystemSelectionChannelsResponse_1_5(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->setSystemSelectionChannelsResponse(toAidl(info));
+    networkCb()->setSystemSelectionChannelsResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::startNetworkScanResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->startNetworkScanResponse(toAidl(info));
+    networkCb()->startNetworkScanResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::startNetworkScanResponse_1_4(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->startNetworkScanResponse(toAidl(info));
+    networkCb()->startNetworkScanResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::startNetworkScanResponse_1_5(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->startNetworkScanResponse(toAidl(info));
+    networkCb()->startNetworkScanResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::stopNetworkScanResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->stopNetworkScanResponse(toAidl(info));
+    networkCb()->stopNetworkScanResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::supplyNetworkDepersonalizationResponse(
         const V1_0::RadioResponseInfo& info, int32_t remainingRetries) {
     LOG_CALL << info.serial;
-    CHECK_CB(mNetworkCb);
-    mNetworkCb->supplyNetworkDepersonalizationResponse(toAidl(info), remainingRetries);
+    networkCb()->supplyNetworkDepersonalizationResponse(toAidl(info), remainingRetries);
     return {};
 }
 
diff --git a/radio/aidl/compat/libradiocompat/sim/RadioIndication-sim.cpp b/radio/aidl/compat/libradiocompat/sim/RadioIndication-sim.cpp
index 6b906c6..3938e00 100644
--- a/radio/aidl/compat/libradiocompat/sim/RadioIndication-sim.cpp
+++ b/radio/aidl/compat/libradiocompat/sim/RadioIndication-sim.cpp
@@ -29,29 +29,29 @@
 namespace aidl = ::aidl::android::hardware::radio::sim;
 
 void RadioIndication::setResponseFunction(std::shared_ptr<aidl::IRadioSimIndication> simCb) {
-    CHECK(simCb);
     mSimCb = simCb;
 }
 
+std::shared_ptr<aidl::IRadioSimIndication> RadioIndication::simCb() {
+    return mSimCb.get();
+}
+
 Return<void> RadioIndication::carrierInfoForImsiEncryption(V1_0::RadioIndicationType type) {
     LOG_CALL << type;
-    CHECK_CB(mSimCb);
-    mSimCb->carrierInfoForImsiEncryption(toAidl(type));
+    simCb()->carrierInfoForImsiEncryption(toAidl(type));
     return {};
 }
 
 Return<void> RadioIndication::cdmaSubscriptionSourceChanged(
         V1_0::RadioIndicationType type, V1_0::CdmaSubscriptionSource cdmaSource) {
     LOG_CALL << type;
-    CHECK_CB(mSimCb);
-    mSimCb->cdmaSubscriptionSourceChanged(toAidl(type), aidl::CdmaSubscriptionSource(cdmaSource));
+    simCb()->cdmaSubscriptionSourceChanged(toAidl(type), aidl::CdmaSubscriptionSource(cdmaSource));
     return {};
 }
 
 Return<void> RadioIndication::simPhonebookChanged(V1_0::RadioIndicationType type) {
     LOG_CALL << type;
-    CHECK_CB(mSimCb);
-    mSimCb->simPhonebookChanged(toAidl(type));
+    simCb()->simPhonebookChanged(toAidl(type));
     return {};
 }
 
@@ -59,62 +59,54 @@
         V1_0::RadioIndicationType type, V1_6::PbReceivedStatus status,
         const hidl_vec<V1_6::PhonebookRecordInfo>& rec) {
     LOG_CALL << type;
-    CHECK_CB(mSimCb);
-    mSimCb->simPhonebookRecordsReceived(toAidl(type), aidl::PbReceivedStatus(status), toAidl(rec));
+    simCb()->simPhonebookRecordsReceived(toAidl(type), aidl::PbReceivedStatus(status), toAidl(rec));
     return {};
 }
 
 Return<void> RadioIndication::simRefresh(V1_0::RadioIndicationType type,
                                          const V1_0::SimRefreshResult& refreshResult) {
     LOG_CALL << type;
-    CHECK_CB(mSimCb);
-    mSimCb->simRefresh(toAidl(type), toAidl(refreshResult));
+    simCb()->simRefresh(toAidl(type), toAidl(refreshResult));
     return {};
 }
 
 Return<void> RadioIndication::simStatusChanged(V1_0::RadioIndicationType type) {
     LOG_CALL << type;
-    CHECK_CB(mSimCb);
-    mSimCb->simStatusChanged(toAidl(type));
+    simCb()->simStatusChanged(toAidl(type));
     return {};
 }
 
 Return<void> RadioIndication::stkEventNotify(V1_0::RadioIndicationType type,
                                              const hidl_string& cmd) {
     LOG_CALL << type;
-    CHECK_CB(mSimCb);
-    mSimCb->stkEventNotify(toAidl(type), cmd);
+    simCb()->stkEventNotify(toAidl(type), cmd);
     return {};
 }
 
 Return<void> RadioIndication::stkProactiveCommand(V1_0::RadioIndicationType type,
                                                   const hidl_string& cmd) {
     LOG_CALL << type;
-    CHECK_CB(mSimCb);
-    mSimCb->stkProactiveCommand(toAidl(type), cmd);
+    simCb()->stkProactiveCommand(toAidl(type), cmd);
     return {};
 }
 
 Return<void> RadioIndication::stkSessionEnd(V1_0::RadioIndicationType type) {
     LOG_CALL << type;
-    CHECK_CB(mSimCb);
-    mSimCb->stkSessionEnd(toAidl(type));
+    simCb()->stkSessionEnd(toAidl(type));
     return {};
 }
 
 Return<void> RadioIndication::subscriptionStatusChanged(V1_0::RadioIndicationType type,
                                                         bool activate) {
     LOG_CALL << type;
-    CHECK_CB(mSimCb);
-    mSimCb->subscriptionStatusChanged(toAidl(type), activate);
+    simCb()->subscriptionStatusChanged(toAidl(type), activate);
     return {};
 }
 
 Return<void> RadioIndication::uiccApplicationsEnablementChanged(V1_0::RadioIndicationType type,
                                                                 bool enabled) {
     LOG_CALL << type;
-    CHECK_CB(mSimCb);
-    mSimCb->uiccApplicationsEnablementChanged(toAidl(type), enabled);
+    simCb()->uiccApplicationsEnablementChanged(toAidl(type), enabled);
     return {};
 }
 
diff --git a/radio/aidl/compat/libradiocompat/sim/RadioResponse-sim.cpp b/radio/aidl/compat/libradiocompat/sim/RadioResponse-sim.cpp
index 2dfbc50..3ad9130 100644
--- a/radio/aidl/compat/libradiocompat/sim/RadioResponse-sim.cpp
+++ b/radio/aidl/compat/libradiocompat/sim/RadioResponse-sim.cpp
@@ -29,48 +29,46 @@
 namespace aidl = ::aidl::android::hardware::radio::sim;
 
 void RadioResponse::setResponseFunction(std::shared_ptr<aidl::IRadioSimResponse> simCb) {
-    CHECK(simCb);
     mSimCb = simCb;
 }
 
+std::shared_ptr<aidl::IRadioSimResponse> RadioResponse::simCb() {
+    return mSimCb.get();
+}
+
 Return<void> RadioResponse::areUiccApplicationsEnabledResponse(const V1_0::RadioResponseInfo& info,
                                                                bool enabled) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->areUiccApplicationsEnabledResponse(toAidl(info), enabled);
+    simCb()->areUiccApplicationsEnabledResponse(toAidl(info), enabled);
     return {};
 }
 
 Return<void> RadioResponse::changeIccPin2ForAppResponse(const V1_0::RadioResponseInfo& info,
                                                         int32_t remainingRetries) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->changeIccPin2ForAppResponse(toAidl(info), remainingRetries);
+    simCb()->changeIccPin2ForAppResponse(toAidl(info), remainingRetries);
     return {};
 }
 
 Return<void> RadioResponse::changeIccPinForAppResponse(const V1_0::RadioResponseInfo& info,
                                                        int32_t remainingRetries) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->changeIccPinForAppResponse(toAidl(info), remainingRetries);
+    simCb()->changeIccPinForAppResponse(toAidl(info), remainingRetries);
     return {};
 }
 
 Return<void> RadioResponse::enableUiccApplicationsResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->enableUiccApplicationsResponse(toAidl(info));
+    simCb()->enableUiccApplicationsResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::getAllowedCarriersResponse(  //
         const V1_0::RadioResponseInfo& info, bool allAllowed, const V1_0::CarrierRestrictions& cr) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
     aidl::CarrierRestrictions aidlCr = toAidl(cr);
     if (allAllowed) aidlCr = {};
-    mSimCb->getAllowedCarriersResponse(toAidl(info), aidlCr, {});
+    simCb()->getAllowedCarriersResponse(toAidl(info), aidlCr, {});
     return {};
 }
 
@@ -78,9 +76,8 @@
         const V1_0::RadioResponseInfo& info, const V1_4::CarrierRestrictionsWithPriority& carriers,
         V1_4::SimLockMultiSimPolicy multiSimPolicy) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->getAllowedCarriersResponse(toAidl(info), toAidl(carriers),
-                                       aidl::SimLockMultiSimPolicy(multiSimPolicy));
+    simCb()->getAllowedCarriersResponse(toAidl(info), toAidl(carriers),
+                                        aidl::SimLockMultiSimPolicy(multiSimPolicy));
     return {};
 }
 
@@ -88,133 +85,116 @@
         const V1_0::RadioResponseInfo& info, const hidl_string& mdn, const hidl_string& hSid,
         const hidl_string& hNid, const hidl_string& min, const hidl_string& prl) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->getCdmaSubscriptionResponse(toAidl(info), mdn, hSid, hNid, min, prl);
+    simCb()->getCdmaSubscriptionResponse(toAidl(info), mdn, hSid, hNid, min, prl);
     return {};
 }
 
 Return<void> RadioResponse::getCdmaSubscriptionSourceResponse(const V1_0::RadioResponseInfo& info,
                                                               V1_0::CdmaSubscriptionSource s) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->getCdmaSubscriptionSourceResponse(toAidl(info), aidl::CdmaSubscriptionSource(s));
+    simCb()->getCdmaSubscriptionSourceResponse(toAidl(info), aidl::CdmaSubscriptionSource(s));
     return {};
 }
 
 Return<void> RadioResponse::getFacilityLockForAppResponse(const V1_0::RadioResponseInfo& info,
                                                           int32_t response) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->getFacilityLockForAppResponse(toAidl(info), response);
+    simCb()->getFacilityLockForAppResponse(toAidl(info), response);
     return {};
 }
 
 Return<void> RadioResponse::getIccCardStatusResponse(const V1_0::RadioResponseInfo& info,
                                                      const V1_0::CardStatus& cardStatus) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->getIccCardStatusResponse(toAidl(info), toAidl(cardStatus));
+    simCb()->getIccCardStatusResponse(toAidl(info), toAidl(cardStatus));
     return {};
 }
 
 Return<void> RadioResponse::getIccCardStatusResponse_1_2(const V1_0::RadioResponseInfo& info,
                                                          const V1_2::CardStatus& cardStatus) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->getIccCardStatusResponse(toAidl(info), toAidl(cardStatus));
+    simCb()->getIccCardStatusResponse(toAidl(info), toAidl(cardStatus));
     return {};
 }
 
 Return<void> RadioResponse::getIccCardStatusResponse_1_4(const V1_0::RadioResponseInfo& info,
                                                          const V1_4::CardStatus& cardStatus) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->getIccCardStatusResponse(toAidl(info), toAidl(cardStatus));
+    simCb()->getIccCardStatusResponse(toAidl(info), toAidl(cardStatus));
     return {};
 }
 
 Return<void> RadioResponse::getIccCardStatusResponse_1_5(const V1_0::RadioResponseInfo& info,
                                                          const V1_5::CardStatus& cardStatus) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->getIccCardStatusResponse(toAidl(info), toAidl(cardStatus));
+    simCb()->getIccCardStatusResponse(toAidl(info), toAidl(cardStatus));
     return {};
 }
 
 Return<void> RadioResponse::getIMSIForAppResponse(const V1_0::RadioResponseInfo& info,
                                                   const hidl_string& imsi) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->getImsiForAppResponse(toAidl(info), imsi);
+    simCb()->getImsiForAppResponse(toAidl(info), imsi);
     return {};
 }
 
 Return<void> RadioResponse::getSimPhonebookCapacityResponse(
         const V1_6::RadioResponseInfo& info, const V1_6::PhonebookCapacity& capacity) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->getSimPhonebookCapacityResponse(toAidl(info), toAidl(capacity));
+    simCb()->getSimPhonebookCapacityResponse(toAidl(info), toAidl(capacity));
     return {};
 }
 
 Return<void> RadioResponse::getSimPhonebookRecordsResponse(const V1_6::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->getSimPhonebookRecordsResponse(toAidl(info));
+    simCb()->getSimPhonebookRecordsResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::iccCloseLogicalChannelResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->iccCloseLogicalChannelResponse(toAidl(info));
+    simCb()->iccCloseLogicalChannelResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::iccIOForAppResponse(const V1_0::RadioResponseInfo& info,
                                                 const V1_0::IccIoResult& iccIo) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->iccIoForAppResponse(toAidl(info), toAidl(iccIo));
+    simCb()->iccIoForAppResponse(toAidl(info), toAidl(iccIo));
     return {};
 }
 
 Return<void> RadioResponse::iccOpenLogicalChannelResponse(  //
         const V1_0::RadioResponseInfo& info, int32_t chanId, const hidl_vec<int8_t>& selectResp) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->iccOpenLogicalChannelResponse(toAidl(info), chanId, toAidl(selectResp));
+    simCb()->iccOpenLogicalChannelResponse(toAidl(info), chanId, toAidl(selectResp));
     return {};
 }
 
 Return<void> RadioResponse::iccTransmitApduBasicChannelResponse(const V1_0::RadioResponseInfo& info,
                                                                 const V1_0::IccIoResult& result) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->iccTransmitApduBasicChannelResponse(toAidl(info), toAidl(result));
+    simCb()->iccTransmitApduBasicChannelResponse(toAidl(info), toAidl(result));
     return {};
 }
 
 Return<void> RadioResponse::iccTransmitApduLogicalChannelResponse(
         const V1_0::RadioResponseInfo& info, const V1_0::IccIoResult& result) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->iccTransmitApduLogicalChannelResponse(toAidl(info), toAidl(result));
+    simCb()->iccTransmitApduLogicalChannelResponse(toAidl(info), toAidl(result));
     return {};
 }
 
 Return<void> RadioResponse::reportStkServiceIsRunningResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->reportStkServiceIsRunningResponse(toAidl(info));
+    simCb()->reportStkServiceIsRunningResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::requestIccSimAuthenticationResponse(const V1_0::RadioResponseInfo& info,
                                                                 const V1_0::IccIoResult& result) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->requestIccSimAuthenticationResponse(toAidl(info), toAidl(result));
+    simCb()->requestIccSimAuthenticationResponse(toAidl(info), toAidl(result));
     return {};
 }
 
@@ -228,121 +208,105 @@
 Return<void> RadioResponse::sendEnvelopeResponse(const V1_0::RadioResponseInfo& info,
                                                  const hidl_string& commandResponse) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->sendEnvelopeResponse(toAidl(info), commandResponse);
+    simCb()->sendEnvelopeResponse(toAidl(info), commandResponse);
     return {};
 }
 
 Return<void> RadioResponse::sendEnvelopeWithStatusResponse(const V1_0::RadioResponseInfo& info,
                                                            const V1_0::IccIoResult& iccIo) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->sendEnvelopeWithStatusResponse(toAidl(info), toAidl(iccIo));
+    simCb()->sendEnvelopeWithStatusResponse(toAidl(info), toAidl(iccIo));
     return {};
 }
 
 Return<void> RadioResponse::sendTerminalResponseToSimResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->sendTerminalResponseToSimResponse(toAidl(info));
+    simCb()->sendTerminalResponseToSimResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setAllowedCarriersResponse(const V1_0::RadioResponseInfo& info,
                                                        int32_t numAllowed) {
     LOG_CALL << info.serial << ' ' << numAllowed;
-    CHECK_CB(mSimCb);
-    mSimCb->setAllowedCarriersResponse(toAidl(info));
+    simCb()->setAllowedCarriersResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setAllowedCarriersResponse_1_4(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->setAllowedCarriersResponse(toAidl(info));
+    simCb()->setAllowedCarriersResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setCarrierInfoForImsiEncryptionResponse(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->setCarrierInfoForImsiEncryptionResponse(toAidl(info));
+    simCb()->setCarrierInfoForImsiEncryptionResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setCdmaSubscriptionSourceResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->setCdmaSubscriptionSourceResponse(toAidl(info));
+    simCb()->setCdmaSubscriptionSourceResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setFacilityLockForAppResponse(const V1_0::RadioResponseInfo& info,
                                                           int32_t retry) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->setFacilityLockForAppResponse(toAidl(info), retry);
+    simCb()->setFacilityLockForAppResponse(toAidl(info), retry);
     return {};
 }
 
 Return<void> RadioResponse::setSimCardPowerResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->setSimCardPowerResponse(toAidl(info));
+    simCb()->setSimCardPowerResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setSimCardPowerResponse_1_1(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->setSimCardPowerResponse(toAidl(info));
+    simCb()->setSimCardPowerResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setSimCardPowerResponse_1_6(const V1_6::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->setSimCardPowerResponse(toAidl(info));
+    simCb()->setSimCardPowerResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setUiccSubscriptionResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->setUiccSubscriptionResponse(toAidl(info));
+    simCb()->setUiccSubscriptionResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::supplyIccPin2ForAppResponse(const V1_0::RadioResponseInfo& info,
                                                         int32_t remainingRetries) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->supplyIccPin2ForAppResponse(toAidl(info), remainingRetries);
+    simCb()->supplyIccPin2ForAppResponse(toAidl(info), remainingRetries);
     return {};
 }
 
 Return<void> RadioResponse::supplyIccPinForAppResponse(const V1_0::RadioResponseInfo& info,
                                                        int32_t remainingRetries) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->supplyIccPinForAppResponse(toAidl(info), remainingRetries);
+    simCb()->supplyIccPinForAppResponse(toAidl(info), remainingRetries);
     return {};
 }
 
 Return<void> RadioResponse::supplyIccPuk2ForAppResponse(const V1_0::RadioResponseInfo& info,
                                                         int32_t remainingRetries) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->supplyIccPuk2ForAppResponse(toAidl(info), remainingRetries);
+    simCb()->supplyIccPuk2ForAppResponse(toAidl(info), remainingRetries);
     return {};
 }
 
 Return<void> RadioResponse::supplyIccPukForAppResponse(const V1_0::RadioResponseInfo& info,
                                                        int32_t remainingRetries) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->supplyIccPukForAppResponse(toAidl(info), remainingRetries);
+    simCb()->supplyIccPukForAppResponse(toAidl(info), remainingRetries);
     return {};
 }
 
@@ -350,16 +314,14 @@
                                                                V1_5::PersoSubstate persoType,
                                                                int32_t rRet) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->supplySimDepersonalizationResponse(toAidl(info), aidl::PersoSubstate(persoType), rRet);
+    simCb()->supplySimDepersonalizationResponse(toAidl(info), aidl::PersoSubstate(persoType), rRet);
     return {};
 }
 
 Return<void> RadioResponse::updateSimPhonebookRecordsResponse(const V1_6::RadioResponseInfo& info,
                                                               int32_t updatedRecordIndex) {
     LOG_CALL << info.serial;
-    CHECK_CB(mSimCb);
-    mSimCb->updateSimPhonebookRecordsResponse(toAidl(info), updatedRecordIndex);
+    simCb()->updateSimPhonebookRecordsResponse(toAidl(info), updatedRecordIndex);
     return {};
 }
 
diff --git a/radio/aidl/compat/libradiocompat/sim/RadioSim.cpp b/radio/aidl/compat/libradiocompat/sim/RadioSim.cpp
index ca27918..b43f64f 100644
--- a/radio/aidl/compat/libradiocompat/sim/RadioSim.cpp
+++ b/radio/aidl/compat/libradiocompat/sim/RadioSim.cpp
@@ -30,6 +30,10 @@
 namespace aidl = ::aidl::android::hardware::radio::sim;
 constexpr auto ok = &ScopedAStatus::ok;
 
+std::shared_ptr<aidl::IRadioSimResponse> RadioSim::respond() {
+    return mCallbackManager->response().simCb();
+}
+
 ScopedAStatus RadioSim::areUiccApplicationsEnabled(int32_t serial) {
     LOG_CALL << serial;
     mHal1_5->areUiccApplicationsEnabled(serial);
@@ -58,7 +62,7 @@
 
 ScopedAStatus RadioSim::getAllowedCarriers(int32_t serial) {
     LOG_CALL << serial;
-    mHal1_5->getAllowedCarriers(serial);
+    mHal1_5->getAllowedCarriers_1_4(serial);
     return ok();
 }
 
@@ -99,7 +103,7 @@
     if (mHal1_6) {
         mHal1_6->getSimPhonebookCapacity(serial);
     } else {
-        respond().getSimPhonebookCapacityResponse(notSupported(serial), {});
+        respond()->getSimPhonebookCapacityResponse(notSupported(serial), {});
     }
     return ok();
 }
@@ -109,7 +113,7 @@
     if (mHal1_6) {
         mHal1_6->getSimPhonebookRecords(serial);
     } else {
-        respond().getSimPhonebookRecordsResponse(notSupported(serial));
+        respond()->getSimPhonebookRecordsResponse(notSupported(serial));
     }
     return ok();
 }
@@ -217,16 +221,10 @@
 }
 
 ScopedAStatus RadioSim::setResponseFunctions(
-        const std::shared_ptr<aidl::IRadioSimResponse>& simResponse,
-        const std::shared_ptr<aidl::IRadioSimIndication>& simIndication) {
-    LOG_CALL << simResponse << ' ' << simIndication;
-
-    CHECK(simResponse);
-    CHECK(simIndication);
-
-    mRadioResponse->setResponseFunction(simResponse);
-    mRadioIndication->setResponseFunction(simIndication);
-
+        const std::shared_ptr<aidl::IRadioSimResponse>& response,
+        const std::shared_ptr<aidl::IRadioSimIndication>& indication) {
+    LOG_CALL << response << ' ' << indication;
+    mCallbackManager->setResponseFunctions(response, indication);
     return ok();
 }
 
@@ -287,7 +285,7 @@
     if (mHal1_6) {
         mHal1_6->updateSimPhonebookRecords(serial, toHidl(recordInfo));
     } else {
-        respond().updateSimPhonebookRecordsResponse(notSupported(serial), 0);
+        respond()->updateSimPhonebookRecordsResponse(notSupported(serial), 0);
     }
     return ok();
 }
diff --git a/radio/aidl/compat/libradiocompat/sim/structs.cpp b/radio/aidl/compat/libradiocompat/sim/structs.cpp
index 97a21a1..bfbff02 100644
--- a/radio/aidl/compat/libradiocompat/sim/structs.cpp
+++ b/radio/aidl/compat/libradiocompat/sim/structs.cpp
@@ -173,7 +173,6 @@
             .atr = status.base.base.atr,
             .iccid = status.base.base.iccid,
             .eid = status.base.eid,
-            // TODO(b/203699028): we don't know portId here (but we can get it from RadioConfig)
             .slotMap = {static_cast<int32_t>(status.base.base.physicalSlotId), 0},
     };
 }
diff --git a/radio/aidl/compat/libradiocompat/voice/RadioIndication-voice.cpp b/radio/aidl/compat/libradiocompat/voice/RadioIndication-voice.cpp
index 6d9bda8..359fce0 100644
--- a/radio/aidl/compat/libradiocompat/voice/RadioIndication-voice.cpp
+++ b/radio/aidl/compat/libradiocompat/voice/RadioIndication-voice.cpp
@@ -29,113 +29,102 @@
 namespace aidl = ::aidl::android::hardware::radio::voice;
 
 void RadioIndication::setResponseFunction(std::shared_ptr<aidl::IRadioVoiceIndication> voiceCb) {
-    CHECK(voiceCb);
     mVoiceCb = voiceCb;
 }
 
+std::shared_ptr<aidl::IRadioVoiceIndication> RadioIndication::voiceCb() {
+    return mVoiceCb.get();
+}
+
 Return<void> RadioIndication::callRing(V1_0::RadioIndicationType type, bool isGsm,
                                        const V1_0::CdmaSignalInfoRecord& record) {
     LOG_CALL << type;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->callRing(toAidl(type), isGsm, toAidl(record));
+    voiceCb()->callRing(toAidl(type), isGsm, toAidl(record));
     return {};
 }
 
 Return<void> RadioIndication::callStateChanged(V1_0::RadioIndicationType type) {
     LOG_CALL << type;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->callStateChanged(toAidl(type));
+    voiceCb()->callStateChanged(toAidl(type));
     return {};
 }
 
 Return<void> RadioIndication::cdmaCallWaiting(V1_0::RadioIndicationType type,
                                               const V1_0::CdmaCallWaiting& callWaitingRecord) {
     LOG_CALL << type;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->cdmaCallWaiting(toAidl(type), toAidl(callWaitingRecord));
+    voiceCb()->cdmaCallWaiting(toAidl(type), toAidl(callWaitingRecord));
     return {};
 }
 
 Return<void> RadioIndication::cdmaInfoRec(V1_0::RadioIndicationType type,
                                           const V1_0::CdmaInformationRecords& records) {
     LOG_CALL << type;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->cdmaInfoRec(toAidl(type), toAidl(records.infoRec));
+    voiceCb()->cdmaInfoRec(toAidl(type), toAidl(records.infoRec));
     return {};
 }
 
 Return<void> RadioIndication::cdmaOtaProvisionStatus(V1_0::RadioIndicationType type,
                                                      V1_0::CdmaOtaProvisionStatus status) {
     LOG_CALL << type;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->cdmaOtaProvisionStatus(toAidl(type), aidl::CdmaOtaProvisionStatus(status));
+    voiceCb()->cdmaOtaProvisionStatus(toAidl(type), aidl::CdmaOtaProvisionStatus(status));
     return {};
 }
 
 Return<void> RadioIndication::currentEmergencyNumberList(
         V1_0::RadioIndicationType type, const hidl_vec<V1_4::EmergencyNumber>& emergencyNumbers) {
     LOG_CALL << type;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->currentEmergencyNumberList(toAidl(type), toAidl(emergencyNumbers));
+    voiceCb()->currentEmergencyNumberList(toAidl(type), toAidl(emergencyNumbers));
     return {};
 }
 
 Return<void> RadioIndication::enterEmergencyCallbackMode(V1_0::RadioIndicationType type) {
     LOG_CALL << type;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->enterEmergencyCallbackMode(toAidl(type));
+    voiceCb()->enterEmergencyCallbackMode(toAidl(type));
     return {};
 }
 
 Return<void> RadioIndication::exitEmergencyCallbackMode(V1_0::RadioIndicationType type) {
     LOG_CALL << type;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->exitEmergencyCallbackMode(toAidl(type));
+    voiceCb()->exitEmergencyCallbackMode(toAidl(type));
     return {};
 }
 
 Return<void> RadioIndication::indicateRingbackTone(V1_0::RadioIndicationType type, bool start) {
     LOG_CALL << type;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->indicateRingbackTone(toAidl(type), start);
+    voiceCb()->indicateRingbackTone(toAidl(type), start);
     return {};
 }
 
 Return<void> RadioIndication::onSupplementaryServiceIndication(V1_0::RadioIndicationType type,
                                                                const V1_0::StkCcUnsolSsResult& ss) {
     LOG_CALL << type;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->onSupplementaryServiceIndication(toAidl(type), toAidl(ss));
+    voiceCb()->onSupplementaryServiceIndication(toAidl(type), toAidl(ss));
     return {};
 }
 
 Return<void> RadioIndication::resendIncallMute(V1_0::RadioIndicationType type) {
     LOG_CALL << type;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->resendIncallMute(toAidl(type));
+    voiceCb()->resendIncallMute(toAidl(type));
     return {};
 }
 
 Return<void> RadioIndication::srvccStateNotify(V1_0::RadioIndicationType type,
                                                V1_0::SrvccState state) {
     LOG_CALL << type;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->srvccStateNotify(toAidl(type), aidl::SrvccState(state));
+    voiceCb()->srvccStateNotify(toAidl(type), aidl::SrvccState(state));
     return {};
 }
 
 Return<void> RadioIndication::stkCallControlAlphaNotify(V1_0::RadioIndicationType type,
                                                         const hidl_string& alpha) {
     LOG_CALL << type;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->stkCallControlAlphaNotify(toAidl(type), alpha);
+    voiceCb()->stkCallControlAlphaNotify(toAidl(type), alpha);
     return {};
 }
 
 Return<void> RadioIndication::stkCallSetup(V1_0::RadioIndicationType type, int64_t timeout) {
     LOG_CALL << type;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->stkCallSetup(toAidl(type), timeout);
+    voiceCb()->stkCallSetup(toAidl(type), timeout);
     return {};
 }
 
diff --git a/radio/aidl/compat/libradiocompat/voice/RadioResponse-voice.cpp b/radio/aidl/compat/libradiocompat/voice/RadioResponse-voice.cpp
index 0a64c56..d233548 100644
--- a/radio/aidl/compat/libradiocompat/voice/RadioResponse-voice.cpp
+++ b/radio/aidl/compat/libradiocompat/voice/RadioResponse-voice.cpp
@@ -29,265 +29,233 @@
 namespace aidl = ::aidl::android::hardware::radio::voice;
 
 void RadioResponse::setResponseFunction(std::shared_ptr<aidl::IRadioVoiceResponse> voiceCb) {
-    CHECK(voiceCb);
     mVoiceCb = voiceCb;
 }
 
+std::shared_ptr<aidl::IRadioVoiceResponse> RadioResponse::voiceCb() {
+    return mVoiceCb.get();
+}
+
 Return<void> RadioResponse::acceptCallResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->acceptCallResponse(toAidl(info));
+    voiceCb()->acceptCallResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::conferenceResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->conferenceResponse(toAidl(info));
+    voiceCb()->conferenceResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::dialResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->dialResponse(toAidl(info));
+    voiceCb()->dialResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::emergencyDialResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->emergencyDialResponse(toAidl(info));
+    voiceCb()->emergencyDialResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::exitEmergencyCallbackModeResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->exitEmergencyCallbackModeResponse(toAidl(info));
+    voiceCb()->exitEmergencyCallbackModeResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::explicitCallTransferResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->explicitCallTransferResponse(toAidl(info));
+    voiceCb()->explicitCallTransferResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::getCallForwardStatusResponse(
         const V1_0::RadioResponseInfo& info, const hidl_vec<V1_0::CallForwardInfo>& callFwdInfos) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->getCallForwardStatusResponse(toAidl(info), toAidl(callFwdInfos));
+    voiceCb()->getCallForwardStatusResponse(toAidl(info), toAidl(callFwdInfos));
     return {};
 }
 
 Return<void> RadioResponse::getCallWaitingResponse(const V1_0::RadioResponseInfo& info, bool enable,
                                                    int32_t serviceClass) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->getCallWaitingResponse(toAidl(info), enable, serviceClass);
+    voiceCb()->getCallWaitingResponse(toAidl(info), enable, serviceClass);
     return {};
 }
 
 Return<void> RadioResponse::getClipResponse(const V1_0::RadioResponseInfo& info,
                                             V1_0::ClipStatus status) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->getClipResponse(toAidl(info), aidl::ClipStatus(status));
+    voiceCb()->getClipResponse(toAidl(info), aidl::ClipStatus(status));
     return {};
 }
 
 Return<void> RadioResponse::getClirResponse(const V1_0::RadioResponseInfo& info, int32_t n,
                                             int32_t m) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->getClirResponse(toAidl(info), n, m);
+    voiceCb()->getClirResponse(toAidl(info), n, m);
     return {};
 }
 
 Return<void> RadioResponse::getCurrentCallsResponse(const V1_0::RadioResponseInfo& info,
                                                     const hidl_vec<V1_0::Call>& calls) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->getCurrentCallsResponse(toAidl(info), toAidl(calls));
+    voiceCb()->getCurrentCallsResponse(toAidl(info), toAidl(calls));
     return {};
 }
 
 Return<void> RadioResponse::getCurrentCallsResponse_1_2(const V1_0::RadioResponseInfo& info,
                                                         const hidl_vec<V1_2::Call>& calls) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->getCurrentCallsResponse(toAidl(info), toAidl(calls));
+    voiceCb()->getCurrentCallsResponse(toAidl(info), toAidl(calls));
     return {};
 }
 
 Return<void> RadioResponse::getCurrentCallsResponse_1_6(const V1_6::RadioResponseInfo& info,
                                                         const hidl_vec<V1_6::Call>& calls) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->getCurrentCallsResponse(toAidl(info), toAidl(calls));
+    voiceCb()->getCurrentCallsResponse(toAidl(info), toAidl(calls));
     return {};
 }
 
 Return<void> RadioResponse::getLastCallFailCauseResponse(
         const V1_0::RadioResponseInfo& info, const V1_0::LastCallFailCauseInfo& failCauseinfo) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->getLastCallFailCauseResponse(toAidl(info), toAidl(failCauseinfo));
+    voiceCb()->getLastCallFailCauseResponse(toAidl(info), toAidl(failCauseinfo));
     return {};
 }
 
 Return<void> RadioResponse::getMuteResponse(const V1_0::RadioResponseInfo& info, bool enable) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->getMuteResponse(toAidl(info), enable);
+    voiceCb()->getMuteResponse(toAidl(info), enable);
     return {};
 }
 
 Return<void> RadioResponse::getPreferredVoicePrivacyResponse(const V1_0::RadioResponseInfo& info,
                                                              bool enable) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->getPreferredVoicePrivacyResponse(toAidl(info), enable);
+    voiceCb()->getPreferredVoicePrivacyResponse(toAidl(info), enable);
     return {};
 }
 
 Return<void> RadioResponse::getTTYModeResponse(const V1_0::RadioResponseInfo& info,
                                                V1_0::TtyMode mode) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->getTtyModeResponse(toAidl(info), aidl::TtyMode(mode));
+    voiceCb()->getTtyModeResponse(toAidl(info), aidl::TtyMode(mode));
     return {};
 }
 
 Return<void> RadioResponse::handleStkCallSetupRequestFromSimResponse(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->handleStkCallSetupRequestFromSimResponse(toAidl(info));
+    voiceCb()->handleStkCallSetupRequestFromSimResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::hangupConnectionResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->hangupConnectionResponse(toAidl(info));
+    voiceCb()->hangupConnectionResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::hangupForegroundResumeBackgroundResponse(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->hangupForegroundResumeBackgroundResponse(toAidl(info));
+    voiceCb()->hangupForegroundResumeBackgroundResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::hangupWaitingOrBackgroundResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->hangupWaitingOrBackgroundResponse(toAidl(info));
+    voiceCb()->hangupWaitingOrBackgroundResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::rejectCallResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->rejectCallResponse(toAidl(info));
+    voiceCb()->rejectCallResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::sendBurstDtmfResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->sendBurstDtmfResponse(toAidl(info));
+    voiceCb()->sendBurstDtmfResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::sendCDMAFeatureCodeResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->sendCdmaFeatureCodeResponse(toAidl(info));
+    voiceCb()->sendCdmaFeatureCodeResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::sendDtmfResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->sendDtmfResponse(toAidl(info));
+    voiceCb()->sendDtmfResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::separateConnectionResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->separateConnectionResponse(toAidl(info));
+    voiceCb()->separateConnectionResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setCallForwardResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->setCallForwardResponse(toAidl(info));
+    voiceCb()->setCallForwardResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setCallWaitingResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->setCallWaitingResponse(toAidl(info));
+    voiceCb()->setCallWaitingResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setClirResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->setClirResponse(toAidl(info));
+    voiceCb()->setClirResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setMuteResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->setMuteResponse(toAidl(info));
+    voiceCb()->setMuteResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setPreferredVoicePrivacyResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->setPreferredVoicePrivacyResponse(toAidl(info));
+    voiceCb()->setPreferredVoicePrivacyResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::setTTYModeResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->setTtyModeResponse(toAidl(info));
+    voiceCb()->setTtyModeResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::startDtmfResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->startDtmfResponse(toAidl(info));
+    voiceCb()->startDtmfResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::stopDtmfResponse(const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->stopDtmfResponse(toAidl(info));
+    voiceCb()->stopDtmfResponse(toAidl(info));
     return {};
 }
 
 Return<void> RadioResponse::switchWaitingOrHoldingAndActiveResponse(
         const V1_0::RadioResponseInfo& info) {
     LOG_CALL << info.serial;
-    CHECK_CB(mVoiceCb);
-    mVoiceCb->switchWaitingOrHoldingAndActiveResponse(toAidl(info));
+    voiceCb()->switchWaitingOrHoldingAndActiveResponse(toAidl(info));
     return {};
 }
 
diff --git a/radio/aidl/compat/libradiocompat/voice/RadioVoice.cpp b/radio/aidl/compat/libradiocompat/voice/RadioVoice.cpp
index 16c6b14..71d1a56 100644
--- a/radio/aidl/compat/libradiocompat/voice/RadioVoice.cpp
+++ b/radio/aidl/compat/libradiocompat/voice/RadioVoice.cpp
@@ -30,6 +30,10 @@
 namespace aidl = ::aidl::android::hardware::radio::voice;
 constexpr auto ok = &ScopedAStatus::ok;
 
+std::shared_ptr<aidl::IRadioVoiceResponse> RadioVoice::respond() {
+    return mCallbackManager->response().voiceCb();
+}
+
 ScopedAStatus RadioVoice::acceptCall(int32_t serial) {
     LOG_CALL << serial;
     mHal1_5->acceptCall(serial);
@@ -49,13 +53,19 @@
 }
 
 ScopedAStatus RadioVoice::emergencyDial(  //
-        int32_t serial, const aidl::Dial& dialInfo, aidl::EmergencyServiceCategory categories,
+        int32_t serial, const aidl::Dial& info, int32_t categories,
         const std::vector<std::string>& urns, aidl::EmergencyCallRouting routing,
-        bool hasKnownUserIntentEmerg, bool isTesting) {
+        bool knownUserIntentEmerg, bool isTesting) {
     LOG_CALL << serial;
-    mHal1_5->emergencyDial(serial, toHidl(dialInfo),
-                           toHidlBitfield<V1_4::EmergencyServiceCategory>(categories), toHidl(urns),
-                           V1_4::EmergencyCallRouting(routing), hasKnownUserIntentEmerg, isTesting);
+    if (mHal1_6) {
+        mHal1_6->emergencyDial_1_6(  //
+                serial, toHidl(info), toHidlBitfield<V1_4::EmergencyServiceCategory>(categories),
+                toHidl(urns), V1_4::EmergencyCallRouting(routing), knownUserIntentEmerg, isTesting);
+    } else {
+        mHal1_5->emergencyDial(  //
+                serial, toHidl(info), toHidlBitfield<V1_4::EmergencyServiceCategory>(categories),
+                toHidl(urns), V1_4::EmergencyCallRouting(routing), knownUserIntentEmerg, isTesting);
+    }
     return ok();
 }
 
@@ -98,7 +108,11 @@
 
 ScopedAStatus RadioVoice::getCurrentCalls(int32_t serial) {
     LOG_CALL << serial;
-    mHal1_5->getCurrentCalls(serial);
+    if (mHal1_6) {
+        mHal1_6->getCurrentCalls_1_6(serial);
+    } else {
+        mHal1_5->getCurrentCalls(serial);
+    }
     return ok();
 }
 
@@ -152,7 +166,7 @@
 
 ScopedAStatus RadioVoice::isVoNrEnabled(int32_t serial) {
     LOG_CALL << serial;
-    // TODO(b/203699028): can't call isVoNrEnabledResponse with 1.6 callback
+    respond()->isVoNrEnabledResponse(notSupported(serial), false);
     return ok();
 }
 
@@ -224,16 +238,10 @@
 }
 
 ScopedAStatus RadioVoice::setResponseFunctions(
-        const std::shared_ptr<aidl::IRadioVoiceResponse>& voiceResponse,
-        const std::shared_ptr<aidl::IRadioVoiceIndication>& voiceIndication) {
-    LOG_CALL << voiceResponse << ' ' << voiceIndication;
-
-    CHECK(voiceResponse);
-    CHECK(voiceIndication);
-
-    mRadioResponse->setResponseFunction(voiceResponse);
-    mRadioIndication->setResponseFunction(voiceIndication);
-
+        const std::shared_ptr<aidl::IRadioVoiceResponse>& response,
+        const std::shared_ptr<aidl::IRadioVoiceIndication>& indication) {
+    LOG_CALL << response << ' ' << indication;
+    mCallbackManager->setResponseFunctions(response, indication);
     return ok();
 }
 
@@ -245,7 +253,8 @@
 
 ndk::ScopedAStatus RadioVoice::setVoNrEnabled(int32_t serial, [[maybe_unused]] bool enable) {
     LOG_CALL << serial;
-    // TODO(b/203699028): should set `persist.radio.is_vonr_enabled_` property instead
+    // Note: a workaround for older HALs could also be setting persist.radio.is_vonr_enabled_
+    respond()->setVoNrEnabledResponse(notSupported(serial));
     return ok();
 }
 
diff --git a/radio/aidl/compat/libradiocompat/voice/structs.cpp b/radio/aidl/compat/libradiocompat/voice/structs.cpp
index ae6342e..254ea20 100644
--- a/radio/aidl/compat/libradiocompat/voice/structs.cpp
+++ b/radio/aidl/compat/libradiocompat/voice/structs.cpp
@@ -147,7 +147,7 @@
             .number = num.number,
             .mcc = num.mcc,
             .mnc = num.mnc,
-            .categories = aidl::EmergencyServiceCategory(num.categories),
+            .categories = num.categories,
             .urns = toAidl(num.urns),
             .sources = num.sources,
     };
diff --git a/radio/aidl/compat/service/service.cpp b/radio/aidl/compat/service/service.cpp
index 2a67569..8af05de 100644
--- a/radio/aidl/compat/service/service.cpp
+++ b/radio/aidl/compat/service/service.cpp
@@ -19,13 +19,12 @@
 #include <android-base/logging.h>
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
+#include <libradiocompat/CallbackManager.h>
 #include <libradiocompat/RadioConfig.h>
 #include <libradiocompat/RadioData.h>
-#include <libradiocompat/RadioIndication.h>
 #include <libradiocompat/RadioMessaging.h>
 #include <libradiocompat/RadioModem.h>
 #include <libradiocompat/RadioNetwork.h>
-#include <libradiocompat/RadioResponse.h>
 #include <libradiocompat/RadioSim.h>
 #include <libradiocompat/RadioVoice.h>
 
@@ -36,8 +35,8 @@
 static std::vector<std::shared_ptr<ndk::ICInterface>> gPublishedHals;
 
 template <typename T>
-static void publishRadioHal(sp<V1_5::IRadio> hidlHal, sp<compat::RadioResponse> responseCb,
-                            sp<compat::RadioIndication> indicationCb, const std::string& slot) {
+static void publishRadioHal(std::shared_ptr<compat::DriverContext> ctx, sp<V1_5::IRadio> hidlHal,
+                            std::shared_ptr<compat::CallbackManager> cm, const std::string& slot) {
     const auto instance = T::descriptor + "/"s + slot;
     if (!AServiceManager_isDeclared(instance.c_str())) {
         LOG(INFO) << instance << " is not declared in VINTF (this may be intentional)";
@@ -45,7 +44,7 @@
     }
     LOG(DEBUG) << "Publishing " << instance;
 
-    auto aidlHal = ndk::SharedRefBase::make<T>(hidlHal, responseCb, indicationCb);
+    auto aidlHal = ndk::SharedRefBase::make<T>(ctx, hidlHal, cm);
     gPublishedHals.push_back(aidlHal);
     const auto status = AServiceManager_addService(aidlHal->asBinder().get(), instance.c_str());
     CHECK_EQ(status, STATUS_OK);
@@ -57,16 +56,15 @@
 
     hidl_utils::linkDeathToDeath(radioHidl);
 
-    auto responseCb = sp<compat::RadioResponse>::make();
-    auto indicationCb = sp<compat::RadioIndication>::make();
-    radioHidl->setResponseFunctions(responseCb, indicationCb).assertOk();
+    auto context = std::make_shared<compat::DriverContext>();
+    auto callbackMgr = std::make_shared<compat::CallbackManager>(context, radioHidl);
 
-    publishRadioHal<compat::RadioData>(radioHidl, responseCb, indicationCb, slot);
-    publishRadioHal<compat::RadioMessaging>(radioHidl, responseCb, indicationCb, slot);
-    publishRadioHal<compat::RadioModem>(radioHidl, responseCb, indicationCb, slot);
-    publishRadioHal<compat::RadioNetwork>(radioHidl, responseCb, indicationCb, slot);
-    publishRadioHal<compat::RadioSim>(radioHidl, responseCb, indicationCb, slot);
-    publishRadioHal<compat::RadioVoice>(radioHidl, responseCb, indicationCb, slot);
+    publishRadioHal<compat::RadioData>(context, radioHidl, callbackMgr, slot);
+    publishRadioHal<compat::RadioMessaging>(context, radioHidl, callbackMgr, slot);
+    publishRadioHal<compat::RadioModem>(context, radioHidl, callbackMgr, slot);
+    publishRadioHal<compat::RadioNetwork>(context, radioHidl, callbackMgr, slot);
+    publishRadioHal<compat::RadioSim>(context, radioHidl, callbackMgr, slot);
+    publishRadioHal<compat::RadioVoice>(context, radioHidl, callbackMgr, slot);
 }
 
 static void publishRadioConfig() {
@@ -83,6 +81,7 @@
 }
 
 static void main() {
+    base::InitLogging(nullptr, base::LogdLogger(base::RADIO));
     base::SetDefaultTag("radiocompat");
     base::SetMinimumLogSeverity(base::VERBOSE);
     LOG(DEBUG) << "Radio HAL compat service starting...";
diff --git a/radio/aidl/vts/Android.bp b/radio/aidl/vts/Android.bp
new file mode 100644
index 0000000..8060e4b
--- /dev/null
+++ b/radio/aidl/vts/Android.bp
@@ -0,0 +1,74 @@
+// Copyright 2021 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_test {
+    name: "VtsHalRadioTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: [
+        "radio_aidl_hal_utils.cpp",
+        "radio_config_indication.cpp",
+        "radio_config_response.cpp",
+        "radio_config_test.cpp",
+        "radio_data_indication.cpp",
+        "radio_data_response.cpp",
+        "radio_data_test.cpp",
+        "radio_messaging_indication.cpp",
+        "radio_messaging_response.cpp",
+        "radio_messaging_test.cpp",
+        "radio_modem_indication.cpp",
+        "radio_modem_response.cpp",
+        "radio_modem_test.cpp",
+        "radio_network_indication.cpp",
+        "radio_network_response.cpp",
+        "radio_network_test.cpp",
+        "radio_sim_indication.cpp",
+        "radio_sim_response.cpp",
+        "radio_sim_test.cpp",
+        "radio_voice_indication.cpp",
+        "radio_voice_response.cpp",
+        "radio_voice_test.cpp",
+        "VtsHalRadioTargetTest.cpp",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+        "libvintf",
+    ],
+    static_libs: [
+        "android.hardware.radio-V1-ndk",
+        "android.hardware.radio.config-V1-ndk",
+        "android.hardware.radio.data-V1-ndk",
+        "android.hardware.radio.messaging-V1-ndk",
+        "android.hardware.radio.modem-V1-ndk",
+        "android.hardware.radio.network-V1-ndk",
+        "android.hardware.radio.sim-V1-ndk",
+        "android.hardware.radio.voice-V1-ndk",
+    ],
+    // TODO(b/210712359): enable after b/207695009 is resolved.
+    //test_suites: [
+    //    "general-tests",
+    //    "vts",
+    //],
+}
diff --git a/radio/aidl/vts/VtsHalRadioTargetTest.cpp b/radio/aidl/vts/VtsHalRadioTargetTest.cpp
new file mode 100644
index 0000000..1ebc6af
--- /dev/null
+++ b/radio/aidl/vts/VtsHalRadioTargetTest.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2021 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/binder_process.h>
+
+#include "radio_config_utils.h"
+#include "radio_data_utils.h"
+#include "radio_messaging_utils.h"
+#include "radio_modem_utils.h"
+#include "radio_network_utils.h"
+#include "radio_sim_utils.h"
+#include "radio_voice_utils.h"
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RadioConfigTest);
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, RadioConfigTest,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IRadioConfig::descriptor)),
+        android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RadioDataTest);
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, RadioDataTest,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IRadioData::descriptor)),
+        android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RadioMessagingTest);
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, RadioMessagingTest,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IRadioMessaging::descriptor)),
+        android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RadioModemTest);
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, RadioModemTest,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IRadioModem::descriptor)),
+        android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RadioNetworkTest);
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, RadioNetworkTest,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IRadioNetwork::descriptor)),
+        android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RadioSimTest);
+INSTANTIATE_TEST_SUITE_P(PerInstance, RadioSimTest,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(IRadioSim::descriptor)),
+                         android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RadioVoiceTest);
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, RadioVoiceTest,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IRadioVoice::descriptor)),
+        android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/radio/aidl/vts/radio_aidl_hal_utils.cpp b/radio/aidl/vts/radio_aidl_hal_utils.cpp
new file mode 100644
index 0000000..dc61a3c
--- /dev/null
+++ b/radio/aidl/vts/radio_aidl_hal_utils.cpp
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2021 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 "RadioTest"
+
+#include "radio_aidl_hal_utils.h"
+#include <iostream>
+#include "VtsCoreUtil.h"
+#include "radio_config_utils.h"
+#include "radio_sim_utils.h"
+
+#define WAIT_TIMEOUT_PERIOD 75
+
+sim::CardStatus cardStatus = {};
+int serial = 0;
+int count_ = 0;
+
+int GetRandomSerialNumber() {
+    return rand();
+}
+
+::testing::AssertionResult CheckAnyOfErrors(RadioError err, std::vector<RadioError> errors,
+                                            CheckFlag flag) {
+    const static std::vector<RadioError> generalErrors = {
+            RadioError::RADIO_NOT_AVAILABLE,   RadioError::NO_MEMORY,
+            RadioError::INTERNAL_ERR,          RadioError::SYSTEM_ERR,
+            RadioError::REQUEST_NOT_SUPPORTED, RadioError::CANCELLED};
+    if (flag == CHECK_GENERAL_ERROR || flag == CHECK_OEM_AND_GENERAL_ERROR) {
+        for (size_t i = 0; i < generalErrors.size(); i++) {
+            if (err == generalErrors[i]) {
+                return testing::AssertionSuccess();
+            }
+        }
+    }
+    if (flag == CHECK_OEM_ERROR || flag == CHECK_OEM_AND_GENERAL_ERROR) {
+        if (err >= RadioError::OEM_ERROR_1 && err <= RadioError::OEM_ERROR_25) {
+            return testing::AssertionSuccess();
+        }
+    }
+    for (size_t i = 0; i < errors.size(); i++) {
+        if (err == errors[i]) {
+            return testing::AssertionSuccess();
+        }
+    }
+    return testing::AssertionFailure() << "RadioError:" + toString(err) + " is returned";
+}
+
+// Runs "pm list features" and attempts to find the specified feature in its output.
+bool deviceSupportsFeature(const char* feature) {
+    bool hasFeature = false;
+    FILE* p = popen("/system/bin/pm list features", "re");
+    if (p) {
+        char* line = NULL;
+        size_t len = 0;
+        while (getline(&line, &len, p) > 0) {
+            if (strstr(line, feature)) {
+                hasFeature = true;
+                break;
+            }
+        }
+        pclose(p);
+    } else {
+        __android_log_print(ANDROID_LOG_FATAL, LOG_TAG, "popen failed: %d", errno);
+        _exit(EXIT_FAILURE);
+    }
+    __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "Feature %s: %ssupported", feature,
+                        hasFeature ? "" : "not ");
+    return hasFeature;
+}
+
+bool isSsSsEnabled() {
+    // Do not use checkSubstringInCommandOutput("getprop persist.radio.multisim.config", "")
+    // until b/148904287 is fixed. We need exact matching instead of partial matching. (i.e.
+    // by definition the empty string "" is a substring of any string).
+    return !isDsDsEnabled() && !isTsTsEnabled();
+}
+
+bool isDsDsEnabled() {
+    return testing::checkSubstringInCommandOutput("getprop persist.radio.multisim.config", "dsds");
+}
+
+bool isTsTsEnabled() {
+    return testing::checkSubstringInCommandOutput("getprop persist.radio.multisim.config", "tsts");
+}
+
+bool isVoiceInService(RegState state) {
+    return RegState::REG_HOME == state || RegState::REG_ROAMING == state;
+}
+
+bool isVoiceEmergencyOnly(RegState state) {
+    return RegState::NOT_REG_MT_NOT_SEARCHING_OP_EM == state ||
+           RegState::NOT_REG_MT_SEARCHING_OP_EM == state || RegState::REG_DENIED_EM == state ||
+           RegState::UNKNOWN_EM == state;
+}
+
+bool stringEndsWith(std::string const& string, std::string const& end) {
+    if (string.size() >= end.size()) {
+        return (0 == string.compare(string.size() - end.size() - 1, end.size(), end));
+    } else {
+        return false;
+    }
+}
+
+bool isServiceValidForDeviceConfiguration(std::string& serviceName) {
+    if (isSsSsEnabled()) {
+        // Device is configured as SSSS.
+        if (stringEndsWith(serviceName, RADIO_SERVICE_SLOT1_NAME)) {
+            ALOGI("%s instance is not valid for SSSS device.", serviceName.c_str());
+            return false;
+        }
+    } else if (isDsDsEnabled()) {
+        // Device is configured as DSDS.
+        if (!stringEndsWith(serviceName, RADIO_SERVICE_SLOT1_NAME) &&
+            !stringEndsWith(serviceName, RADIO_SERVICE_SLOT2_NAME)) {
+            ALOGI("%s instance is not valid for DSDS device.", serviceName.c_str());
+            return false;
+        }
+    } else if (isTsTsEnabled()) {
+        // Device is configured as TSTS.
+        if (!stringEndsWith(serviceName, RADIO_SERVICE_SLOT1_NAME) &&
+            !stringEndsWith(serviceName, RADIO_SERVICE_SLOT2_NAME) &&
+            !stringEndsWith(serviceName, RADIO_SERVICE_SLOT3_NAME)) {
+            ALOGI("%s instance is not valid for TSTS device.", serviceName.c_str());
+            return false;
+        }
+    }
+    return true;
+}
+
+/*
+ * Notify that the response message is received.
+ */
+void RadioServiceTest::notify(int receivedSerial) {
+    std::unique_lock<std::mutex> lock(mtx_);
+    if (serial == receivedSerial) {
+        count_++;
+        cv_.notify_one();
+    }
+}
+
+/*
+ * Wait till the response message is notified or till WAIT_TIMEOUT_PERIOD.
+ */
+std::cv_status RadioServiceTest::wait() {
+    std::unique_lock<std::mutex> lock(mtx_);
+    std::cv_status status = std::cv_status::no_timeout;
+    auto now = std::chrono::system_clock::now();
+    while (count_ == 0) {
+        status = cv_.wait_until(lock, now + std::chrono::seconds(WAIT_TIMEOUT_PERIOD));
+        if (status == std::cv_status::timeout) {
+            return status;
+        }
+    }
+    count_--;
+    return status;
+}
+
+/**
+ * Specific features on the Radio HAL rely on Radio HAL Capabilities.
+ * The VTS test related to those features must not run if the related capability is disabled.
+ * Typical usage within VTS:
+ * if (getRadioHalCapabilities()) return;
+ */
+bool RadioServiceTest::getRadioHalCapabilities() {
+    // Get HalDeviceCapabilities from RadioConfig
+    std::shared_ptr<RadioConfigResponse> radioConfigRsp =
+            ndk::SharedRefBase::make<RadioConfigResponse>(*this);
+    std::shared_ptr<RadioConfigIndication> radioConfigInd =
+            ndk::SharedRefBase::make<RadioConfigIndication>(*this);
+    radio_config->setResponseFunctions(radioConfigRsp, radioConfigInd);
+    serial = GetRandomSerialNumber();
+    radio_config->getHalDeviceCapabilities(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    return radioConfigRsp->modemReducedFeatureSet1;
+}
+
+/**
+ * Some VTS tests require the SIM card status to be present before running.
+ * Update the SIM card status, which can be accessed via the extern cardStatus.
+ */
+void RadioServiceTest::updateSimCardStatus() {
+    // Update CardStatus from RadioSim
+    std::shared_ptr<RadioSimResponse> radioSimRsp =
+            ndk::SharedRefBase::make<RadioSimResponse>(*this);
+    std::shared_ptr<RadioSimIndication> radioSimInd =
+            ndk::SharedRefBase::make<RadioSimIndication>(*this);
+    radio_sim->setResponseFunctions(radioSimRsp, radioSimInd);
+    serial = GetRandomSerialNumber();
+    radio_sim->getIccCardStatus(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioSimRsp->rspInfo.type);
+    EXPECT_EQ(serial, radioSimRsp->rspInfo.serial);
+    EXPECT_EQ(RadioError::NONE, radioSimRsp->rspInfo.error);
+}
diff --git a/radio/aidl/vts/radio_aidl_hal_utils.h b/radio/aidl/vts/radio_aidl_hal_utils.h
new file mode 100644
index 0000000..414ffbc
--- /dev/null
+++ b/radio/aidl/vts/radio_aidl_hal_utils.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/radio/RadioError.h>
+#include <aidl/android/hardware/radio/config/IRadioConfig.h>
+#include <aidl/android/hardware/radio/network/RegState.h>
+#include <aidl/android/hardware/radio/sim/CardStatus.h>
+#include <aidl/android/hardware/radio/sim/IRadioSim.h>
+#include <utils/Log.h>
+#include <vector>
+
+using namespace aidl::android::hardware::radio;
+using aidl::android::hardware::radio::network::RegState;
+using aidl::android::hardware::radio::sim::CardStatus;
+
+extern CardStatus cardStatus;
+extern int serial;
+extern int count_;
+
+/*
+ * MACRO used to skip test case when radio response return error REQUEST_NOT_SUPPORTED
+ * on HAL versions which has deprecated the request interfaces. The MACRO can only be used
+ * AFTER receiving radio response.
+ */
+#define SKIP_TEST_IF_REQUEST_NOT_SUPPORTED_WITH_HAL(__ver__, __radio__, __radioRsp__)      \
+    do {                                                                                   \
+        sp<::android::hardware::radio::V##__ver__::IRadio> __radio =                       \
+                ::android::hardware::radio::V##__ver__::IRadio::castFrom(__radio__);       \
+        if (__radio && __radioRsp__->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED) { \
+            GTEST_SKIP() << "REQUEST_NOT_SUPPORTED";                                       \
+        }                                                                                  \
+    } while (0)
+
+enum CheckFlag {
+    CHECK_DEFAULT = 0,
+    CHECK_GENERAL_ERROR = 1,
+    CHECK_OEM_ERROR = 2,
+    CHECK_OEM_AND_GENERAL_ERROR = 3,
+    CHECK_SAP_ERROR = 4,
+};
+
+static constexpr const char* FEATURE_VOICE_CALL = "android.software.connectionservice";
+
+static constexpr const char* FEATURE_TELEPHONY = "android.hardware.telephony";
+
+static constexpr const char* FEATURE_TELEPHONY_GSM = "android.hardware.telephony.gsm";
+
+static constexpr const char* FEATURE_TELEPHONY_CDMA = "android.hardware.telephony.cdma";
+
+#define MODEM_EMERGENCY_CALL_ESTABLISH_TIME 3
+#define MODEM_EMERGENCY_CALL_DISCONNECT_TIME 3
+#define MODEM_SET_SIM_POWER_DELAY_IN_SECONDS 2
+
+#define RADIO_SERVICE_SLOT1_NAME "slot1"  // HAL instance name for SIM slot 1 or single SIM device
+#define RADIO_SERVICE_SLOT2_NAME "slot2"  // HAL instance name for SIM slot 2 on dual SIM device
+#define RADIO_SERVICE_SLOT3_NAME "slot3"  // HAL instance name for SIM slot 3 on triple SIM device
+
+/*
+ * Generate random serial number for radio test
+ */
+int GetRandomSerialNumber();
+
+/*
+ * Check multiple radio error codes which are possibly returned because of the different
+ * vendor/devices implementations. It allows optional checks for general errors or/and oem errors.
+ */
+::testing::AssertionResult CheckAnyOfErrors(RadioError err, std::vector<RadioError> generalError,
+                                            CheckFlag flag = CHECK_DEFAULT);
+
+/*
+ * Check if device supports feature.
+ */
+bool deviceSupportsFeature(const char* feature);
+
+/*
+ * Check if device is in SsSs (Single SIM Single Standby).
+ */
+bool isSsSsEnabled();
+
+/*
+ * Check if device is in DSDS (Dual SIM Dual Standby).
+ */
+bool isDsDsEnabled();
+
+/*
+ * Check if device is in TSTS (Triple SIM Triple Standby).
+ */
+bool isTsTsEnabled();
+
+/*
+ * Check if voice status is in emergency only.
+ */
+bool isVoiceEmergencyOnly(RegState state);
+
+/*
+ * Check if voice status is in service.
+ */
+bool isVoiceInService(RegState state);
+
+/*
+ * Check if service is valid for device configuration
+ */
+bool isServiceValidForDeviceConfiguration(std::string& serviceName);
+
+/**
+ * RadioServiceTest base class
+ */
+class RadioServiceTest {
+  protected:
+    std::mutex mtx_;
+    std::condition_variable cv_;
+    std::shared_ptr<config::IRadioConfig> radio_config;
+    std::shared_ptr<sim::IRadioSim> radio_sim;
+
+  public:
+    /* Used as a mechanism to inform the test about data/event callback */
+    void notify(int receivedSerial);
+
+    /* Test code calls this function to wait for response */
+    std::cv_status wait();
+
+    /* Get the radio HAL capabilities */
+    bool getRadioHalCapabilities();
+
+    /* Update SIM card status */
+    void updateSimCardStatus();
+};
diff --git a/radio/aidl/vts/radio_config_indication.cpp b/radio/aidl/vts/radio_config_indication.cpp
new file mode 100644
index 0000000..a84c20b
--- /dev/null
+++ b/radio/aidl/vts/radio_config_indication.cpp
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2021 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 "radio_config_utils.h"
+
+RadioConfigIndication::RadioConfigIndication(RadioServiceTest& parent) : parent_config(parent) {}
+
+ndk::ScopedAStatus RadioConfigIndication::simSlotsStatusChanged(
+        RadioIndicationType /*type*/, const std::vector<SimSlotStatus>& /*slotStatus*/) {
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_config_response.cpp b/radio/aidl/vts/radio_config_response.cpp
new file mode 100644
index 0000000..1a152fb
--- /dev/null
+++ b/radio/aidl/vts/radio_config_response.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2021 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 "radio_config_utils.h"
+
+RadioConfigResponse::RadioConfigResponse(RadioServiceTest& parent) : parent_config(parent) {}
+
+ndk::ScopedAStatus RadioConfigResponse::getSimSlotsStatusResponse(
+        const RadioResponseInfo& /* info */, const std::vector<SimSlotStatus>& /* slotStatus */) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioConfigResponse::setSimSlotsMappingResponse(
+        const RadioResponseInfo& /* info */) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioConfigResponse::getPhoneCapabilityResponse(
+        const RadioResponseInfo& info, const PhoneCapability& phoneCapability) {
+    rspInfo = info;
+    phoneCap = phoneCapability;
+    parent_config.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioConfigResponse::setPreferredDataModemResponse(
+        const RadioResponseInfo& /* info */) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioConfigResponse::getNumOfLiveModemsResponse(
+        const RadioResponseInfo& /* info */, const int8_t /* numOfLiveModems */) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioConfigResponse::setNumOfLiveModemsResponse(
+        const RadioResponseInfo& /* info */) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioConfigResponse::getHalDeviceCapabilitiesResponse(
+        const RadioResponseInfo& info, bool modemReducedFeatures) {
+    modemReducedFeatureSet1 = modemReducedFeatures;
+    parent_config.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_config_test.cpp b/radio/aidl/vts/radio_config_test.cpp
new file mode 100644
index 0000000..2d7fe01
--- /dev/null
+++ b/radio/aidl/vts/radio_config_test.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2021 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 <android/binder_manager.h>
+
+#include "radio_config_utils.h"
+
+#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
+
+void RadioConfigTest::SetUp() {
+    std::string serviceName = GetParam();
+
+    if (!isServiceValidForDeviceConfiguration(serviceName)) {
+        ALOGI("Skipped the test due to device configuration.");
+        GTEST_SKIP();
+    }
+
+    radio_config = IRadioConfig::fromBinder(
+            ndk::SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+    ASSERT_NE(nullptr, radio_config.get());
+
+    radioRsp_config = ndk::SharedRefBase::make<RadioConfigResponse>(*this);
+    ASSERT_NE(nullptr, radioRsp_config.get());
+
+    count_ = 0;
+
+    radioInd_config = ndk::SharedRefBase::make<RadioConfigIndication>(*this);
+    ASSERT_NE(nullptr, radioInd_config.get());
+
+    radio_config->setResponseFunctions(radioRsp_config, radioInd_config);
+}
+
+/*
+ * Test IRadioConfig.getHalDeviceCapabilities() for the response returned.
+ */
+TEST_P(RadioConfigTest, getHalDeviceCapabilities) {
+    serial = GetRandomSerialNumber();
+    ndk::ScopedAStatus res = radio_config->getHalDeviceCapabilities(serial);
+    ASSERT_OK(res);
+    ALOGI("getHalDeviceCapabilities, rspInfo.error = %s\n",
+          toString(radioRsp_config->rspInfo.error).c_str());
+}
diff --git a/radio/aidl/vts/radio_config_utils.h b/radio/aidl/vts/radio_config_utils.h
new file mode 100644
index 0000000..465c106
--- /dev/null
+++ b/radio/aidl/vts/radio_config_utils.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/radio/config/BnRadioConfigIndication.h>
+#include <aidl/android/hardware/radio/config/BnRadioConfigResponse.h>
+#include <aidl/android/hardware/radio/config/IRadioConfig.h>
+
+#include "radio_aidl_hal_utils.h"
+
+using namespace aidl::android::hardware::radio::config;
+
+class RadioConfigTest;
+
+/* Callback class for radio config response */
+class RadioConfigResponse : public BnRadioConfigResponse {
+  protected:
+    RadioServiceTest& parent_config;
+
+  public:
+    RadioConfigResponse(RadioServiceTest& parent_config);
+    virtual ~RadioConfigResponse() = default;
+
+    RadioResponseInfo rspInfo;
+    PhoneCapability phoneCap;
+    bool modemReducedFeatureSet1;
+
+    virtual ndk::ScopedAStatus getSimSlotsStatusResponse(
+            const RadioResponseInfo& info, const std::vector<SimSlotStatus>& slotStatus) override;
+
+    virtual ndk::ScopedAStatus setSimSlotsMappingResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus getPhoneCapabilityResponse(
+            const RadioResponseInfo& info, const PhoneCapability& phoneCapability) override;
+
+    virtual ndk::ScopedAStatus setPreferredDataModemResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus getNumOfLiveModemsResponse(const RadioResponseInfo& info,
+                                                          const int8_t numOfLiveModems) override;
+
+    virtual ndk::ScopedAStatus setNumOfLiveModemsResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus getHalDeviceCapabilitiesResponse(
+            const RadioResponseInfo& info, bool modemReducedFeatureSet1) override;
+};
+
+/* Callback class for radio config indication */
+class RadioConfigIndication : public BnRadioConfigIndication {
+  protected:
+    RadioServiceTest& parent_config;
+
+  public:
+    RadioConfigIndication(RadioServiceTest& parent_config);
+    virtual ~RadioConfigIndication() = default;
+
+    virtual ndk::ScopedAStatus simSlotsStatusChanged(
+            RadioIndicationType type, const std::vector<SimSlotStatus>& slotStatus) override;
+};
+
+// The main test class for Radio AIDL Config.
+class RadioConfigTest : public ::testing::TestWithParam<std::string>, public RadioServiceTest {
+  public:
+    virtual void SetUp() override;
+    ndk::ScopedAStatus updateSimCardStatus();
+
+    /* radio config service handle in RadioServiceTest */
+    /* radio config response handle */
+    std::shared_ptr<RadioConfigResponse> radioRsp_config;
+    /* radio config indication handle */
+    std::shared_ptr<RadioConfigIndication> radioInd_config;
+};
diff --git a/radio/aidl/vts/radio_data_indication.cpp b/radio/aidl/vts/radio_data_indication.cpp
new file mode 100644
index 0000000..61e079e
--- /dev/null
+++ b/radio/aidl/vts/radio_data_indication.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2021 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 "radio_data_utils.h"
+
+RadioDataIndication::RadioDataIndication(RadioServiceTest& parent) : parent_data(parent) {}
+
+ndk::ScopedAStatus RadioDataIndication::dataCallListChanged(
+        RadioIndicationType /*type*/, const std::vector<SetupDataCallResult>& /*dcList*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataIndication::keepaliveStatus(RadioIndicationType /*type*/,
+                                                        const KeepaliveStatus& /*status*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataIndication::pcoData(RadioIndicationType /*type*/,
+                                                const PcoDataInfo& /*pco*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataIndication::unthrottleApn(RadioIndicationType /*type*/,
+                                                      const DataProfileInfo& /*dataProfileInfo*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataIndication::slicingConfigChanged(
+        RadioIndicationType /*type*/, const SlicingConfig& /*slicingConfig*/) {
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_data_response.cpp b/radio/aidl/vts/radio_data_response.cpp
new file mode 100644
index 0000000..9b17bfb
--- /dev/null
+++ b/radio/aidl/vts/radio_data_response.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2021 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 "radio_data_utils.h"
+
+RadioDataResponse::RadioDataResponse(RadioServiceTest& parent) : parent_data(parent) {}
+
+ndk::ScopedAStatus RadioDataResponse::acknowledgeRequest(int32_t /*serial*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataResponse::allocatePduSessionIdResponse(const RadioResponseInfo& info,
+                                                                   int32_t id) {
+    rspInfo = info;
+    allocatedPduSessionId = id;
+    parent_data.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataResponse::cancelHandoverResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_data.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataResponse::deactivateDataCallResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataResponse::getDataCallListResponse(
+        const RadioResponseInfo& info, const std::vector<SetupDataCallResult>& /*dcResponse*/) {
+    rspInfo = info;
+    parent_data.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataResponse::getSlicingConfigResponse(
+        const RadioResponseInfo& info, const SlicingConfig& /*slicingConfig*/) {
+    rspInfo = info;
+    parent_data.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataResponse::releasePduSessionIdResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_data.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataResponse::setDataAllowedResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataResponse::setDataProfileResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataResponse::setDataThrottlingResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_data.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataResponse::setInitialAttachApnResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataResponse::setupDataCallResponse(const RadioResponseInfo& info,
+                                                            const SetupDataCallResult& dcResponse) {
+    rspInfo = info;
+    setupDataCallResult = dcResponse;
+    parent_data.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataResponse::startHandoverResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_data.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataResponse::startKeepaliveResponse(const RadioResponseInfo& /*info*/,
+                                                             const KeepaliveStatus& /*status*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioDataResponse::stopKeepaliveResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_data_test.cpp b/radio/aidl/vts/radio_data_test.cpp
new file mode 100644
index 0000000..8547e9d
--- /dev/null
+++ b/radio/aidl/vts/radio_data_test.cpp
@@ -0,0 +1,311 @@
+/*
+ * Copyright (C) 2021 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 <aidl/android/hardware/radio/RadioAccessFamily.h>
+#include <aidl/android/hardware/radio/config/IRadioConfig.h>
+#include <aidl/android/hardware/radio/data/ApnTypes.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+
+#include "radio_data_utils.h"
+
+#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
+
+void RadioDataTest::SetUp() {
+    std::string serviceName = GetParam();
+
+    if (!isServiceValidForDeviceConfiguration(serviceName)) {
+        ALOGI("Skipped the test due to device configuration.");
+        GTEST_SKIP();
+    }
+
+    radio_data = IRadioData::fromBinder(
+            ndk::SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+    ASSERT_NE(nullptr, radio_data.get());
+
+    radioRsp_data = ndk::SharedRefBase::make<RadioDataResponse>(*this);
+    ASSERT_NE(nullptr, radioRsp_data.get());
+
+    count_ = 0;
+
+    radioInd_data = ndk::SharedRefBase::make<RadioDataIndication>(*this);
+    ASSERT_NE(nullptr, radioInd_data.get());
+
+    radio_data->setResponseFunctions(radioRsp_data, radioInd_data);
+
+    // Assert IRadioSim exists and SIM is present before testing
+    radio_sim = sim::IRadioSim::fromBinder(ndk::SpAIBinder(
+            AServiceManager_waitForService("android.hardware.radio.sim.IRadioSim/slot1")));
+    ASSERT_NE(nullptr, radio_sim.get());
+    updateSimCardStatus();
+    EXPECT_EQ(CardStatus::STATE_PRESENT, cardStatus.cardState);
+
+    // Assert IRadioConfig exists before testing
+    radio_config = config::IRadioConfig::fromBinder(ndk::SpAIBinder(
+            AServiceManager_waitForService("android.hardware.radio.config.IRadioConfig/default")));
+    ASSERT_NE(nullptr, radio_config.get());
+}
+
+ndk::ScopedAStatus RadioDataTest::getDataCallList() {
+    serial = GetRandomSerialNumber();
+    radio_data->getDataCallList(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    return ndk::ScopedAStatus::ok();
+}
+
+/*
+ * Test IRadioData.setupDataCall() for the response returned.
+ */
+TEST_P(RadioDataTest, setupDataCall) {
+    serial = GetRandomSerialNumber();
+
+    AccessNetwork accessNetwork = AccessNetwork::EUTRAN;
+
+    DataProfileInfo dataProfileInfo;
+    memset(&dataProfileInfo, 0, sizeof(dataProfileInfo));
+    dataProfileInfo.profileId = DataProfileInfo::ID_DEFAULT;
+    dataProfileInfo.apn = std::string("internet");
+    dataProfileInfo.protocol = PdpProtocolType::IP;
+    dataProfileInfo.roamingProtocol = PdpProtocolType::IP;
+    dataProfileInfo.authType = ApnAuthType::NO_PAP_NO_CHAP;
+    dataProfileInfo.user = std::string("username");
+    dataProfileInfo.password = std::string("password");
+    dataProfileInfo.type = DataProfileInfo::TYPE_THREE_GPP;
+    dataProfileInfo.maxConnsTime = 300;
+    dataProfileInfo.maxConns = 20;
+    dataProfileInfo.waitTime = 0;
+    dataProfileInfo.enabled = true;
+    dataProfileInfo.supportedApnTypesBitmap =
+            static_cast<int32_t>(ApnTypes::IMS) | static_cast<int32_t>(ApnTypes::IA);
+    dataProfileInfo.bearerBitmap = static_cast<int32_t>(RadioAccessFamily::GPRS) |
+                                   static_cast<int32_t>(RadioAccessFamily::EDGE) |
+                                   static_cast<int32_t>(RadioAccessFamily::UMTS) |
+                                   static_cast<int32_t>(RadioAccessFamily::HSDPA) |
+                                   static_cast<int32_t>(RadioAccessFamily::HSUPA) |
+                                   static_cast<int32_t>(RadioAccessFamily::HSPA) |
+                                   static_cast<int32_t>(RadioAccessFamily::EHRPD) |
+                                   static_cast<int32_t>(RadioAccessFamily::LTE) |
+                                   static_cast<int32_t>(RadioAccessFamily::HSPAP) |
+                                   static_cast<int32_t>(RadioAccessFamily::IWLAN);
+    dataProfileInfo.mtuV4 = 0;
+    dataProfileInfo.mtuV6 = 0;
+    dataProfileInfo.preferred = true;
+    dataProfileInfo.persistent = false;
+
+    bool roamingAllowed = false;
+
+    std::vector<LinkAddress> addresses = {};
+    std::vector<std::string> dnses = {};
+
+    DataRequestReason reason = DataRequestReason::NORMAL;
+    SliceInfo sliceInfo;
+    bool matchAllRuleAllowed = true;
+
+    ndk::ScopedAStatus res =
+            radio_data->setupDataCall(serial, accessNetwork, dataProfileInfo, roamingAllowed,
+                                      reason, addresses, dnses, -1, sliceInfo, matchAllRuleAllowed);
+    ASSERT_OK(res);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_data->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_data->rspInfo.serial);
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+                                     {RadioError::SIM_ABSENT, RadioError::RADIO_NOT_AVAILABLE,
+                                      RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW}));
+    } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+                                     {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+                                      RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW}));
+    }
+}
+
+/*
+ * Test IRadioData.setupDataCall() with osAppId for the response returned.
+ */
+TEST_P(RadioDataTest, setupDataCall_osAppId) {
+    serial = GetRandomSerialNumber();
+
+    AccessNetwork accessNetwork = AccessNetwork::EUTRAN;
+
+    TrafficDescriptor trafficDescriptor;
+    OsAppId osAppId;
+    std::string osAppIdString("osAppId");
+    std::vector<unsigned char> osAppIdVec(osAppIdString.begin(), osAppIdString.end());
+    osAppId.osAppId = osAppIdVec;
+    trafficDescriptor.osAppId = osAppId;
+
+    DataProfileInfo dataProfileInfo;
+    memset(&dataProfileInfo, 0, sizeof(dataProfileInfo));
+    dataProfileInfo.profileId = DataProfileInfo::ID_DEFAULT;
+    dataProfileInfo.apn = std::string("internet");
+    dataProfileInfo.protocol = PdpProtocolType::IP;
+    dataProfileInfo.roamingProtocol = PdpProtocolType::IP;
+    dataProfileInfo.authType = ApnAuthType::NO_PAP_NO_CHAP;
+    dataProfileInfo.user = std::string("username");
+    dataProfileInfo.password = std::string("password");
+    dataProfileInfo.type = DataProfileInfo::TYPE_THREE_GPP;
+    dataProfileInfo.maxConnsTime = 300;
+    dataProfileInfo.maxConns = 20;
+    dataProfileInfo.waitTime = 0;
+    dataProfileInfo.enabled = true;
+    dataProfileInfo.supportedApnTypesBitmap =
+            static_cast<int32_t>(ApnTypes::IMS) | static_cast<int32_t>(ApnTypes::IA);
+    dataProfileInfo.bearerBitmap = static_cast<int32_t>(RadioAccessFamily::GPRS) |
+                                   static_cast<int32_t>(RadioAccessFamily::EDGE) |
+                                   static_cast<int32_t>(RadioAccessFamily::UMTS) |
+                                   static_cast<int32_t>(RadioAccessFamily::HSDPA) |
+                                   static_cast<int32_t>(RadioAccessFamily::HSUPA) |
+                                   static_cast<int32_t>(RadioAccessFamily::HSPA) |
+                                   static_cast<int32_t>(RadioAccessFamily::EHRPD) |
+                                   static_cast<int32_t>(RadioAccessFamily::LTE) |
+                                   static_cast<int32_t>(RadioAccessFamily::HSPAP) |
+                                   static_cast<int32_t>(RadioAccessFamily::IWLAN);
+    dataProfileInfo.mtuV4 = 0;
+    dataProfileInfo.mtuV6 = 0;
+    dataProfileInfo.preferred = true;
+    dataProfileInfo.persistent = false;
+    dataProfileInfo.trafficDescriptor = trafficDescriptor;
+
+    bool roamingAllowed = false;
+
+    std::vector<LinkAddress> addresses = {};
+    std::vector<std::string> dnses = {};
+
+    DataRequestReason reason = DataRequestReason::NORMAL;
+    SliceInfo sliceInfo;
+    bool matchAllRuleAllowed = true;
+
+    ndk::ScopedAStatus res =
+            radio_data->setupDataCall(serial, accessNetwork, dataProfileInfo, roamingAllowed,
+                                      reason, addresses, dnses, -1, sliceInfo, matchAllRuleAllowed);
+    ASSERT_OK(res);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_data->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_data->rspInfo.serial);
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+                                     {RadioError::SIM_ABSENT, RadioError::RADIO_NOT_AVAILABLE,
+                                      RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW}));
+    } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+                                     {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+                                      RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW}));
+        if (radioRsp_data->setupDataCallResult.trafficDescriptors.size() <= 0) {
+            return;
+        }
+        EXPECT_EQ(trafficDescriptor.osAppId.value().osAppId,
+                  radioRsp_data->setupDataCallResult.trafficDescriptors[0].osAppId.value().osAppId);
+    }
+}
+
+/*
+ * Test IRadioData.getSlicingConfig() for the response returned.
+ */
+TEST_P(RadioDataTest, getSlicingConfig) {
+    serial = GetRandomSerialNumber();
+    radio_data->getSlicingConfig(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_data->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_data->rspInfo.serial);
+    if (getRadioHalCapabilities()) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+                                     {RadioError::REQUEST_NOT_SUPPORTED}));
+    } else {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+                                     {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+                                      RadioError::INTERNAL_ERR, RadioError::MODEM_ERR}));
+    }
+}
+
+/*
+ * Test IRadioData.setDataThrottling() for the response returned.
+ */
+TEST_P(RadioDataTest, setDataThrottling) {
+    serial = GetRandomSerialNumber();
+
+    ndk::ScopedAStatus res = radio_data->setDataThrottling(
+            serial, DataThrottlingAction::THROTTLE_SECONDARY_CARRIER, 60000);
+    ASSERT_OK(res);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_data->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_data->rspInfo.serial);
+    if (getRadioHalCapabilities()) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+                                     {RadioError::REQUEST_NOT_SUPPORTED, RadioError::NONE}));
+    } else {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+                                     {RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR,
+                                      RadioError::NONE, RadioError::INVALID_ARGUMENTS}));
+    }
+
+    sleep(1);
+    serial = GetRandomSerialNumber();
+
+    res = radio_data->setDataThrottling(serial, DataThrottlingAction::THROTTLE_ANCHOR_CARRIER,
+                                        60000);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_data->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_data->rspInfo.serial);
+    if (getRadioHalCapabilities()) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+                                     {RadioError::REQUEST_NOT_SUPPORTED, RadioError::NONE}));
+    } else {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+                                     {RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR,
+                                      RadioError::NONE, RadioError::INVALID_ARGUMENTS}));
+    }
+
+    sleep(1);
+    serial = GetRandomSerialNumber();
+
+    res = radio_data->setDataThrottling(serial, DataThrottlingAction::HOLD, 60000);
+    ASSERT_OK(res);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_data->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_data->rspInfo.serial);
+    if (getRadioHalCapabilities()) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+                                     {RadioError::REQUEST_NOT_SUPPORTED, RadioError::NONE}));
+    } else {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+                                     {RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR,
+                                      RadioError::NONE, RadioError::INVALID_ARGUMENTS}));
+    }
+
+    sleep(1);
+    serial = GetRandomSerialNumber();
+
+    res = radio_data->setDataThrottling(serial, DataThrottlingAction::NO_DATA_THROTTLING, 60000);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_data->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_data->rspInfo.serial);
+    if (getRadioHalCapabilities()) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+                                     {RadioError::REQUEST_NOT_SUPPORTED, RadioError::NONE}));
+    } else {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_data->rspInfo.error,
+                                     {RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR,
+                                      RadioError::NONE, RadioError::INVALID_ARGUMENTS}));
+    }
+
+    sleep(1);
+}
diff --git a/radio/aidl/vts/radio_data_utils.h b/radio/aidl/vts/radio_data_utils.h
new file mode 100644
index 0000000..fb91ef6
--- /dev/null
+++ b/radio/aidl/vts/radio_data_utils.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/radio/data/BnRadioDataIndication.h>
+#include <aidl/android/hardware/radio/data/BnRadioDataResponse.h>
+#include <aidl/android/hardware/radio/data/IRadioData.h>
+
+#include "radio_aidl_hal_utils.h"
+
+using namespace aidl::android::hardware::radio::data;
+
+class RadioDataTest;
+
+/* Callback class for radio data response */
+class RadioDataResponse : public BnRadioDataResponse {
+  protected:
+    RadioServiceTest& parent_data;
+
+  public:
+    RadioDataResponse(RadioServiceTest& parent_data);
+    virtual ~RadioDataResponse() = default;
+
+    RadioResponseInfo rspInfo;
+    int32_t allocatedPduSessionId;
+    SetupDataCallResult setupDataCallResult;
+
+    virtual ndk::ScopedAStatus acknowledgeRequest(int32_t serial) override;
+
+    virtual ndk::ScopedAStatus allocatePduSessionIdResponse(const RadioResponseInfo& info,
+                                                            int32_t id) override;
+
+    virtual ndk::ScopedAStatus cancelHandoverResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus deactivateDataCallResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus getDataCallListResponse(
+            const RadioResponseInfo& info,
+            const std::vector<SetupDataCallResult>& dcResponse) override;
+
+    virtual ndk::ScopedAStatus getSlicingConfigResponse(
+            const RadioResponseInfo& info, const SlicingConfig& slicingConfig) override;
+
+    virtual ndk::ScopedAStatus releasePduSessionIdResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setDataAllowedResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setDataProfileResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setDataThrottlingResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setInitialAttachApnResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setupDataCallResponse(
+            const RadioResponseInfo& info, const SetupDataCallResult& dcResponse) override;
+
+    virtual ndk::ScopedAStatus startHandoverResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus startKeepaliveResponse(const RadioResponseInfo& info,
+                                                      const KeepaliveStatus& status) override;
+
+    virtual ndk::ScopedAStatus stopKeepaliveResponse(const RadioResponseInfo& info) override;
+};
+
+/* Callback class for radio data indication */
+class RadioDataIndication : public BnRadioDataIndication {
+  protected:
+    RadioServiceTest& parent_data;
+
+  public:
+    RadioDataIndication(RadioServiceTest& parent_data);
+    virtual ~RadioDataIndication() = default;
+
+    virtual ndk::ScopedAStatus dataCallListChanged(
+            RadioIndicationType type, const std::vector<SetupDataCallResult>& dcList) override;
+
+    virtual ndk::ScopedAStatus keepaliveStatus(RadioIndicationType type,
+                                               const KeepaliveStatus& status) override;
+
+    virtual ndk::ScopedAStatus pcoData(RadioIndicationType type, const PcoDataInfo& pco) override;
+
+    virtual ndk::ScopedAStatus unthrottleApn(RadioIndicationType type,
+                                             const DataProfileInfo& dataProfile) override;
+    virtual ndk::ScopedAStatus slicingConfigChanged(RadioIndicationType type,
+                                                    const SlicingConfig& slicingConfig) override;
+};
+
+// The main test class for Radio AIDL Data.
+class RadioDataTest : public ::testing::TestWithParam<std::string>, public RadioServiceTest {
+  protected:
+    /* Get current data call list */
+    ndk::ScopedAStatus getDataCallList();
+
+  public:
+    virtual void SetUp() override;
+
+    /* radio data service handle */
+    std::shared_ptr<IRadioData> radio_data;
+    /* radio data response handle */
+    std::shared_ptr<RadioDataResponse> radioRsp_data;
+    /* radio data indication handle */
+    std::shared_ptr<RadioDataIndication> radioInd_data;
+};
diff --git a/radio/aidl/vts/radio_messaging_indication.cpp b/radio/aidl/vts/radio_messaging_indication.cpp
new file mode 100644
index 0000000..c69611f
--- /dev/null
+++ b/radio/aidl/vts/radio_messaging_indication.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2021 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 "radio_messaging_utils.h"
+
+RadioMessagingIndication::RadioMessagingIndication(RadioServiceTest& parent)
+    : parent_messaging(parent) {}
+
+ndk::ScopedAStatus RadioMessagingIndication::cdmaNewSms(RadioIndicationType /*type*/,
+                                                        const CdmaSmsMessage& /*msg*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingIndication::cdmaRuimSmsStorageFull(RadioIndicationType /*type*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingIndication::newBroadcastSms(RadioIndicationType /*type*/,
+                                                             const std::vector<uint8_t>& /*data*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingIndication::newSms(RadioIndicationType /*type*/,
+                                                    const std::vector<uint8_t>& /*pdu*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingIndication::newSmsOnSim(RadioIndicationType /*type*/,
+                                                         int32_t /*recordNumber*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingIndication::newSmsStatusReport(
+        RadioIndicationType /*type*/, const std::vector<uint8_t>& /*pdu*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingIndication::onUssd(RadioIndicationType /*type*/,
+                                                    UssdModeType /*modeType*/,
+                                                    const std::string& /*msg*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingIndication::simSmsStorageFull(RadioIndicationType /*type*/) {
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_messaging_response.cpp b/radio/aidl/vts/radio_messaging_response.cpp
new file mode 100644
index 0000000..718df7e
--- /dev/null
+++ b/radio/aidl/vts/radio_messaging_response.cpp
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2021 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 "radio_messaging_utils.h"
+
+RadioMessagingResponse::RadioMessagingResponse(RadioServiceTest& parent)
+    : parent_messaging(parent) {}
+
+ndk::ScopedAStatus RadioMessagingResponse::acknowledgeIncomingGsmSmsWithPduResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::acknowledgeLastIncomingCdmaSmsResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::acknowledgeLastIncomingGsmSmsResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::acknowledgeRequest(int32_t /*serial*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::cancelPendingUssdResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::deleteSmsOnRuimResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::deleteSmsOnSimResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::getCdmaBroadcastConfigResponse(
+        const RadioResponseInfo& /*info*/,
+        const std::vector<CdmaBroadcastSmsConfigInfo>& /*configs*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::getGsmBroadcastConfigResponse(
+        const RadioResponseInfo& /*info*/,
+        const std::vector<GsmBroadcastSmsConfigInfo>& /*configs*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::getSmscAddressResponse(const RadioResponseInfo& /*info*/,
+                                                                  const std::string& /*smsc*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::reportSmsMemoryStatusResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::sendCdmaSmsExpectMoreResponse(
+        const RadioResponseInfo& info, const SendSmsResult& sms) {
+    rspInfo = info;
+    sendSmsResult = sms;
+    parent_messaging.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::sendCdmaSmsResponse(const RadioResponseInfo& info,
+                                                               const SendSmsResult& sms) {
+    rspInfo = info;
+    sendSmsResult = sms;
+    parent_messaging.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::sendImsSmsResponse(const RadioResponseInfo& /*info*/,
+                                                              const SendSmsResult& /*sms*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::sendSmsExpectMoreResponse(const RadioResponseInfo& info,
+                                                                     const SendSmsResult& sms) {
+    rspInfo = info;
+    sendSmsResult = sms;
+    parent_messaging.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::sendSmsResponse(const RadioResponseInfo& info,
+                                                           const SendSmsResult& sms) {
+    rspInfo = info;
+    sendSmsResult = sms;
+    parent_messaging.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::sendUssdResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::setCdmaBroadcastActivationResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::setCdmaBroadcastConfigResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::setGsmBroadcastActivationResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::setGsmBroadcastConfigResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::setSmscAddressResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::writeSmsToRuimResponse(const RadioResponseInfo& /*info*/,
+                                                                  int32_t /*index*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioMessagingResponse::writeSmsToSimResponse(const RadioResponseInfo& /*info*/,
+                                                                 int32_t /*index*/) {
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_messaging_test.cpp b/radio/aidl/vts/radio_messaging_test.cpp
new file mode 100644
index 0000000..8abd91d
--- /dev/null
+++ b/radio/aidl/vts/radio_messaging_test.cpp
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2021 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 <aidl/android/hardware/radio/config/IRadioConfig.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+
+#include "radio_messaging_utils.h"
+
+#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
+
+void RadioMessagingTest::SetUp() {
+    std::string serviceName = GetParam();
+
+    if (!isServiceValidForDeviceConfiguration(serviceName)) {
+        ALOGI("Skipped the test due to device configuration.");
+        GTEST_SKIP();
+    }
+
+    radio_messaging = IRadioMessaging::fromBinder(
+            ndk::SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+    ASSERT_NE(nullptr, radio_messaging.get());
+
+    radioRsp_messaging = ndk::SharedRefBase::make<RadioMessagingResponse>(*this);
+    ASSERT_NE(nullptr, radioRsp_messaging.get());
+
+    count_ = 0;
+
+    radioInd_messaging = ndk::SharedRefBase::make<RadioMessagingIndication>(*this);
+    ASSERT_NE(nullptr, radioInd_messaging.get());
+
+    radio_messaging->setResponseFunctions(radioRsp_messaging, radioInd_messaging);
+
+    // Assert IRadioSim exists and SIM is present before testing
+    radio_sim = sim::IRadioSim::fromBinder(ndk::SpAIBinder(
+            AServiceManager_waitForService("android.hardware.radio.sim.IRadioSim/slot1")));
+    ASSERT_NE(nullptr, radio_sim.get());
+    updateSimCardStatus();
+    EXPECT_EQ(CardStatus::STATE_PRESENT, cardStatus.cardState);
+
+    // Assert IRadioConfig exists before testing
+    radio_config = config::IRadioConfig::fromBinder(ndk::SpAIBinder(
+            AServiceManager_waitForService("android.hardware.radio.config.IRadioConfig/default")));
+    ASSERT_NE(nullptr, radio_config.get());
+}
+
+/*
+ * Test IRadioMessaging.sendSms() for the response returned.
+ */
+TEST_P(RadioMessagingTest, sendSms) {
+    LOG(DEBUG) << "sendSms";
+    serial = GetRandomSerialNumber();
+    GsmSmsMessage msg;
+    msg.smscPdu = "";
+    msg.pdu = "01000b916105770203f3000006d4f29c3e9b01";
+
+    radio_messaging->sendSms(serial, msg);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_messaging->rspInfo.error,
+                {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::SIM_ABSENT},
+                CHECK_GENERAL_ERROR));
+        EXPECT_EQ(0, radioRsp_messaging->sendSmsResult.errorCode);
+    }
+    LOG(DEBUG) << "sendSms finished";
+}
+
+/*
+ * Test IRadioMessaging.sendSmsExpectMore() for the response returned.
+ */
+TEST_P(RadioMessagingTest, sendSmsExpectMore) {
+    LOG(DEBUG) << "sendSmsExpectMore";
+    serial = GetRandomSerialNumber();
+    GsmSmsMessage msg;
+    msg.smscPdu = "";
+    msg.pdu = "01000b916105770203f3000006d4f29c3e9b01";
+
+    radio_messaging->sendSmsExpectMore(serial, msg);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_messaging->rspInfo.error,
+                {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::SIM_ABSENT},
+                CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "sendSmsExpectMore finished";
+}
+
+/*
+ * Test IRadioMessaging.sendCdmaSms() for the response returned.
+ */
+TEST_P(RadioMessagingTest, sendCdmaSms) {
+    LOG(DEBUG) << "sendCdmaSms";
+    serial = GetRandomSerialNumber();
+
+    // Create a CdmaSmsAddress
+    CdmaSmsAddress cdmaSmsAddress;
+    cdmaSmsAddress.digitMode = CdmaSmsAddress::DIGIT_MODE_FOUR_BIT;
+    cdmaSmsAddress.isNumberModeDataNetwork = false;
+    cdmaSmsAddress.numberType = CdmaSmsAddress::NUMBER_TYPE_UNKNOWN;
+    cdmaSmsAddress.numberPlan = CdmaSmsAddress::NUMBER_PLAN_UNKNOWN;
+    cdmaSmsAddress.digits = (std::vector<uint8_t>){11, 1, 6, 5, 10, 7, 7, 2, 10, 3, 10, 3};
+
+    // Create a CdmaSmsSubAddress
+    CdmaSmsSubaddress cdmaSmsSubaddress;
+    cdmaSmsSubaddress.subaddressType = CdmaSmsSubaddress::SUBADDRESS_TYPE_NSAP;
+    cdmaSmsSubaddress.odd = false;
+    cdmaSmsSubaddress.digits = (std::vector<uint8_t>){};
+
+    // Create a CdmaSmsMessage
+    CdmaSmsMessage cdmaSmsMessage;
+    cdmaSmsMessage.teleserviceId = 4098;
+    cdmaSmsMessage.isServicePresent = false;
+    cdmaSmsMessage.serviceCategory = 0;
+    cdmaSmsMessage.address = cdmaSmsAddress;
+    cdmaSmsMessage.subAddress = cdmaSmsSubaddress;
+    cdmaSmsMessage.bearerData =
+            (std::vector<uint8_t>){15, 0, 3, 32, 3, 16, 1, 8, 16, 53, 76, 68, 6, 51, 106, 0};
+
+    radio_messaging->sendCdmaSms(serial, cdmaSmsMessage);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_messaging->rspInfo.error,
+                {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::SIM_ABSENT},
+                CHECK_GENERAL_ERROR));
+    }
+    LOG(DEBUG) << "sendCdmaSms finished";
+}
+
+/*
+ * Test IRadioMessaging.sendCdmaSmsExpectMore() for the response returned.
+ */
+TEST_P(RadioMessagingTest, sendCdmaSmsExpectMore) {
+    serial = GetRandomSerialNumber();
+
+    // Create a CdmaSmsAddress
+    CdmaSmsAddress cdmaSmsAddress;
+    cdmaSmsAddress.digitMode = CdmaSmsAddress::DIGIT_MODE_FOUR_BIT;
+    cdmaSmsAddress.isNumberModeDataNetwork = false;
+    cdmaSmsAddress.numberType = CdmaSmsAddress::NUMBER_TYPE_UNKNOWN;
+    cdmaSmsAddress.numberPlan = CdmaSmsAddress::NUMBER_PLAN_UNKNOWN;
+    cdmaSmsAddress.digits = (std::vector<uint8_t>){11, 1, 6, 5, 10, 7, 7, 2, 10, 3, 10, 3};
+
+    // Create a CdmaSmsSubAddress
+    CdmaSmsSubaddress cdmaSmsSubaddress;
+    cdmaSmsSubaddress.subaddressType = CdmaSmsSubaddress::SUBADDRESS_TYPE_NSAP;
+    cdmaSmsSubaddress.odd = false;
+    cdmaSmsSubaddress.digits = (std::vector<uint8_t>){};
+
+    // Create a CdmaSmsMessage
+    CdmaSmsMessage cdmaSmsMessage;
+    cdmaSmsMessage.teleserviceId = 4098;
+    cdmaSmsMessage.isServicePresent = false;
+    cdmaSmsMessage.serviceCategory = 0;
+    cdmaSmsMessage.address = cdmaSmsAddress;
+    cdmaSmsMessage.subAddress = cdmaSmsSubaddress;
+    cdmaSmsMessage.bearerData =
+            (std::vector<uint8_t>){15, 0, 3, 32, 3, 16, 1, 8, 16, 53, 76, 68, 6, 51, 106, 0};
+
+    radio_messaging->sendCdmaSmsExpectMore(serial, cdmaSmsMessage);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_messaging->rspInfo.error,
+                {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::SIM_ABSENT},
+                CHECK_GENERAL_ERROR));
+    }
+}
diff --git a/radio/aidl/vts/radio_messaging_utils.h b/radio/aidl/vts/radio_messaging_utils.h
new file mode 100644
index 0000000..7bb99cd
--- /dev/null
+++ b/radio/aidl/vts/radio_messaging_utils.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/radio/messaging/BnRadioMessagingIndication.h>
+#include <aidl/android/hardware/radio/messaging/BnRadioMessagingResponse.h>
+#include <aidl/android/hardware/radio/messaging/IRadioMessaging.h>
+
+#include "radio_aidl_hal_utils.h"
+
+using namespace aidl::android::hardware::radio::messaging;
+
+class RadioMessagingTest;
+
+/* Callback class for radio messaging response */
+class RadioMessagingResponse : public BnRadioMessagingResponse {
+  protected:
+    RadioServiceTest& parent_messaging;
+
+  public:
+    RadioMessagingResponse(RadioServiceTest& parent_messaging);
+    virtual ~RadioMessagingResponse() = default;
+
+    RadioResponseInfo rspInfo;
+    SendSmsResult sendSmsResult;
+
+    virtual ndk::ScopedAStatus acknowledgeIncomingGsmSmsWithPduResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus acknowledgeLastIncomingCdmaSmsResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus acknowledgeLastIncomingGsmSmsResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus acknowledgeRequest(int32_t serial) override;
+
+    virtual ndk::ScopedAStatus cancelPendingUssdResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus deleteSmsOnRuimResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus deleteSmsOnSimResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus getCdmaBroadcastConfigResponse(
+            const RadioResponseInfo& info,
+            const std::vector<CdmaBroadcastSmsConfigInfo>& configs) override;
+
+    virtual ndk::ScopedAStatus getGsmBroadcastConfigResponse(
+            const RadioResponseInfo& info,
+            const std::vector<GsmBroadcastSmsConfigInfo>& configs) override;
+
+    virtual ndk::ScopedAStatus getSmscAddressResponse(const RadioResponseInfo& info,
+                                                      const std::string& smsc) override;
+
+    virtual ndk::ScopedAStatus reportSmsMemoryStatusResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus sendCdmaSmsExpectMoreResponse(const RadioResponseInfo& info,
+                                                             const SendSmsResult& sms) override;
+
+    virtual ndk::ScopedAStatus sendCdmaSmsResponse(const RadioResponseInfo& info,
+                                                   const SendSmsResult& sms) override;
+
+    virtual ndk::ScopedAStatus sendImsSmsResponse(const RadioResponseInfo& info,
+                                                  const SendSmsResult& sms) override;
+
+    virtual ndk::ScopedAStatus sendSmsExpectMoreResponse(const RadioResponseInfo& info,
+                                                         const SendSmsResult& sms) override;
+
+    virtual ndk::ScopedAStatus sendSmsResponse(const RadioResponseInfo& info,
+                                               const SendSmsResult& sms) override;
+
+    virtual ndk::ScopedAStatus sendUssdResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setCdmaBroadcastActivationResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setCdmaBroadcastConfigResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setGsmBroadcastActivationResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setGsmBroadcastConfigResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setSmscAddressResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus writeSmsToRuimResponse(const RadioResponseInfo& info,
+                                                      int32_t index) override;
+
+    virtual ndk::ScopedAStatus writeSmsToSimResponse(const RadioResponseInfo& info,
+                                                     int32_t index) override;
+};
+
+/* Callback class for radio messaging indication */
+class RadioMessagingIndication : public BnRadioMessagingIndication {
+  protected:
+    RadioServiceTest& parent_messaging;
+
+  public:
+    RadioMessagingIndication(RadioServiceTest& parent_messaging);
+    virtual ~RadioMessagingIndication() = default;
+
+    virtual ndk::ScopedAStatus cdmaNewSms(RadioIndicationType type,
+                                          const CdmaSmsMessage& msg) override;
+
+    virtual ndk::ScopedAStatus cdmaRuimSmsStorageFull(RadioIndicationType type) override;
+
+    virtual ndk::ScopedAStatus newBroadcastSms(RadioIndicationType type,
+                                               const std::vector<uint8_t>& data) override;
+
+    virtual ndk::ScopedAStatus newSms(RadioIndicationType type,
+                                      const std::vector<uint8_t>& pdu) override;
+
+    virtual ndk::ScopedAStatus newSmsOnSim(RadioIndicationType type, int32_t recordNumber) override;
+
+    virtual ndk::ScopedAStatus newSmsStatusReport(RadioIndicationType type,
+                                                  const std::vector<uint8_t>& pdu) override;
+
+    virtual ndk::ScopedAStatus onUssd(RadioIndicationType type, UssdModeType modeType,
+                                      const std::string& msg) override;
+
+    virtual ndk::ScopedAStatus simSmsStorageFull(RadioIndicationType type) override;
+};
+
+// The main test class for Radio AIDL Messaging.
+class RadioMessagingTest : public ::testing::TestWithParam<std::string>, public RadioServiceTest {
+  public:
+    virtual void SetUp() override;
+
+    /* radio messaging service handle */
+    std::shared_ptr<IRadioMessaging> radio_messaging;
+    /* radio messaging response handle */
+    std::shared_ptr<RadioMessagingResponse> radioRsp_messaging;
+    /* radio messaging indication handle */
+    std::shared_ptr<RadioMessagingIndication> radioInd_messaging;
+};
diff --git a/radio/aidl/vts/radio_modem_indication.cpp b/radio/aidl/vts/radio_modem_indication.cpp
new file mode 100644
index 0000000..0bfcd66
--- /dev/null
+++ b/radio/aidl/vts/radio_modem_indication.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2021 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 "radio_modem_utils.h"
+
+RadioModemIndication::RadioModemIndication(RadioServiceTest& parent) : parent_modem(parent) {}
+
+ndk::ScopedAStatus RadioModemIndication::hardwareConfigChanged(
+        RadioIndicationType /*type*/, const std::vector<HardwareConfig>& /*configs*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemIndication::modemReset(RadioIndicationType /*type*/,
+                                                    const std::string& /*reason*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemIndication::radioCapabilityIndication(RadioIndicationType /*type*/,
+                                                                   const RadioCapability& /*rc*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemIndication::radioStateChanged(RadioIndicationType /*type*/,
+                                                           RadioState /*radioState*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemIndication::rilConnected(RadioIndicationType /*type*/) {
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_modem_response.cpp b/radio/aidl/vts/radio_modem_response.cpp
new file mode 100644
index 0000000..53bfab4
--- /dev/null
+++ b/radio/aidl/vts/radio_modem_response.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2021 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 "radio_modem_utils.h"
+
+RadioModemResponse::RadioModemResponse(RadioServiceTest& parent) : parent_modem(parent) {}
+
+ndk::ScopedAStatus RadioModemResponse::acknowledgeRequest(int32_t /*serial*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemResponse::enableModemResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemResponse::getBasebandVersionResponse(const RadioResponseInfo& /*info*/,
+                                                                  const std::string& /*version*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemResponse::getDeviceIdentityResponse(const RadioResponseInfo& /*info*/,
+                                                                 const std::string& /*imei*/,
+                                                                 const std::string& /*imeisv*/,
+                                                                 const std::string& /*esn*/,
+                                                                 const std::string& /*meid*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemResponse::getHardwareConfigResponse(
+        const RadioResponseInfo& /*info*/, const std::vector<HardwareConfig>& /*config*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemResponse::getModemActivityInfoResponse(
+        const RadioResponseInfo& /*info*/, const ActivityStatsInfo& /*activityInfo*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemResponse::getModemStackStatusResponse(
+        const RadioResponseInfo& /*info*/, const bool /*enabled*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemResponse::getRadioCapabilityResponse(const RadioResponseInfo& /*info*/,
+                                                                  const RadioCapability& /*rc*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemResponse::nvReadItemResponse(const RadioResponseInfo& /*info*/,
+                                                          const std::string& /*result*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemResponse::nvResetConfigResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemResponse::nvWriteCdmaPrlResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemResponse::nvWriteItemResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemResponse::requestShutdownResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemResponse::sendDeviceStateResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemResponse::setRadioCapabilityResponse(const RadioResponseInfo& /*info*/,
+                                                                  const RadioCapability& /*rc*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioModemResponse::setRadioPowerResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_modem.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_modem_test.cpp b/radio/aidl/vts/radio_modem_test.cpp
new file mode 100644
index 0000000..b40bb7b
--- /dev/null
+++ b/radio/aidl/vts/radio_modem_test.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2021 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 <aidl/android/hardware/radio/config/IRadioConfig.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+
+#include "radio_modem_utils.h"
+
+#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
+
+void RadioModemTest::SetUp() {
+    std::string serviceName = GetParam();
+
+    if (!isServiceValidForDeviceConfiguration(serviceName)) {
+        ALOGI("Skipped the test due to device configuration.");
+        GTEST_SKIP();
+    }
+
+    radio_modem = IRadioModem::fromBinder(
+            ndk::SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+    ASSERT_NE(nullptr, radio_modem.get());
+
+    radioRsp_modem = ndk::SharedRefBase::make<RadioModemResponse>(*this);
+    ASSERT_NE(nullptr, radioRsp_modem.get());
+
+    count_ = 0;
+
+    radioInd_modem = ndk::SharedRefBase::make<RadioModemIndication>(*this);
+    ASSERT_NE(nullptr, radioInd_modem.get());
+
+    radio_modem->setResponseFunctions(radioRsp_modem, radioInd_modem);
+
+    // Assert IRadioSim exists and SIM is present before testing
+    radio_sim = sim::IRadioSim::fromBinder(ndk::SpAIBinder(
+            AServiceManager_waitForService("android.hardware.radio.sim.IRadioSim/slot1")));
+    ASSERT_NE(nullptr, radio_sim.get());
+    updateSimCardStatus();
+    EXPECT_EQ(CardStatus::STATE_PRESENT, cardStatus.cardState);
+
+    // Assert IRadioConfig exists before testing
+    radio_config = config::IRadioConfig::fromBinder(ndk::SpAIBinder(
+            AServiceManager_waitForService("android.hardware.radio.config.IRadioConfig/default")));
+    ASSERT_NE(nullptr, radio_config.get());
+}
+
+/*
+ * Test IRadioModem.setRadioPower() for the response returned.
+ */
+TEST_P(RadioModemTest, setRadioPower_emergencyCall_cancelled) {
+    // Set radio power to off.
+    serial = GetRandomSerialNumber();
+    radio_modem->setRadioPower(serial, false, false, false);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+    EXPECT_EQ(RadioError::NONE, radioRsp_modem->rspInfo.error);
+
+    // Set radio power to on with forEmergencyCall being true. This should put modem to only scan
+    // emergency call bands.
+    serial = GetRandomSerialNumber();
+    radio_modem->setRadioPower(serial, true, true, true);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+    EXPECT_EQ(RadioError::NONE, radioRsp_modem->rspInfo.error);
+
+    // Set radio power to on with forEmergencyCall being false. This should put modem in regular
+    // operation modem.
+    serial = GetRandomSerialNumber();
+    radio_modem->setRadioPower(serial, true, false, false);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
+    EXPECT_EQ(RadioError::NONE, radioRsp_modem->rspInfo.error);
+}
diff --git a/radio/aidl/vts/radio_modem_utils.h b/radio/aidl/vts/radio_modem_utils.h
new file mode 100644
index 0000000..8779e0c
--- /dev/null
+++ b/radio/aidl/vts/radio_modem_utils.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/radio/modem/BnRadioModemIndication.h>
+#include <aidl/android/hardware/radio/modem/BnRadioModemResponse.h>
+#include <aidl/android/hardware/radio/modem/IRadioModem.h>
+
+#include "radio_aidl_hal_utils.h"
+
+using namespace aidl::android::hardware::radio::modem;
+
+class RadioModemTest;
+
+/* Callback class for radio modem response */
+class RadioModemResponse : public BnRadioModemResponse {
+  protected:
+    RadioServiceTest& parent_modem;
+
+  public:
+    RadioModemResponse(RadioServiceTest& parent_modem);
+    virtual ~RadioModemResponse() = default;
+
+    RadioResponseInfo rspInfo;
+    bool isModemEnabled;
+    bool enableModemResponseToggle;
+
+    virtual ndk::ScopedAStatus acknowledgeRequest(int32_t serial) override;
+
+    virtual ndk::ScopedAStatus enableModemResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus getBasebandVersionResponse(const RadioResponseInfo& info,
+                                                          const std::string& version) override;
+
+    virtual ndk::ScopedAStatus getDeviceIdentityResponse(const RadioResponseInfo& info,
+                                                         const std::string& imei,
+                                                         const std::string& imeisv,
+                                                         const std::string& esn,
+                                                         const std::string& meid) override;
+
+    virtual ndk::ScopedAStatus getHardwareConfigResponse(
+            const RadioResponseInfo& info, const std::vector<HardwareConfig>& config) override;
+
+    virtual ndk::ScopedAStatus getModemActivityInfoResponse(
+            const RadioResponseInfo& info, const ActivityStatsInfo& activityInfo) override;
+
+    virtual ndk::ScopedAStatus getModemStackStatusResponse(const RadioResponseInfo& info,
+                                                           const bool enabled) override;
+
+    virtual ndk::ScopedAStatus getRadioCapabilityResponse(const RadioResponseInfo& info,
+                                                          const RadioCapability& rc) override;
+
+    virtual ndk::ScopedAStatus nvReadItemResponse(const RadioResponseInfo& info,
+                                                  const std::string& result) override;
+
+    virtual ndk::ScopedAStatus nvResetConfigResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus nvWriteCdmaPrlResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus nvWriteItemResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus requestShutdownResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus sendDeviceStateResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setRadioCapabilityResponse(const RadioResponseInfo& info,
+                                                          const RadioCapability& rc) override;
+
+    virtual ndk::ScopedAStatus setRadioPowerResponse(const RadioResponseInfo& info) override;
+};
+
+/* Callback class for radio modem indication */
+class RadioModemIndication : public BnRadioModemIndication {
+  protected:
+    RadioServiceTest& parent_modem;
+
+  public:
+    RadioModemIndication(RadioServiceTest& parent_modem);
+    virtual ~RadioModemIndication() = default;
+
+    virtual ndk::ScopedAStatus hardwareConfigChanged(
+            RadioIndicationType type, const std::vector<HardwareConfig>& configs) override;
+
+    virtual ndk::ScopedAStatus modemReset(RadioIndicationType type,
+                                          const std::string& reason) override;
+
+    virtual ndk::ScopedAStatus radioCapabilityIndication(RadioIndicationType type,
+                                                         const RadioCapability& rc) override;
+
+    virtual ndk::ScopedAStatus radioStateChanged(RadioIndicationType type,
+                                                 RadioState radioState) override;
+
+    virtual ndk::ScopedAStatus rilConnected(RadioIndicationType type) override;
+};
+
+// The main test class for Radio AIDL Modem.
+class RadioModemTest : public ::testing::TestWithParam<std::string>, public RadioServiceTest {
+  public:
+    virtual void SetUp() override;
+
+    /* radio modem service handle */
+    std::shared_ptr<IRadioModem> radio_modem;
+    /* radio modem response handle */
+    std::shared_ptr<RadioModemResponse> radioRsp_modem;
+    /* radio modem indication handle */
+    std::shared_ptr<RadioModemIndication> radioInd_modem;
+};
diff --git a/radio/aidl/vts/radio_network_indication.cpp b/radio/aidl/vts/radio_network_indication.cpp
new file mode 100644
index 0000000..7acbff4
--- /dev/null
+++ b/radio/aidl/vts/radio_network_indication.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2021 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 "radio_network_utils.h"
+
+RadioNetworkIndication::RadioNetworkIndication(RadioServiceTest& parent) : parent_network(parent) {}
+
+ndk::ScopedAStatus RadioNetworkIndication::barringInfoChanged(
+        RadioIndicationType /*type*/, const CellIdentity& /*cellIdentity*/,
+        const std::vector<BarringInfo>& /*barringInfos*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkIndication::cdmaPrlChanged(RadioIndicationType /*type*/,
+                                                          int32_t /*version*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkIndication::cellInfoList(RadioIndicationType /*type*/,
+                                                        const std::vector<CellInfo>& /*records*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkIndication::currentLinkCapacityEstimate(
+        RadioIndicationType /*type*/, const LinkCapacityEstimate& /*lce*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkIndication::currentPhysicalChannelConfigs(
+        RadioIndicationType /*type*/, const std::vector<PhysicalChannelConfig>& /*configs*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkIndication::currentSignalStrength(
+        RadioIndicationType /*type*/, const SignalStrength& /*signalStrength*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkIndication::imsNetworkStateChanged(RadioIndicationType /*type*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkIndication::networkScanResult(RadioIndicationType /*type*/,
+                                                             const NetworkScanResult& /*result*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkIndication::networkStateChanged(RadioIndicationType /*type*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkIndication::nitzTimeReceived(RadioIndicationType /*type*/,
+                                                            const std::string& /*nitzTime*/,
+                                                            int64_t /*receivedTime*/,
+                                                            int64_t /*age*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkIndication::registrationFailed(RadioIndicationType /*type*/,
+                                                              const CellIdentity& /*cellIdentity*/,
+                                                              const std::string& /*chosenPlmn*/,
+                                                              int32_t /*domain*/,
+                                                              int32_t /*causeCode*/,
+                                                              int32_t /*additionalCauseCode*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkIndication::restrictedStateChanged(RadioIndicationType /*type*/,
+                                                                  PhoneRestrictedState /*state*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkIndication::suppSvcNotify(RadioIndicationType /*type*/,
+                                                         const SuppSvcNotification& /*suppSvc*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkIndication::voiceRadioTechChanged(RadioIndicationType /*type*/,
+                                                                 RadioTechnology /*rat*/) {
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_network_response.cpp b/radio/aidl/vts/radio_network_response.cpp
new file mode 100644
index 0000000..9df1db4
--- /dev/null
+++ b/radio/aidl/vts/radio_network_response.cpp
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2021 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 "radio_network_utils.h"
+
+RadioNetworkResponse::RadioNetworkResponse(RadioServiceTest& parent) : parent_network(parent) {}
+
+ndk::ScopedAStatus RadioNetworkResponse::acknowledgeRequest(int32_t /*serial*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::getAllowedNetworkTypesBitmapResponse(
+        const RadioResponseInfo& info, const int32_t networkTypeBitmap) {
+    rspInfo = info;
+    networkTypeBitmapResponse = networkTypeBitmap;
+    parent_network.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::getAvailableBandModesResponse(
+        const RadioResponseInfo& /*info*/, const std::vector<RadioBandMode>& /*bandModes*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::getAvailableNetworksResponse(
+        const RadioResponseInfo& info, const std::vector<OperatorInfo>& operatorInfos) {
+    rspInfo = info;
+    networkInfos = operatorInfos;
+    parent_network.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::getBarringInfoResponse(
+        const RadioResponseInfo& /*info*/, const CellIdentity& /*cellIdentity*/,
+        const std::vector<BarringInfo>& /*barringInfos*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::getCdmaRoamingPreferenceResponse(
+        const RadioResponseInfo& /*info*/, CdmaRoamingType /*type*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::getCellInfoListResponse(
+        const RadioResponseInfo& /*info*/, const std::vector<CellInfo>& /*cellInfo*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::getDataRegistrationStateResponse(
+        const RadioResponseInfo& info, const RegStateResult& /*regResponse*/) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::getImsRegistrationStateResponse(
+        const RadioResponseInfo& /*info*/, bool /*isRegistered*/,
+        RadioTechnologyFamily /*ratFamily*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::getNetworkSelectionModeResponse(
+        const RadioResponseInfo& /*info*/, bool /*manual*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::getOperatorResponse(const RadioResponseInfo& /*info*/,
+                                                             const std::string& /*longName*/,
+                                                             const std::string& /*shortName*/,
+                                                             const std::string& /*numeric*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::getSignalStrengthResponse(
+        const RadioResponseInfo& /*info*/, const SignalStrength& /*sig_strength*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::getSystemSelectionChannelsResponse(
+        const RadioResponseInfo& info, const std::vector<RadioAccessSpecifier>& /*specifier*/) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::getUsageSettingResponse(
+        const RadioResponseInfo& /*info*/, const UsageSetting /*usageSetting*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::getVoiceRadioTechnologyResponse(
+        const RadioResponseInfo& /*info*/, RadioTechnology /*rat*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::getVoiceRegistrationStateResponse(
+        const RadioResponseInfo& info, const RegStateResult& regResponse) {
+    rspInfo = info;
+    voiceRegResp.regState = regResponse.regState;
+    parent_network.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::isNrDualConnectivityEnabledResponse(
+        const RadioResponseInfo& info, bool isEnabled) {
+    rspInfo = info;
+    isNrDualConnectivityEnabled = isEnabled;
+    parent_network.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setAllowedNetworkTypesBitmapResponse(
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setBandModeResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setBarringPasswordResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setCdmaRoamingPreferenceResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setCellInfoListRateResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setIndicationFilterResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setLinkCapacityReportingCriteriaResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setLocationUpdatesResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setNetworkSelectionModeAutomaticResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setNetworkSelectionModeManualResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setNrDualConnectivityStateResponse(
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setSignalStrengthReportingCriteriaResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setSuppServiceNotificationsResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setSystemSelectionChannelsResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setUsageSettingResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::startNetworkScanResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::stopNetworkScanResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::supplyNetworkDepersonalizationResponse(
+        const RadioResponseInfo& /*info*/, int32_t /*remainingRetries*/) {
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_network_test.cpp b/radio/aidl/vts/radio_network_test.cpp
new file mode 100644
index 0000000..64d8eec
--- /dev/null
+++ b/radio/aidl/vts/radio_network_test.cpp
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2021 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 <aidl/android/hardware/radio/RadioAccessFamily.h>
+#include <aidl/android/hardware/radio/config/IRadioConfig.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+
+#include "radio_network_utils.h"
+
+#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
+
+void RadioNetworkTest::SetUp() {
+    std::string serviceName = GetParam();
+
+    if (!isServiceValidForDeviceConfiguration(serviceName)) {
+        ALOGI("Skipped the test due to device configuration.");
+        GTEST_SKIP();
+    }
+
+    radio_network = IRadioNetwork::fromBinder(
+            ndk::SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+    ASSERT_NE(nullptr, radio_network.get());
+
+    radioRsp_network = ndk::SharedRefBase::make<RadioNetworkResponse>(*this);
+    ASSERT_NE(nullptr, radioRsp_network.get());
+
+    count_ = 0;
+
+    radioInd_network = ndk::SharedRefBase::make<RadioNetworkIndication>(*this);
+    ASSERT_NE(nullptr, radioInd_network.get());
+
+    radio_network->setResponseFunctions(radioRsp_network, radioInd_network);
+
+    // Assert IRadioSim exists and SIM is present before testing
+    radio_sim = sim::IRadioSim::fromBinder(ndk::SpAIBinder(
+            AServiceManager_waitForService("android.hardware.radio.sim.IRadioSim/slot1")));
+    ASSERT_NE(nullptr, radio_sim.get());
+    updateSimCardStatus();
+    EXPECT_EQ(CardStatus::STATE_PRESENT, cardStatus.cardState);
+
+    // Assert IRadioConfig exists before testing
+    radio_config = config::IRadioConfig::fromBinder(ndk::SpAIBinder(
+            AServiceManager_waitForService("android.hardware.radio.config.IRadioConfig/default")));
+    ASSERT_NE(nullptr, radio_config.get());
+}
+
+/*
+ * Test IRadioNetwork.setAllowedNetworkTypesBitmap for the response returned.
+ */
+TEST_P(RadioNetworkTest, setAllowedNetworkTypesBitmap) {
+    serial = GetRandomSerialNumber();
+    int32_t allowedNetworkTypesBitmap = static_cast<int32_t>(RadioAccessFamily::LTE);
+
+    radio_network->setAllowedNetworkTypesBitmap(serial, allowedNetworkTypesBitmap);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+    ASSERT_TRUE(CheckAnyOfErrors(
+            radioRsp_network->rspInfo.error,
+            {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::OPERATION_NOT_ALLOWED,
+             RadioError::MODE_NOT_SUPPORTED, RadioError::INTERNAL_ERR, RadioError::MODEM_ERR,
+             RadioError::INVALID_ARGUMENTS, RadioError::REQUEST_NOT_SUPPORTED,
+             RadioError::NO_RESOURCES}));
+}
+
+/*
+ * Test IRadioNetwork.getAllowedNetworkTypesBitmap for the response returned.
+ */
+TEST_P(RadioNetworkTest, getAllowedNetworkTypesBitmap) {
+    serial = GetRandomSerialNumber();
+    int32_t allowedNetworkTypesBitmap = static_cast<int32_t>(RadioAccessFamily::LTE);
+
+    radio_network->setAllowedNetworkTypesBitmap(serial, allowedNetworkTypesBitmap);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+    if (radioRsp_network->rspInfo.error == RadioError::NONE) {
+        sleep(3);  // wait for modem
+        serial = GetRandomSerialNumber();
+        radio_network->getAllowedNetworkTypesBitmap(serial);
+
+        EXPECT_EQ(std::cv_status::no_timeout, wait());
+        EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+        EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_network->rspInfo.error,
+                {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::INTERNAL_ERR,
+                 RadioError::OPERATION_NOT_ALLOWED, RadioError::MODE_NOT_SUPPORTED,
+                 RadioError::INVALID_ARGUMENTS, RadioError::MODEM_ERR,
+                 RadioError::REQUEST_NOT_SUPPORTED, RadioError::NO_RESOURCES}));
+    }
+}
+
+/*
+ * Test IRadioNetwork.setNrDualConnectivityState() for the response returned.
+ */
+TEST_P(RadioNetworkTest, setNrDualConnectivityState) {
+    serial = GetRandomSerialNumber();
+
+    ndk::ScopedAStatus res =
+            radio_network->setNrDualConnectivityState(serial, NrDualConnectivityState::DISABLE);
+    ASSERT_OK(res);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+    if (getRadioHalCapabilities()) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                     {RadioError::REQUEST_NOT_SUPPORTED}));
+    } else {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_network->rspInfo.error,
+                {RadioError::RADIO_NOT_AVAILABLE, RadioError::INTERNAL_ERR,
+                 RadioError::INVALID_STATE, RadioError::REQUEST_NOT_SUPPORTED, RadioError::NONE}));
+    }
+}
+
+/*
+ * Test IRadioNetwork.isNrDualConnectivityEnabled() for the response returned.
+ */
+TEST_P(RadioNetworkTest, isNrDualConnectivityEnabled) {
+    serial = GetRandomSerialNumber();
+
+    ndk::ScopedAStatus res = radio_network->isNrDualConnectivityEnabled(serial);
+    ASSERT_OK(res);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+    if (getRadioHalCapabilities()) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                     {RadioError::REQUEST_NOT_SUPPORTED}));
+    } else {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_network->rspInfo.error,
+                {RadioError::RADIO_NOT_AVAILABLE, RadioError::INTERNAL_ERR, RadioError::NONE}));
+    }
+}
\ No newline at end of file
diff --git a/radio/aidl/vts/radio_network_utils.h b/radio/aidl/vts/radio_network_utils.h
new file mode 100644
index 0000000..c26d7c3
--- /dev/null
+++ b/radio/aidl/vts/radio_network_utils.h
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/radio/network/BnRadioNetworkIndication.h>
+#include <aidl/android/hardware/radio/network/BnRadioNetworkResponse.h>
+#include <aidl/android/hardware/radio/network/IRadioNetwork.h>
+
+#include "radio_aidl_hal_utils.h"
+
+using namespace aidl::android::hardware::radio::network;
+
+class RadioNetworkTest;
+
+/* Callback class for radio network response */
+class RadioNetworkResponse : public BnRadioNetworkResponse {
+  protected:
+    RadioServiceTest& parent_network;
+
+  public:
+    RadioNetworkResponse(RadioServiceTest& parent_network);
+    virtual ~RadioNetworkResponse() = default;
+
+    RadioResponseInfo rspInfo;
+    std::vector<RadioBandMode> radioBandModes;
+    std::vector<OperatorInfo> networkInfos;
+    bool isNrDualConnectivityEnabled;
+    int networkTypeBitmapResponse;
+    RegStateResult voiceRegResp;
+    CellIdentity barringCellIdentity;
+    std::vector<BarringInfo> barringInfos;
+
+    virtual ndk::ScopedAStatus acknowledgeRequest(int32_t serial) override;
+
+    virtual ndk::ScopedAStatus getAllowedNetworkTypesBitmapResponse(
+            const RadioResponseInfo& info, const int32_t networkTypeBitmap) override;
+
+    virtual ndk::ScopedAStatus getAvailableBandModesResponse(
+            const RadioResponseInfo& info, const std::vector<RadioBandMode>& bandModes) override;
+
+    virtual ndk::ScopedAStatus getAvailableNetworksResponse(
+            const RadioResponseInfo& info, const std::vector<OperatorInfo>& networkInfos) override;
+
+    virtual ndk::ScopedAStatus getBarringInfoResponse(
+            const RadioResponseInfo& info, const CellIdentity& cellIdentity,
+            const std::vector<BarringInfo>& barringInfos) override;
+
+    virtual ndk::ScopedAStatus getCdmaRoamingPreferenceResponse(const RadioResponseInfo& info,
+                                                                CdmaRoamingType type) override;
+
+    virtual ndk::ScopedAStatus getCellInfoListResponse(
+            const RadioResponseInfo& info, const std::vector<CellInfo>& cellInfo) override;
+
+    virtual ndk::ScopedAStatus getDataRegistrationStateResponse(
+            const RadioResponseInfo& info, const RegStateResult& dataRegResponse) override;
+
+    virtual ndk::ScopedAStatus getImsRegistrationStateResponse(
+            const RadioResponseInfo& info, bool isRegistered,
+            RadioTechnologyFamily ratFamily) override;
+
+    virtual ndk::ScopedAStatus getNetworkSelectionModeResponse(const RadioResponseInfo& info,
+                                                               bool manual) override;
+
+    virtual ndk::ScopedAStatus getOperatorResponse(const RadioResponseInfo& info,
+                                                   const std::string& longName,
+                                                   const std::string& shortName,
+                                                   const std::string& numeric) override;
+
+    virtual ndk::ScopedAStatus getSignalStrengthResponse(
+            const RadioResponseInfo& info, const SignalStrength& sigStrength) override;
+
+    virtual ndk::ScopedAStatus getSystemSelectionChannelsResponse(
+            const RadioResponseInfo& info,
+            const std::vector<RadioAccessSpecifier>& specifier) override;
+
+    virtual ndk::ScopedAStatus getUsageSettingResponse(const RadioResponseInfo& info,
+                                                       UsageSetting usageSetting) override;
+
+    virtual ndk::ScopedAStatus getVoiceRadioTechnologyResponse(const RadioResponseInfo& info,
+                                                               RadioTechnology rat) override;
+
+    virtual ndk::ScopedAStatus getVoiceRegistrationStateResponse(
+            const RadioResponseInfo& info, const RegStateResult& voiceRegResponse) override;
+
+    virtual ndk::ScopedAStatus isNrDualConnectivityEnabledResponse(const RadioResponseInfo& info,
+                                                                   bool isEnabled) override;
+
+    virtual ndk::ScopedAStatus setAllowedNetworkTypesBitmapResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setBandModeResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setBarringPasswordResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setCdmaRoamingPreferenceResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setCellInfoListRateResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setIndicationFilterResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setLinkCapacityReportingCriteriaResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setLocationUpdatesResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setNetworkSelectionModeAutomaticResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setNetworkSelectionModeManualResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setNrDualConnectivityStateResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setSignalStrengthReportingCriteriaResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setSuppServiceNotificationsResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setSystemSelectionChannelsResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setUsageSettingResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus startNetworkScanResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus stopNetworkScanResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus supplyNetworkDepersonalizationResponse(
+            const RadioResponseInfo& info, int32_t remainingRetries) override;
+};
+
+/* Callback class for radio network indication */
+class RadioNetworkIndication : public BnRadioNetworkIndication {
+  protected:
+    RadioServiceTest& parent_network;
+
+  public:
+    RadioNetworkIndication(RadioServiceTest& parent_network);
+    virtual ~RadioNetworkIndication() = default;
+
+    virtual ndk::ScopedAStatus barringInfoChanged(
+            RadioIndicationType type, const CellIdentity& cellIdentity,
+            const std::vector<BarringInfo>& barringInfos) override;
+
+    virtual ndk::ScopedAStatus cdmaPrlChanged(RadioIndicationType type, int32_t version) override;
+
+    virtual ndk::ScopedAStatus cellInfoList(RadioIndicationType type,
+                                            const std::vector<CellInfo>& records) override;
+
+    virtual ndk::ScopedAStatus currentLinkCapacityEstimate(
+            RadioIndicationType type, const LinkCapacityEstimate& lce) override;
+
+    virtual ndk::ScopedAStatus currentPhysicalChannelConfigs(
+            RadioIndicationType type, const std::vector<PhysicalChannelConfig>& configs) override;
+
+    virtual ndk::ScopedAStatus currentSignalStrength(RadioIndicationType type,
+                                                     const SignalStrength& signalStrength) override;
+
+    virtual ndk::ScopedAStatus imsNetworkStateChanged(RadioIndicationType type) override;
+
+    virtual ndk::ScopedAStatus networkScanResult(RadioIndicationType type,
+                                                 const NetworkScanResult& result) override;
+
+    virtual ndk::ScopedAStatus networkStateChanged(RadioIndicationType type) override;
+
+    virtual ndk::ScopedAStatus nitzTimeReceived(RadioIndicationType type,
+                                                const std::string& nitzTime, int64_t receivedTimeMs,
+                                                int64_t ageMs) override;
+
+    virtual ndk::ScopedAStatus registrationFailed(RadioIndicationType type,
+                                                  const CellIdentity& cellIdentity,
+                                                  const std::string& chosenPlmn, int32_t domain,
+                                                  int32_t causeCode,
+                                                  int32_t additionalCauseCode) override;
+
+    virtual ndk::ScopedAStatus restrictedStateChanged(RadioIndicationType type,
+                                                      PhoneRestrictedState state) override;
+
+    virtual ndk::ScopedAStatus suppSvcNotify(RadioIndicationType type,
+                                             const SuppSvcNotification& suppSvc) override;
+
+    virtual ndk::ScopedAStatus voiceRadioTechChanged(RadioIndicationType type,
+                                                     RadioTechnology rat) override;
+};
+
+// The main test class for Radio AIDL Network.
+class RadioNetworkTest : public ::testing::TestWithParam<std::string>, public RadioServiceTest {
+  public:
+    virtual void SetUp() override;
+
+    /* radio network service handle */
+    std::shared_ptr<IRadioNetwork> radio_network;
+    /* radio network response handle */
+    std::shared_ptr<RadioNetworkResponse> radioRsp_network;
+    /* radio network indication handle */
+    std::shared_ptr<RadioNetworkIndication> radioInd_network;
+};
diff --git a/radio/aidl/vts/radio_sim_indication.cpp b/radio/aidl/vts/radio_sim_indication.cpp
new file mode 100644
index 0000000..c03d947
--- /dev/null
+++ b/radio/aidl/vts/radio_sim_indication.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2021 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 "radio_sim_utils.h"
+
+RadioSimIndication::RadioSimIndication(RadioServiceTest& parent) : parent_sim(parent) {}
+
+ndk::ScopedAStatus RadioSimIndication::carrierInfoForImsiEncryption(RadioIndicationType /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimIndication::cdmaSubscriptionSourceChanged(
+        RadioIndicationType /*type*/, CdmaSubscriptionSource /*cdmaSource*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimIndication::simPhonebookChanged(RadioIndicationType /*type*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimIndication::simPhonebookRecordsReceived(
+        RadioIndicationType /*type*/, PbReceivedStatus /*status*/,
+        const std::vector<PhonebookRecordInfo>& /*records*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimIndication::simRefresh(RadioIndicationType /*type*/,
+                                                  const SimRefreshResult& /*refreshResult*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimIndication::simStatusChanged(RadioIndicationType /*type*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimIndication::stkEventNotify(RadioIndicationType /*type*/,
+                                                      const std::string& /*cmd*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimIndication::stkProactiveCommand(RadioIndicationType /*type*/,
+                                                           const std::string& /*cmd*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimIndication::stkSessionEnd(RadioIndicationType /*type*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimIndication::subscriptionStatusChanged(RadioIndicationType /*type*/,
+                                                                 bool /*activate*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimIndication::uiccApplicationsEnablementChanged(
+        RadioIndicationType /*type*/, bool /*enabled*/) {
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_sim_response.cpp b/radio/aidl/vts/radio_sim_response.cpp
new file mode 100644
index 0000000..a783f43
--- /dev/null
+++ b/radio/aidl/vts/radio_sim_response.cpp
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2021 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 "radio_sim_utils.h"
+
+RadioSimResponse::RadioSimResponse(RadioServiceTest& parent) : parent_sim(parent) {}
+
+ndk::ScopedAStatus RadioSimResponse::acknowledgeRequest(int32_t /*serial*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::areUiccApplicationsEnabledResponse(
+        const RadioResponseInfo& /*info*/, bool /*enabled*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::changeIccPin2ForAppResponse(const RadioResponseInfo& /*info*/,
+                                                                 int32_t /*remainingRetries*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::changeIccPinForAppResponse(const RadioResponseInfo& /*info*/,
+                                                                int32_t /*remainingRetries*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::enableUiccApplicationsResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::getAllowedCarriersResponse(
+        const RadioResponseInfo& /*info*/, const CarrierRestrictions& /*carriers*/,
+        SimLockMultiSimPolicy /*multiSimPolicy*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::getCdmaSubscriptionResponse(
+        const RadioResponseInfo& /*info*/, const std::string& /*mdn*/, const std::string& /*hSid*/,
+        const std::string& /*hNid*/, const std::string& /*min*/, const std::string& /*prl*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::getCdmaSubscriptionSourceResponse(
+        const RadioResponseInfo& /*info*/, CdmaSubscriptionSource /*source*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::getFacilityLockForAppResponse(
+        const RadioResponseInfo& /*info*/, int32_t /*response*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::getIccCardStatusResponse(const RadioResponseInfo& info,
+                                                              const CardStatus& card_status) {
+    rspInfo = info;
+    cardStatus = card_status;
+    parent_sim.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::getImsiForAppResponse(const RadioResponseInfo& /*info*/,
+                                                           const std::string& /*imsi*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::getSimPhonebookCapacityResponse(
+        const RadioResponseInfo& info, const PhonebookCapacity& pbCapacity) {
+    rspInfo = info;
+    capacity = pbCapacity;
+    parent_sim.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::getSimPhonebookRecordsResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_sim.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::iccCloseLogicalChannelResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::iccIoForAppResponse(const RadioResponseInfo& /*info*/,
+                                                         const IccIoResult& /*iccIo*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::iccOpenLogicalChannelResponse(
+        const RadioResponseInfo& /*info*/, int32_t /*channelId*/,
+        const std::vector<uint8_t>& /*selectResponse*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::iccTransmitApduBasicChannelResponse(
+        const RadioResponseInfo& /*info*/, const IccIoResult& /*result*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::iccTransmitApduLogicalChannelResponse(
+        const RadioResponseInfo& /*info*/, const IccIoResult& /*result*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::reportStkServiceIsRunningResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::requestIccSimAuthenticationResponse(
+        const RadioResponseInfo& /*info*/, const IccIoResult& /*result*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::sendEnvelopeResponse(const RadioResponseInfo& /*info*/,
+                                                          const std::string& /*commandResponse*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::sendEnvelopeWithStatusResponse(
+        const RadioResponseInfo& /*info*/, const IccIoResult& /*iccIo*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::sendTerminalResponseToSimResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::setAllowedCarriersResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::setCarrierInfoForImsiEncryptionResponse(
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_sim.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::setCdmaSubscriptionSourceResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::setFacilityLockForAppResponse(
+        const RadioResponseInfo& /*info*/, int32_t /*retry*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::setSimCardPowerResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_sim.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::setUiccSubscriptionResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::supplyIccPin2ForAppResponse(const RadioResponseInfo& /*info*/,
+                                                                 int32_t /*remainingRetries*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::supplyIccPinForAppResponse(const RadioResponseInfo& /*info*/,
+                                                                int32_t /*remainingRetries*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::supplyIccPuk2ForAppResponse(const RadioResponseInfo& /*info*/,
+                                                                 int32_t /*remainingRetries*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::supplyIccPukForAppResponse(const RadioResponseInfo& /*info*/,
+                                                                int32_t /*remainingRetries*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::supplySimDepersonalizationResponse(
+        const RadioResponseInfo& /*info*/, PersoSubstate /*persoType*/,
+        int32_t /*remainingRetries*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioSimResponse::updateSimPhonebookRecordsResponse(
+        const RadioResponseInfo& info, int32_t recordIndex) {
+    rspInfo = info;
+    updatedRecordIndex = recordIndex;
+    parent_sim.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_sim_test.cpp b/radio/aidl/vts/radio_sim_test.cpp
new file mode 100644
index 0000000..5db77f6
--- /dev/null
+++ b/radio/aidl/vts/radio_sim_test.cpp
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2021 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 <aidl/android/hardware/radio/config/IRadioConfig.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+
+#include "radio_sim_utils.h"
+
+#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
+
+void RadioSimTest::SetUp() {
+    std::string serviceName = GetParam();
+
+    if (!isServiceValidForDeviceConfiguration(serviceName)) {
+        ALOGI("Skipped the test due to device configuration.");
+        GTEST_SKIP();
+    }
+
+    radio_sim = IRadioSim::fromBinder(
+            ndk::SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+    ASSERT_NE(nullptr, radio_sim.get());
+
+    radioRsp_sim = ndk::SharedRefBase::make<RadioSimResponse>(*this);
+    ASSERT_NE(nullptr, radioRsp_sim.get());
+
+    count_ = 0;
+
+    radioInd_sim = ndk::SharedRefBase::make<RadioSimIndication>(*this);
+    ASSERT_NE(nullptr, radioInd_sim.get());
+
+    radio_sim->setResponseFunctions(radioRsp_sim, radioInd_sim);
+    // Assert SIM is present before testing
+    updateSimCardStatus();
+    EXPECT_EQ(CardStatus::STATE_PRESENT, cardStatus.cardState);
+
+    // Assert IRadioConfig exists before testing
+    radio_config = config::IRadioConfig::fromBinder(ndk::SpAIBinder(
+            AServiceManager_waitForService("android.hardware.radio.config.IRadioConfig/default")));
+    ASSERT_NE(nullptr, radio_config.get());
+}
+
+void RadioSimTest::updateSimCardStatus() {
+    serial = GetRandomSerialNumber();
+    radio_sim->getIccCardStatus(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+    EXPECT_EQ(RadioError::NONE, radioRsp_sim->rspInfo.error);
+}
+
+/*
+ * Test IRadioSim.setSimCardPower() for the response returned.
+ */
+TEST_P(RadioSimTest, setSimCardPower) {
+    /* Test setSimCardPower power down */
+    serial = GetRandomSerialNumber();
+    radio_sim->setSimCardPower(serial, CardPowerState::POWER_DOWN);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_sim->rspInfo.error,
+                                 {RadioError::NONE, RadioError::INVALID_ARGUMENTS,
+                                  RadioError::RADIO_NOT_AVAILABLE, RadioError::SIM_ERR}));
+
+    // setSimCardPower does not return  until the request is handled, and should not trigger
+    // CardStatus::STATE_ABSENT when turning off power
+    if (radioRsp_sim->rspInfo.error == RadioError::NONE) {
+        /* Wait some time for setting sim power down and then verify it */
+        updateSimCardStatus();
+        // We cannot assert the consistency of CardState here due to b/203031664
+        // EXPECT_EQ(CardStatus::STATE_PRESENT, cardStatus.cardState);
+        // applications should be an empty vector of AppStatus
+        EXPECT_EQ(0, cardStatus.applications.size());
+    }
+
+    // Give some time for modem to fully power down the SIM card
+    sleep(MODEM_SET_SIM_POWER_DELAY_IN_SECONDS);
+
+    /* Test setSimCardPower power up */
+    serial = GetRandomSerialNumber();
+    radio_sim->setSimCardPower(serial, CardPowerState::POWER_UP);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_sim->rspInfo.error,
+                                 {RadioError::NONE, RadioError::INVALID_ARGUMENTS,
+                                  RadioError::RADIO_NOT_AVAILABLE, RadioError::SIM_ERR}));
+
+    // Give some time for modem to fully power up the SIM card
+    sleep(MODEM_SET_SIM_POWER_DELAY_IN_SECONDS);
+
+    // setSimCardPower does not return  until the request is handled. Just verify that we still
+    // have CardStatus::STATE_PRESENT after turning the power back on
+    if (radioRsp_sim->rspInfo.error == RadioError::NONE) {
+        updateSimCardStatus();
+        EXPECT_EQ(CardStatus::STATE_PRESENT, cardStatus.cardState);
+    }
+}
+
+/*
+ * Test IRadioSim.setCarrierInfoForImsiEncryption() for the response returned.
+ */
+TEST_P(RadioSimTest, setCarrierInfoForImsiEncryption) {
+    serial = GetRandomSerialNumber();
+    ImsiEncryptionInfo imsiInfo;
+    imsiInfo.mcc = "310";
+    imsiInfo.mnc = "004";
+    imsiInfo.carrierKey = (std::vector<uint8_t>){1, 2, 3, 4, 5, 6};
+    imsiInfo.keyIdentifier = "Test";
+    imsiInfo.expirationTime = 20180101;
+    imsiInfo.keyType = ImsiEncryptionInfo::PUBLIC_KEY_TYPE_EPDG;
+
+    radio_sim->setCarrierInfoForImsiEncryption(serial, imsiInfo);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_sim->rspInfo.error,
+                                     {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
+    }
+}
+
+/*
+ * Test IRadioSim.getSimPhonebookRecords() for the response returned.
+ */
+TEST_P(RadioSimTest, getSimPhonebookRecords) {
+    serial = GetRandomSerialNumber();
+    radio_sim->getSimPhonebookRecords(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(
+                CheckAnyOfErrors(radioRsp_sim->rspInfo.error,
+                                 {RadioError::INVALID_SIM_STATE, RadioError::RADIO_NOT_AVAILABLE,
+                                  RadioError::MODEM_ERR, RadioError::INVALID_ARGUMENTS,
+                                  RadioError::REQUEST_NOT_SUPPORTED},
+                                 CHECK_GENERAL_ERROR));
+    } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_sim->rspInfo.error,
+                                     {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED},
+                                     CHECK_GENERAL_ERROR));
+    }
+}
+
+/*
+ * Test IRadioSim.getSimPhonebookCapacity for the response returned.
+ */
+TEST_P(RadioSimTest, getSimPhonebookCapacity) {
+    serial = GetRandomSerialNumber();
+    radio_sim->getSimPhonebookCapacity(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(
+                CheckAnyOfErrors(radioRsp_sim->rspInfo.error,
+                                 {RadioError::INVALID_SIM_STATE, RadioError::RADIO_NOT_AVAILABLE,
+                                  RadioError::MODEM_ERR, RadioError::INVALID_ARGUMENTS,
+                                  RadioError::REQUEST_NOT_SUPPORTED},
+                                 CHECK_GENERAL_ERROR));
+    } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_sim->rspInfo.error,
+                                     {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED},
+                                     CHECK_GENERAL_ERROR));
+
+        PhonebookCapacity pbCapacity = radioRsp_sim->capacity;
+        if (pbCapacity.maxAdnRecords > 0) {
+            EXPECT_TRUE(pbCapacity.maxNameLen > 0 && pbCapacity.maxNumberLen > 0);
+            EXPECT_TRUE(pbCapacity.usedAdnRecords <= pbCapacity.maxAdnRecords);
+        }
+
+        if (pbCapacity.maxEmailRecords > 0) {
+            EXPECT_TRUE(pbCapacity.maxEmailLen > 0);
+            EXPECT_TRUE(pbCapacity.usedEmailRecords <= pbCapacity.maxEmailRecords);
+        }
+
+        if (pbCapacity.maxAdditionalNumberRecords > 0) {
+            EXPECT_TRUE(pbCapacity.maxAdditionalNumberLen > 0);
+            EXPECT_TRUE(pbCapacity.usedAdditionalNumberRecords <=
+                        pbCapacity.maxAdditionalNumberRecords);
+        }
+    }
+}
+
+/*
+ * Test IRadioSim.updateSimPhonebookRecords() for the response returned.
+ */
+TEST_P(RadioSimTest, updateSimPhonebookRecords) {
+    serial = GetRandomSerialNumber();
+    radio_sim->getSimPhonebookCapacity(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
+        ASSERT_TRUE(
+                CheckAnyOfErrors(radioRsp_sim->rspInfo.error,
+                                 {RadioError::INVALID_SIM_STATE, RadioError::RADIO_NOT_AVAILABLE,
+                                  RadioError::MODEM_ERR, RadioError::INVALID_ARGUMENTS,
+                                  RadioError::REQUEST_NOT_SUPPORTED},
+                                 CHECK_GENERAL_ERROR));
+    } else if (cardStatus.cardState == CardStatus::STATE_PRESENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_sim->rspInfo.error,
+                                     {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED},
+                                     CHECK_GENERAL_ERROR));
+        PhonebookCapacity pbCapacity = radioRsp_sim->capacity;
+
+        serial = GetRandomSerialNumber();
+        radio_sim->getSimPhonebookRecords(serial);
+
+        EXPECT_EQ(std::cv_status::no_timeout, wait());
+        EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+        EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_sim->rspInfo.error,
+                                     {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED},
+                                     CHECK_GENERAL_ERROR));
+
+        if (pbCapacity.maxAdnRecords > 0 && pbCapacity.usedAdnRecords < pbCapacity.maxAdnRecords) {
+            // Add a phonebook record
+            PhonebookRecordInfo recordInfo;
+            recordInfo.recordId = 0;
+            recordInfo.name = "ABC";
+            recordInfo.number = "1234567890";
+            serial = GetRandomSerialNumber();
+            radio_sim->updateSimPhonebookRecords(serial, recordInfo);
+
+            EXPECT_EQ(std::cv_status::no_timeout, wait());
+            EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+            EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+            EXPECT_EQ(RadioError::NONE, radioRsp_sim->rspInfo.error);
+            int index = radioRsp_sim->updatedRecordIndex;
+            EXPECT_TRUE(index > 0);
+
+            // Deleted a phonebook record
+            recordInfo.recordId = index;
+            recordInfo.name = "";
+            recordInfo.number = "";
+            serial = GetRandomSerialNumber();
+            radio_sim->updateSimPhonebookRecords(serial, recordInfo);
+
+            EXPECT_EQ(std::cv_status::no_timeout, wait());
+            EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
+            EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
+            EXPECT_EQ(RadioError::NONE, radioRsp_sim->rspInfo.error);
+        }
+    }
+}
diff --git a/radio/aidl/vts/radio_sim_utils.h b/radio/aidl/vts/radio_sim_utils.h
new file mode 100644
index 0000000..b5e365d
--- /dev/null
+++ b/radio/aidl/vts/radio_sim_utils.h
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/radio/sim/BnRadioSimIndication.h>
+#include <aidl/android/hardware/radio/sim/BnRadioSimResponse.h>
+#include <aidl/android/hardware/radio/sim/IRadioSim.h>
+
+#include "radio_aidl_hal_utils.h"
+
+using namespace aidl::android::hardware::radio::sim;
+
+class RadioSimTest;
+
+/* Callback class for radio SIM response */
+class RadioSimResponse : public BnRadioSimResponse {
+  protected:
+    RadioServiceTest& parent_sim;
+
+  public:
+    RadioSimResponse(RadioServiceTest& parent_sim);
+    virtual ~RadioSimResponse() = default;
+
+    RadioResponseInfo rspInfo;
+    CarrierRestrictions carrierRestrictionsResp;
+    SimLockMultiSimPolicy multiSimPolicyResp;
+    bool canToggleUiccApplicationsEnablement;
+    bool areUiccApplicationsEnabled;
+    PhonebookCapacity capacity;
+    int32_t updatedRecordIndex;
+
+    virtual ndk::ScopedAStatus acknowledgeRequest(int32_t serial) override;
+
+    virtual ndk::ScopedAStatus areUiccApplicationsEnabledResponse(const RadioResponseInfo& info,
+                                                                  bool enabled) override;
+
+    virtual ndk::ScopedAStatus changeIccPin2ForAppResponse(const RadioResponseInfo& info,
+                                                           int32_t remainingRetries) override;
+
+    virtual ndk::ScopedAStatus changeIccPinForAppResponse(const RadioResponseInfo& info,
+                                                          int32_t remainingRetries) override;
+
+    virtual ndk::ScopedAStatus enableUiccApplicationsResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus getAllowedCarriersResponse(
+            const RadioResponseInfo& info, const CarrierRestrictions& carriers,
+            const SimLockMultiSimPolicy multiSimPolicy) override;
+
+    virtual ndk::ScopedAStatus getCdmaSubscriptionResponse(
+            const RadioResponseInfo& info, const std::string& mdn, const std::string& hSid,
+            const std::string& hNid, const std::string& min, const std::string& prl) override;
+
+    virtual ndk::ScopedAStatus getCdmaSubscriptionSourceResponse(
+            const RadioResponseInfo& info, CdmaSubscriptionSource source) override;
+
+    virtual ndk::ScopedAStatus getFacilityLockForAppResponse(const RadioResponseInfo& info,
+                                                             int32_t response) override;
+
+    virtual ndk::ScopedAStatus getIccCardStatusResponse(const RadioResponseInfo& info,
+                                                        const CardStatus& cardStatus) override;
+
+    virtual ndk::ScopedAStatus getImsiForAppResponse(const RadioResponseInfo& info,
+                                                     const std::string& imsi) override;
+
+    virtual ndk::ScopedAStatus getSimPhonebookCapacityResponse(
+            const RadioResponseInfo& info, const PhonebookCapacity& capacity) override;
+
+    virtual ndk::ScopedAStatus getSimPhonebookRecordsResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus iccCloseLogicalChannelResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus iccIoForAppResponse(const RadioResponseInfo& info,
+                                                   const IccIoResult& iccIo) override;
+
+    virtual ndk::ScopedAStatus iccOpenLogicalChannelResponse(
+            const RadioResponseInfo& info, int32_t channelId,
+            const std::vector<uint8_t>& selectResponse) override;
+
+    virtual ndk::ScopedAStatus iccTransmitApduBasicChannelResponse(
+            const RadioResponseInfo& info, const IccIoResult& result) override;
+
+    virtual ndk::ScopedAStatus iccTransmitApduLogicalChannelResponse(
+            const RadioResponseInfo& info, const IccIoResult& result) override;
+
+    virtual ndk::ScopedAStatus reportStkServiceIsRunningResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus requestIccSimAuthenticationResponse(
+            const RadioResponseInfo& info, const IccIoResult& result) override;
+
+    virtual ndk::ScopedAStatus sendEnvelopeResponse(const RadioResponseInfo& info,
+                                                    const std::string& commandResponse) override;
+
+    virtual ndk::ScopedAStatus sendEnvelopeWithStatusResponse(const RadioResponseInfo& info,
+                                                              const IccIoResult& iccIo) override;
+
+    virtual ndk::ScopedAStatus sendTerminalResponseToSimResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setAllowedCarriersResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setCarrierInfoForImsiEncryptionResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setCdmaSubscriptionSourceResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setFacilityLockForAppResponse(const RadioResponseInfo& info,
+                                                             int32_t retry) override;
+
+    virtual ndk::ScopedAStatus setSimCardPowerResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setUiccSubscriptionResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus supplyIccPin2ForAppResponse(const RadioResponseInfo& info,
+                                                           int32_t remainingRetries) override;
+
+    virtual ndk::ScopedAStatus supplyIccPinForAppResponse(const RadioResponseInfo& info,
+                                                          int32_t remainingRetries) override;
+
+    virtual ndk::ScopedAStatus supplyIccPuk2ForAppResponse(const RadioResponseInfo& info,
+                                                           int32_t remainingRetries) override;
+
+    virtual ndk::ScopedAStatus supplyIccPukForAppResponse(const RadioResponseInfo& info,
+                                                          int32_t remainingRetries) override;
+
+    virtual ndk::ScopedAStatus supplySimDepersonalizationResponse(
+            const RadioResponseInfo& info, PersoSubstate persoType,
+            int32_t remainingRetries) override;
+
+    virtual ndk::ScopedAStatus updateSimPhonebookRecordsResponse(
+            const RadioResponseInfo& info, int32_t updatedRecordIndex) override;
+};
+
+/* Callback class for radio SIM indication */
+class RadioSimIndication : public BnRadioSimIndication {
+  protected:
+    RadioServiceTest& parent_sim;
+
+  public:
+    RadioSimIndication(RadioServiceTest& parent_sim);
+    virtual ~RadioSimIndication() = default;
+
+    virtual ndk::ScopedAStatus carrierInfoForImsiEncryption(RadioIndicationType info) override;
+
+    virtual ndk::ScopedAStatus cdmaSubscriptionSourceChanged(
+            RadioIndicationType type, CdmaSubscriptionSource cdmaSource) override;
+
+    virtual ndk::ScopedAStatus simPhonebookChanged(RadioIndicationType type) override;
+
+    virtual ndk::ScopedAStatus simPhonebookRecordsReceived(
+            RadioIndicationType type, PbReceivedStatus status,
+            const std::vector<PhonebookRecordInfo>& records) override;
+
+    virtual ndk::ScopedAStatus simRefresh(RadioIndicationType type,
+                                          const SimRefreshResult& refreshResult) override;
+
+    virtual ndk::ScopedAStatus simStatusChanged(RadioIndicationType type) override;
+
+    virtual ndk::ScopedAStatus stkEventNotify(RadioIndicationType type,
+                                              const std::string& cmd) override;
+
+    virtual ndk::ScopedAStatus stkProactiveCommand(RadioIndicationType type,
+                                                   const std::string& cmd) override;
+
+    virtual ndk::ScopedAStatus stkSessionEnd(RadioIndicationType type) override;
+
+    virtual ndk::ScopedAStatus subscriptionStatusChanged(RadioIndicationType type,
+                                                         bool activate) override;
+
+    virtual ndk::ScopedAStatus uiccApplicationsEnablementChanged(RadioIndicationType type,
+                                                                 bool enabled) override;
+};
+
+// The main test class for Radio AIDL SIM.
+class RadioSimTest : public ::testing::TestWithParam<std::string>, public RadioServiceTest {
+  public:
+    virtual void SetUp() override;
+
+    /* Override updateSimCardStatus in RadioServiceTest to not call setResponseFunctions */
+    void updateSimCardStatus();
+
+    /* radio SIM service handle in RadioServiceTest */
+    /* radio SIM response handle */
+    std::shared_ptr<RadioSimResponse> radioRsp_sim;
+    /* radio SIM indication handle */
+    std::shared_ptr<RadioSimIndication> radioInd_sim;
+};
diff --git a/radio/aidl/vts/radio_voice_indication.cpp b/radio/aidl/vts/radio_voice_indication.cpp
new file mode 100644
index 0000000..d814c18
--- /dev/null
+++ b/radio/aidl/vts/radio_voice_indication.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2021 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 "radio_voice_utils.h"
+
+RadioVoiceIndication::RadioVoiceIndication(RadioServiceTest& parent) : parent_voice(parent) {}
+
+ndk::ScopedAStatus RadioVoiceIndication::callRing(RadioIndicationType /*type*/, bool /*isGsm*/,
+                                                  const CdmaSignalInfoRecord& /*record*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceIndication::callStateChanged(RadioIndicationType /*type*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceIndication::cdmaCallWaiting(
+        RadioIndicationType /*type*/, const CdmaCallWaiting& /*callWaitingRecord*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceIndication::cdmaInfoRec(
+        RadioIndicationType /*type*/, const std::vector<CdmaInformationRecord>& /*records*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceIndication::cdmaOtaProvisionStatus(RadioIndicationType /*type*/,
+                                                                CdmaOtaProvisionStatus /*status*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceIndication::currentEmergencyNumberList(
+        RadioIndicationType /*type*/, const std::vector<EmergencyNumber>& /*emergencyNumberList*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceIndication::enterEmergencyCallbackMode(RadioIndicationType /*type*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceIndication::exitEmergencyCallbackMode(RadioIndicationType /*type*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceIndication::indicateRingbackTone(RadioIndicationType /*type*/,
+                                                              bool /*start*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceIndication::onSupplementaryServiceIndication(
+        RadioIndicationType /*type*/, const StkCcUnsolSsResult& /*ss*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceIndication::resendIncallMute(RadioIndicationType /*type*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceIndication::srvccStateNotify(RadioIndicationType /*type*/,
+                                                          SrvccState /*state*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceIndication::stkCallControlAlphaNotify(RadioIndicationType /*type*/,
+                                                                   const std::string& /*alpha*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceIndication::stkCallSetup(RadioIndicationType /*type*/,
+                                                      int64_t /*timeout*/) {
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_voice_response.cpp b/radio/aidl/vts/radio_voice_response.cpp
new file mode 100644
index 0000000..a491613
--- /dev/null
+++ b/radio/aidl/vts/radio_voice_response.cpp
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2021 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 "radio_voice_utils.h"
+
+RadioVoiceResponse::RadioVoiceResponse(RadioServiceTest& parent) : parent_voice(parent) {}
+
+ndk::ScopedAStatus RadioVoiceResponse::acceptCallResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::acknowledgeRequest(int32_t /*serial*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::conferenceResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::dialResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::emergencyDialResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::exitEmergencyCallbackModeResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::explicitCallTransferResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::getCallForwardStatusResponse(
+        const RadioResponseInfo& /*info*/,
+        const std::vector<CallForwardInfo>& /*callForwardInfos*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::getCallWaitingResponse(const RadioResponseInfo& /*info*/,
+                                                              bool /*enable*/,
+                                                              int32_t /*serviceClass*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::getClipResponse(const RadioResponseInfo& /*info*/,
+                                                       ClipStatus /*status*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::getClirResponse(const RadioResponseInfo& /*info*/,
+                                                       int32_t /*n*/, int32_t /*m*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::getCurrentCallsResponse(const RadioResponseInfo& info,
+                                                               const std::vector<Call>& calls) {
+    rspInfo = info;
+    currentCalls = calls;
+    parent_voice.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::getLastCallFailCauseResponse(
+        const RadioResponseInfo& /*info*/, const LastCallFailCauseInfo& /*failCauseInfo*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::getMuteResponse(const RadioResponseInfo& /*info*/,
+                                                       bool /*enable*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::getPreferredVoicePrivacyResponse(
+        const RadioResponseInfo& /*info*/, bool /*enable*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::getTtyModeResponse(const RadioResponseInfo& /*info*/,
+                                                          TtyMode /*mode*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::handleStkCallSetupRequestFromSimResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::hangupConnectionResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_voice.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::hangupForegroundResumeBackgroundResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::hangupWaitingOrBackgroundResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::isVoNrEnabledResponse(const RadioResponseInfo& /*info*/,
+                                                             bool /*enabled*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::rejectCallResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::sendBurstDtmfResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::sendCdmaFeatureCodeResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::sendDtmfResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::separateConnectionResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::setCallForwardResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::setCallWaitingResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::setClirResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::setMuteResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::setPreferredVoicePrivacyResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::setTtyModeResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::setVoNrEnabledResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::startDtmfResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::stopDtmfResponse(const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioVoiceResponse::switchWaitingOrHoldingAndActiveResponse(
+        const RadioResponseInfo& /*info*/) {
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_voice_test.cpp b/radio/aidl/vts/radio_voice_test.cpp
new file mode 100644
index 0000000..717f3f0
--- /dev/null
+++ b/radio/aidl/vts/radio_voice_test.cpp
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2021 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 <aidl/android/hardware/radio/config/IRadioConfig.h>
+#include <aidl/android/hardware/radio/voice/EmergencyServiceCategory.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+
+#include "radio_voice_utils.h"
+
+#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
+
+void RadioVoiceTest::SetUp() {
+    std::string serviceName = GetParam();
+
+    if (!isServiceValidForDeviceConfiguration(serviceName)) {
+        ALOGI("Skipped the test due to device configuration.");
+        GTEST_SKIP();
+    }
+
+    radio_voice = IRadioVoice::fromBinder(
+            ndk::SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+    ASSERT_NE(nullptr, radio_voice.get());
+
+    radioRsp_voice = ndk::SharedRefBase::make<RadioVoiceResponse>(*this);
+    ASSERT_NE(nullptr, radioRsp_voice.get());
+
+    count_ = 0;
+
+    radioInd_voice = ndk::SharedRefBase::make<RadioVoiceIndication>(*this);
+    ASSERT_NE(nullptr, radioInd_voice.get());
+
+    radio_voice->setResponseFunctions(radioRsp_voice, radioInd_voice);
+
+    // Assert IRadioSim exists and SIM is present before testing
+    radio_sim = sim::IRadioSim::fromBinder(ndk::SpAIBinder(
+            AServiceManager_waitForService("android.hardware.radio.sim.IRadioSim/slot1")));
+    ASSERT_NE(nullptr, radio_sim.get());
+    updateSimCardStatus();
+    EXPECT_EQ(CardStatus::STATE_PRESENT, cardStatus.cardState);
+
+    // Assert IRadioConfig exists before testing
+    radio_config = config::IRadioConfig::fromBinder(ndk::SpAIBinder(
+            AServiceManager_waitForService("android.hardware.radio.config.IRadioConfig/default")));
+    ASSERT_NE(nullptr, radio_config.get());
+
+    if (isDsDsEnabled() || isTsTsEnabled()) {
+        radio_network = IRadioNetwork::fromBinder(ndk::SpAIBinder(AServiceManager_waitForService(
+                "android.hardware.radio.network.IRadioNetwork/slot1")));
+        ASSERT_NE(nullptr, radio_network.get());
+        radioRsp_network = ndk::SharedRefBase::make<RadioNetworkResponse>(*this);
+        radioInd_network = ndk::SharedRefBase::make<RadioNetworkIndication>(*this);
+        radio_network->setResponseFunctions(radioRsp_network, radioInd_network);
+    }
+}
+
+ndk::ScopedAStatus RadioVoiceTest::clearPotentialEstablishedCalls() {
+    // Get the current call Id to hangup the established emergency call.
+    serial = GetRandomSerialNumber();
+    radio_voice->getCurrentCalls(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+
+    // Hang up to disconnect the established call channels.
+    for (const Call& call : radioRsp_voice->currentCalls) {
+        serial = GetRandomSerialNumber();
+        radio_voice->hangup(serial, call.index);
+        ALOGI("Hang up to disconnect the established call channel: %d", call.index);
+        EXPECT_EQ(std::cv_status::no_timeout, wait());
+        // Give some time for modem to disconnect the established call channel.
+        sleep(MODEM_EMERGENCY_CALL_DISCONNECT_TIME);
+    }
+
+    // Verify there are no more current calls.
+    serial = GetRandomSerialNumber();
+    radio_voice->getCurrentCalls(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(0, radioRsp_voice->currentCalls.size());
+    return ndk::ScopedAStatus::ok();
+}
+
+/*
+ * Test IRadioVoice.emergencyDial() for the response returned.
+ */
+TEST_P(RadioVoiceTest, emergencyDial) {
+    if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) {
+        ALOGI("Skipping emergencyDial because voice call is not supported in device");
+        return;
+    } else if (!deviceSupportsFeature(FEATURE_TELEPHONY_GSM) &&
+               !deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+        ALOGI("Skipping emergencyDial because gsm/cdma radio is not supported in device");
+        return;
+    } else {
+        ALOGI("Running emergencyDial because voice call is supported in device");
+    }
+
+    serial = GetRandomSerialNumber();
+
+    Dial dialInfo;
+    dialInfo.address = std::string("911");
+    int32_t categories = static_cast<int32_t>(EmergencyServiceCategory::UNSPECIFIED);
+    std::vector<std::string> urns = {""};
+    EmergencyCallRouting routing = EmergencyCallRouting::UNKNOWN;
+
+    ndk::ScopedAStatus res =
+            radio_voice->emergencyDial(serial, dialInfo, categories, urns, routing, true, true);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    ALOGI("emergencyDial, rspInfo.error = %s\n", toString(radioRsp_voice->rspInfo.error).c_str());
+
+    RadioError rspEmergencyDial = radioRsp_voice->rspInfo.error;
+    // In DSDS or TSTS, we only check the result if the current slot is IN_SERVICE
+    // or Emergency_Only.
+    if (isDsDsEnabled() || isTsTsEnabled()) {
+        serial = GetRandomSerialNumber();
+        radio_network->getVoiceRegistrationState(serial);
+        EXPECT_EQ(std::cv_status::no_timeout, wait());
+        if (isVoiceEmergencyOnly(radioRsp_network->voiceRegResp.regState) ||
+            isVoiceInService(radioRsp_network->voiceRegResp.regState)) {
+            EXPECT_EQ(RadioError::NONE, rspEmergencyDial);
+        }
+    } else {
+        EXPECT_EQ(RadioError::NONE, rspEmergencyDial);
+    }
+
+    // Give some time for modem to establish the emergency call channel.
+    sleep(MODEM_EMERGENCY_CALL_ESTABLISH_TIME);
+
+    // Disconnect all the potential established calls to prevent them affecting other tests.
+    clearPotentialEstablishedCalls();
+}
+
+/*
+ * Test IRadioVoice.emergencyDial() with specified service and its response returned.
+ */
+TEST_P(RadioVoiceTest, emergencyDial_withServices) {
+    if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) {
+        ALOGI("Skipping emergencyDial because voice call is not supported in device");
+        return;
+    } else if (!deviceSupportsFeature(FEATURE_TELEPHONY_GSM) &&
+               !deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+        ALOGI("Skipping emergencyDial because gsm/cdma radio is not supported in device");
+        return;
+    } else {
+        ALOGI("Running emergencyDial because voice call is supported in device");
+    }
+
+    serial = GetRandomSerialNumber();
+
+    Dial dialInfo;
+    dialInfo.address = std::string("911");
+    int32_t categories = static_cast<int32_t>(EmergencyServiceCategory::AMBULANCE);
+    std::vector<std::string> urns = {"urn:service:sos.ambulance"};
+    EmergencyCallRouting routing = EmergencyCallRouting::UNKNOWN;
+
+    ndk::ScopedAStatus res =
+            radio_voice->emergencyDial(serial, dialInfo, categories, urns, routing, true, true);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    ALOGI("emergencyDial_withServices, rspInfo.error = %s\n",
+          toString(radioRsp_voice->rspInfo.error).c_str());
+    RadioError rspEmergencyDial = radioRsp_voice->rspInfo.error;
+
+    // In DSDS or TSTS, we only check the result if the current slot is IN_SERVICE
+    // or Emergency_Only.
+    if (isDsDsEnabled() || isTsTsEnabled()) {
+        serial = GetRandomSerialNumber();
+        radio_network->getVoiceRegistrationState(serial);
+        EXPECT_EQ(std::cv_status::no_timeout, wait());
+        if (isVoiceEmergencyOnly(radioRsp_network->voiceRegResp.regState) ||
+            isVoiceInService(radioRsp_network->voiceRegResp.regState)) {
+            EXPECT_EQ(RadioError::NONE, rspEmergencyDial);
+        }
+    } else {
+        EXPECT_EQ(RadioError::NONE, rspEmergencyDial);
+    }
+    // Give some time for modem to establish the emergency call channel.
+    sleep(MODEM_EMERGENCY_CALL_ESTABLISH_TIME);
+
+    // Disconnect all the potential established calls to prevent them affecting other tests.
+    clearPotentialEstablishedCalls();
+}
+
+/*
+ * Test IRadioVoice.emergencyDial() with known emergency call routing and its response returned.
+ */
+TEST_P(RadioVoiceTest, emergencyDial_withEmergencyRouting) {
+    if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) {
+        ALOGI("Skipping emergencyDial because voice call is not supported in device");
+        return;
+    } else if (!deviceSupportsFeature(FEATURE_TELEPHONY_GSM) &&
+               !deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+        ALOGI("Skipping emergencyDial because gsm/cdma radio is not supported in device");
+        return;
+    } else {
+        ALOGI("Running emergencyDial because voice call is supported in device");
+    }
+
+    serial = GetRandomSerialNumber();
+
+    Dial dialInfo;
+    dialInfo.address = std::string("911");
+    int32_t categories = static_cast<int32_t>(EmergencyServiceCategory::UNSPECIFIED);
+    std::vector<std::string> urns = {""};
+    EmergencyCallRouting routing = EmergencyCallRouting::EMERGENCY;
+
+    ndk::ScopedAStatus res =
+            radio_voice->emergencyDial(serial, dialInfo, categories, urns, routing, true, true);
+    ASSERT_OK(res);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+
+    ALOGI("emergencyDial_withEmergencyRouting, rspInfo.error = %s\n",
+          toString(radioRsp_voice->rspInfo.error).c_str());
+    RadioError rspEmergencyDial = radioRsp_voice->rspInfo.error;
+
+    // In DSDS or TSTS, we only check the result if the current slot is IN_SERVICE
+    // or Emergency_Only.
+    if (isDsDsEnabled() || isTsTsEnabled()) {
+        serial = GetRandomSerialNumber();
+        radio_network->getVoiceRegistrationState(serial);
+        EXPECT_EQ(std::cv_status::no_timeout, wait());
+        if (isVoiceEmergencyOnly(radioRsp_network->voiceRegResp.regState) ||
+            isVoiceInService(radioRsp_network->voiceRegResp.regState)) {
+            EXPECT_EQ(RadioError::NONE, rspEmergencyDial);
+        }
+    } else {
+        EXPECT_EQ(RadioError::NONE, rspEmergencyDial);
+    }
+
+    // Give some time for modem to establish the emergency call channel.
+    sleep(MODEM_EMERGENCY_CALL_ESTABLISH_TIME);
+
+    // Disconnect all the potential established calls to prevent them affecting other tests.
+    clearPotentialEstablishedCalls();
+}
+
+/*
+ * Test IRadioVoice.getCurrentCalls() for the response returned.
+ */
+TEST_P(RadioVoiceTest, getCurrentCalls) {
+    serial = GetRandomSerialNumber();
+    radio_voice->getCurrentCalls(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
+    EXPECT_EQ(RadioError::NONE, radioRsp_voice->rspInfo.error);
+}
diff --git a/radio/aidl/vts/radio_voice_utils.h b/radio/aidl/vts/radio_voice_utils.h
new file mode 100644
index 0000000..d61bf1e
--- /dev/null
+++ b/radio/aidl/vts/radio_voice_utils.h
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/radio/voice/BnRadioVoiceIndication.h>
+#include <aidl/android/hardware/radio/voice/BnRadioVoiceResponse.h>
+#include <aidl/android/hardware/radio/voice/IRadioVoice.h>
+
+#include "radio_aidl_hal_utils.h"
+#include "radio_network_utils.h"
+
+using namespace aidl::android::hardware::radio::voice;
+
+class RadioVoiceTest;
+
+/* Callback class for radio voice response */
+class RadioVoiceResponse : public BnRadioVoiceResponse {
+  protected:
+    RadioServiceTest& parent_voice;
+
+  public:
+    RadioVoiceResponse(RadioServiceTest& parent_voice);
+    virtual ~RadioVoiceResponse() = default;
+
+    RadioResponseInfo rspInfo;
+    std::vector<Call> currentCalls;
+
+    virtual ndk::ScopedAStatus acceptCallResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus acknowledgeRequest(int32_t serial) override;
+
+    virtual ndk::ScopedAStatus conferenceResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus dialResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus emergencyDialResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus exitEmergencyCallbackModeResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus explicitCallTransferResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus getCallForwardStatusResponse(
+            const RadioResponseInfo& info,
+            const std::vector<CallForwardInfo>& call_forwardInfos) override;
+
+    virtual ndk::ScopedAStatus getCallWaitingResponse(const RadioResponseInfo& info, bool enable,
+                                                      int32_t serviceClass) override;
+
+    virtual ndk::ScopedAStatus getClipResponse(const RadioResponseInfo& info,
+                                               ClipStatus status) override;
+
+    virtual ndk::ScopedAStatus getClirResponse(const RadioResponseInfo& info, int32_t n,
+                                               int32_t m) override;
+
+    virtual ndk::ScopedAStatus getCurrentCallsResponse(const RadioResponseInfo& info,
+                                                       const std::vector<Call>& calls) override;
+
+    virtual ndk::ScopedAStatus getLastCallFailCauseResponse(
+            const RadioResponseInfo& info, const LastCallFailCauseInfo& failCauseInfo) override;
+
+    virtual ndk::ScopedAStatus getMuteResponse(const RadioResponseInfo& info, bool enable) override;
+
+    virtual ndk::ScopedAStatus getPreferredVoicePrivacyResponse(const RadioResponseInfo& info,
+                                                                bool enable) override;
+
+    virtual ndk::ScopedAStatus getTtyModeResponse(const RadioResponseInfo& info,
+                                                  TtyMode mode) override;
+
+    virtual ndk::ScopedAStatus handleStkCallSetupRequestFromSimResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus hangupConnectionResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus hangupForegroundResumeBackgroundResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus hangupWaitingOrBackgroundResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus isVoNrEnabledResponse(const RadioResponseInfo& info,
+                                                     bool enable) override;
+
+    virtual ndk::ScopedAStatus rejectCallResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus sendBurstDtmfResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus sendCdmaFeatureCodeResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus sendDtmfResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus separateConnectionResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setCallForwardResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setCallWaitingResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setClirResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setMuteResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setPreferredVoicePrivacyResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setTtyModeResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setVoNrEnabledResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus startDtmfResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus stopDtmfResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus switchWaitingOrHoldingAndActiveResponse(
+            const RadioResponseInfo& info) override;
+};
+
+/* Callback class for radio voice indication */
+class RadioVoiceIndication : public BnRadioVoiceIndication {
+  protected:
+    RadioServiceTest& parent_voice;
+
+  public:
+    RadioVoiceIndication(RadioServiceTest& parent_voice);
+    virtual ~RadioVoiceIndication() = default;
+
+    virtual ndk::ScopedAStatus callRing(RadioIndicationType type, bool isGsm,
+                                        const CdmaSignalInfoRecord& record) override;
+
+    virtual ndk::ScopedAStatus callStateChanged(RadioIndicationType type) override;
+
+    virtual ndk::ScopedAStatus cdmaCallWaiting(RadioIndicationType type,
+                                               const CdmaCallWaiting& callWaitingRecord) override;
+
+    virtual ndk::ScopedAStatus cdmaInfoRec(
+            RadioIndicationType type, const std::vector<CdmaInformationRecord>& records) override;
+
+    virtual ndk::ScopedAStatus cdmaOtaProvisionStatus(RadioIndicationType type,
+                                                      CdmaOtaProvisionStatus status) override;
+
+    virtual ndk::ScopedAStatus currentEmergencyNumberList(
+            RadioIndicationType type,
+            const std::vector<EmergencyNumber>& emergencyNumberList) override;
+
+    virtual ndk::ScopedAStatus enterEmergencyCallbackMode(RadioIndicationType type) override;
+
+    virtual ndk::ScopedAStatus exitEmergencyCallbackMode(RadioIndicationType type) override;
+
+    virtual ndk::ScopedAStatus indicateRingbackTone(RadioIndicationType type, bool start) override;
+
+    virtual ndk::ScopedAStatus onSupplementaryServiceIndication(
+            RadioIndicationType type, const StkCcUnsolSsResult& ss) override;
+
+    virtual ndk::ScopedAStatus resendIncallMute(RadioIndicationType type) override;
+
+    virtual ndk::ScopedAStatus srvccStateNotify(RadioIndicationType type,
+                                                SrvccState state) override;
+
+    virtual ndk::ScopedAStatus stkCallControlAlphaNotify(RadioIndicationType type,
+                                                         const std::string& alpha) override;
+
+    virtual ndk::ScopedAStatus stkCallSetup(RadioIndicationType type, int64_t timeout) override;
+};
+
+// The main test class for Radio AIDL Voice.
+class RadioVoiceTest : public ::testing::TestWithParam<std::string>, public RadioServiceTest {
+  protected:
+    /* Clear Potential Established Calls */
+    virtual ndk::ScopedAStatus clearPotentialEstablishedCalls();
+    std::shared_ptr<network::IRadioNetwork> radio_network;
+    std::shared_ptr<RadioNetworkResponse> radioRsp_network;
+    std::shared_ptr<RadioNetworkIndication> radioInd_network;
+
+  public:
+    virtual void SetUp() override;
+
+    /* radio voice service handle */
+    std::shared_ptr<IRadioVoice> radio_voice;
+    /* radio voice response handle */
+    std::shared_ptr<RadioVoiceResponse> radioRsp_voice;
+    /* radio voice indication handle */
+    std::shared_ptr<RadioVoiceIndication> radioInd_voice;
+};
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 3695f1e..02462fc 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -537,6 +537,9 @@
     Status result;
     if (!output) return ErrorCode::UNEXPECTED_NULL_POINTER;
 
+    EXPECT_NE(op_, nullptr);
+    if (!op_) return ErrorCode::UNEXPECTED_NULL_POINTER;
+
     std::vector<uint8_t> o_put;
     result = op_->update(vector<uint8_t>(input.begin(), input.end()), {}, {}, &o_put);
 
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index 5b80b6f..d109058 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -4608,8 +4608,10 @@
     auto params = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
 
     // Try various message lengths; all should work.
-    for (size_t i = 0; i < 32; ++i) {
-        string message(i, 'a');
+    for (size_t i = 0; i <= 48; i++) {
+        SCOPED_TRACE(testing::Message() << "i = " << i);
+        // Edge case: '\t' (0x09) is also a valid PKCS7 padding character.
+        string message(i, '\t');
         string ciphertext = EncryptMessage(message, params);
         EXPECT_EQ(i + 16 - (i % 16), ciphertext.size());
         string plaintext = DecryptMessage(ciphertext, params);
@@ -4633,7 +4635,7 @@
     auto params = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
 
     // Try various message lengths; all should fail
-    for (size_t i = 0; i < 32; ++i) {
+    for (size_t i = 0; i <= 48; i++) {
         string message(i, 'a');
         EXPECT_EQ(ErrorCode::INCOMPATIBLE_PADDING_MODE, Begin(KeyPurpose::ENCRYPT, params));
     }
@@ -5775,8 +5777,8 @@
 
     ASSERT_GT(key_blob_.size(), 0U);
 
-    // Two-block message.
-    string message = "1234567890123456";
+    // Four-block message.
+    string message = "12345678901234561234567890123456";
     vector<uint8_t> iv1;
     string ciphertext1 = EncryptMessage(message, BlockMode::CBC, PaddingMode::NONE, &iv1);
     EXPECT_EQ(message.size(), ciphertext1.size());
@@ -5936,8 +5938,10 @@
                                                  .Padding(PaddingMode::PKCS7)));
 
     // Try various message lengths; all should work.
-    for (size_t i = 0; i < 32; ++i) {
-        string message(i, 'a');
+    for (size_t i = 0; i <= 32; i++) {
+        SCOPED_TRACE(testing::Message() << "i = " << i);
+        // Edge case: '\t' (0x09) is also a valid PKCS7 padding character, albeit not for 3DES.
+        string message(i, '\t');
         vector<uint8_t> iv;
         string ciphertext = EncryptMessage(message, BlockMode::CBC, PaddingMode::PKCS7, &iv);
         EXPECT_EQ(i + 8 - (i % 8), ciphertext.size());
@@ -5959,7 +5963,7 @@
                                                  .Padding(PaddingMode::NONE)));
 
     // Try various message lengths; all should fail.
-    for (size_t i = 0; i < 32; ++i) {
+    for (size_t i = 0; i <= 32; i++) {
         auto begin_params =
                 AuthorizationSetBuilder().BlockMode(BlockMode::CBC).Padding(PaddingMode::PKCS7);
         EXPECT_EQ(ErrorCode::INCOMPATIBLE_PADDING_MODE, Begin(KeyPurpose::ENCRYPT, begin_params));
@@ -5990,6 +5994,7 @@
                                 .Authorization(TAG_NONCE, iv);
 
     for (size_t i = 0; i < kMaxPaddingCorruptionRetries; ++i) {
+        SCOPED_TRACE(testing::Message() << "i = " << i);
         ++ciphertext[ciphertext.size() / 2];
         EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params));
         string plaintext;
diff --git a/usb/gadget/1.1/default/lib/UsbGadgetUtils.cpp b/usb/gadget/1.1/default/lib/UsbGadgetUtils.cpp
index 8402853..4c40bf8 100644
--- a/usb/gadget/1.1/default/lib/UsbGadgetUtils.cpp
+++ b/usb/gadget/1.1/default/lib/UsbGadgetUtils.cpp
@@ -178,6 +178,9 @@
 
 Status addAdb(MonitorFfs* monitorFfs, int* functionCount) {
     ALOGI("setCurrentUsbFunctions Adb");
+    if (!WriteStringToFile("1", DESC_USE_PATH))
+        return Status::ERROR;
+
     if (!monitorFfs->addInotifyFd("/dev/usb-ffs/adb/")) return Status::ERROR;
 
     if (linkFunction("ffs.adb", (*functionCount)++)) return Status::ERROR;
diff --git a/usb/gadget/1.2/default/lib/UsbGadgetUtils.cpp b/usb/gadget/1.2/default/lib/UsbGadgetUtils.cpp
index 8986556..fa50821 100644
--- a/usb/gadget/1.2/default/lib/UsbGadgetUtils.cpp
+++ b/usb/gadget/1.2/default/lib/UsbGadgetUtils.cpp
@@ -190,6 +190,9 @@
 
 Status addAdb(MonitorFfs* monitorFfs, int* functionCount) {
     ALOGI("setCurrentUsbFunctions Adb");
+    if (!WriteStringToFile("1", DESC_USE_PATH))
+        return Status::ERROR;
+
     if (!monitorFfs->addInotifyFd("/dev/usb-ffs/adb/")) return Status::ERROR;
 
     if (linkFunction("ffs.adb", (*functionCount)++)) return Status::ERROR;
diff --git a/wifi/1.5/default/Android.bp b/wifi/1.5/default/Android.bp
new file mode 100644
index 0000000..6333b6e
--- /dev/null
+++ b/wifi/1.5/default/Android.bp
@@ -0,0 +1,105 @@
+// Copyright (C) 2021 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_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+filegroup {
+    name: "android.hardware.wifi@1.0-service_srcs",
+    srcs: ["service.cpp"],
+}
+
+cc_defaults {
+    name: "android.hardware.wifi@1.0-service_default",
+    srcs: [":android.hardware.wifi@1.0-service_srcs"],
+    relative_install_path: "hw",
+    soc_specific: true,
+    shared_libs: [
+        "android.hardware.wifi@1.0",
+        "android.hardware.wifi@1.1",
+        "android.hardware.wifi@1.2",
+        "android.hardware.wifi@1.3",
+        "android.hardware.wifi@1.4",
+        "android.hardware.wifi@1.5",
+        "libbase",
+        "libcutils",
+        "libhidlbase",
+        "liblog",
+        "libnl",
+        "libutils",
+        "libwifi-system-iface",
+        "libxml2",
+    ],
+    cppflags: [
+        "-Wall",
+        "-Werror",
+        "-Wextra",
+    ],
+}
+
+filegroup {
+    name: "android.hardware.wifi@1.0-service-lib_srcs",
+    srcs: [
+        "hidl_struct_util.cpp",
+        "hidl_sync_util.cpp",
+        "ringbuffer.cpp",
+        "wifi.cpp",
+        "wifi_ap_iface.cpp",
+        "wifi_chip.cpp",
+        "wifi_feature_flags.cpp",
+        "wifi_iface_util.cpp",
+        "wifi_legacy_hal.cpp",
+        "wifi_legacy_hal_factory.cpp",
+        "wifi_legacy_hal_stubs.cpp",
+        "wifi_mode_controller.cpp",
+        "wifi_nan_iface.cpp",
+        "wifi_p2p_iface.cpp",
+        "wifi_rtt_controller.cpp",
+        "wifi_sta_iface.cpp",
+        "wifi_status_util.cpp",
+    ],
+}
+
+cc_defaults {
+    name: "android.hardware.wifi@1.0-service-lib_defaults",
+    srcs: [":android.hardware.wifi@1.0-service-lib_srcs"],
+    relative_install_path: "hw",
+    soc_specific: true,
+    shared_libs: [
+        "android.hardware.wifi@1.0",
+        "android.hardware.wifi@1.1",
+        "android.hardware.wifi@1.2",
+        "android.hardware.wifi@1.3",
+        "android.hardware.wifi@1.4",
+        "android.hardware.wifi@1.5",
+        "libbase",
+        "libcutils",
+        "libhidlbase",
+        "liblog",
+        "libnl",
+        "libutils",
+        "libwifi-system-iface",
+        "libxml2",
+    ],
+    // Generated by building android.hardware.wifi@1.0-service-lib and printing LOCAL_CPPFLAGS.
+    cppflags: [
+        "-Wall",
+        "-Werror",
+        "-Wextra",
+        "-DWIFI_HIDL_FEATURE_DUAL_INTERFACE",
+    ],
+    export_include_dirs: ["."],
+    include_dirs: ["external/libxml2/include"],
+}
diff --git a/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp b/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp
index 41c54b3..8f88196 100644
--- a/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp
+++ b/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp
@@ -431,6 +431,7 @@
     EXPECT_TRUE(status.isOk());
 }
 
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HostapdAidl);
 INSTANTIATE_TEST_SUITE_P(
     Hostapd, HostapdAidl,
     testing::ValuesIn(android::getAidlHalInstanceNames(IHostapd::descriptor)),
diff --git a/wifi/supplicant/aidl/Android.bp b/wifi/supplicant/aidl/Android.bp
index c97a6f9..d00dd21 100644
--- a/wifi/supplicant/aidl/Android.bp
+++ b/wifi/supplicant/aidl/Android.bp
@@ -12,6 +12,15 @@
 // 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"],
+}
+
 aidl_interface {
     name: "android.hardware.wifi.supplicant",
     vendor_available: true,
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/AuthAlgMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/AuthAlgMask.aidl
index e8101ea..039d41d 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/AuthAlgMask.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/AuthAlgMask.aidl
@@ -19,7 +19,7 @@
 /**
  * Possible mask of values for AuthAlg param.
  * See /external/wpa_supplicant_8/src/common/defs.h for
- * all possible values (starting at WPA_AUTH_ALG_OPEN).
+ * the historical values (starting at WPA_AUTH_ALG_OPEN).
  */
 @VintfStability
 @Backing(type="int")
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/GroupCipherMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/GroupCipherMask.aidl
index d5b26ad..99e9da0 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/GroupCipherMask.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/GroupCipherMask.aidl
@@ -19,7 +19,7 @@
 /**
  * Possible mask of values for GroupCipher param.
  * See /external/wpa_supplicant_8/src/common/defs.h for
- * all possible values (starting at WPA_CIPHER_WEP40).
+ * the historical values (starting at WPA_CIPHER_WEP40).
  */
 @VintfStability
 @Backing(type="int")
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/KeyMgmtMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/KeyMgmtMask.aidl
index 3225585..f0c3345 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/KeyMgmtMask.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/KeyMgmtMask.aidl
@@ -19,7 +19,7 @@
 /**
  * Possible mask of values for KeyMgmt param.
  * See /external/wpa_supplicant_8/src/common/defs.h for
- * all possible values (starting at WPA_KEY_MGMT_IEEE8021X).
+ * the historical values (starting at WPA_KEY_MGMT_IEEE8021X).
  */
 @VintfStability
 @Backing(type="int")
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/PairwiseCipherMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/PairwiseCipherMask.aidl
index ad134fa..7179fea 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/PairwiseCipherMask.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/PairwiseCipherMask.aidl
@@ -19,7 +19,7 @@
 /**
  * Possible mask of values for PairwiseCipher param.
  * See /external/wpa_supplicant_8/src/common/defs.h for
- * all possible values (starting at WPA_CIPHER_NONE).
+ * the historical values (starting at WPA_CIPHER_NONE).
  */
 @VintfStability
 @Backing(type="int")
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ProtoMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ProtoMask.aidl
index 65c832b..dc3d80b 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ProtoMask.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ProtoMask.aidl
@@ -19,7 +19,7 @@
 /**
  * Possible mask of values for Proto param.
  * See /external/wpa_supplicant_8/src/common/defs.h for
- * all possible values (starting at WPA_PROTO_WPA).
+ * the historical values (starting at WPA_PROTO_WPA).
  */
 @VintfStability
 @Backing(type="int")
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp
index 2f4f06d..d9d8179 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp
@@ -620,6 +620,7 @@
         p2p_iface_->removeUpnpService(0 /* version */, upnpServiceName).isOk());
 }
 
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantP2pIfaceAidlTest);
 INSTANTIATE_TEST_SUITE_P(Supplicant, SupplicantP2pIfaceAidlTest,
                          testing::ValuesIn(android::getAidlHalInstanceNames(
                              ISupplicant::descriptor)),
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp
index f51c07f..6e6955f 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp
@@ -769,6 +769,7 @@
     EXPECT_TRUE(sta_iface_->removeDppUri(peer_id).isOk());
 }
 
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaIfaceAidlTest);
 INSTANTIATE_TEST_SUITE_P(Supplicant, SupplicantStaIfaceAidlTest,
                          testing::ValuesIn(android::getAidlHalInstanceNames(
                              ISupplicant::descriptor)),
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp
index 66c8807..3d8242b 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp
@@ -778,6 +778,7 @@
     EXPECT_NE(retrievedToken.size(), 0);
 }
 
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaNetworkAidlTest);
 INSTANTIATE_TEST_SUITE_P(Supplicant, SupplicantStaNetworkAidlTest,
                          testing::ValuesIn(android::getAidlHalInstanceNames(
                              ISupplicant::descriptor)),